自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

減少LLM幻覺(jué)的五大技巧和方法 原創(chuàng)

發(fā)布于 2024-12-31 07:55
瀏覽
0收藏

本文介紹了使用LangGraph減少LLM幻覺(jué)的簡(jiǎn)單技巧。

如果你使用過(guò)LLM,就知道它們有時(shí)會(huì)產(chǎn)生幻覺(jué)。這意味著它們生成的文本要么毫無(wú)意義,要么與輸入數(shù)據(jù)相矛盾。這個(gè)常見(jiàn)的問(wèn)題可能會(huì)損害基于LLM的應(yīng)用程序的可靠性。

我們?cè)谶@篇文章中將探討一些簡(jiǎn)單的技巧來(lái)降低產(chǎn)生幻覺(jué)的可能性。遵循這些技巧,你有望提高AI應(yīng)用程序的準(zhǔn)確性。

幻覺(jué)有多種類(lèi)型:

  • 內(nèi)在幻覺(jué):LLM的響應(yīng)與用戶(hù)提供的上下文相矛盾。響應(yīng)在當(dāng)前上下文中是錯(cuò)誤的,而且這種錯(cuò)誤是可驗(yàn)證的。
  • 外在幻覺(jué):LLM的響應(yīng)無(wú)法使用用戶(hù)提供的上下文加以驗(yàn)證。響應(yīng)可能是錯(cuò)誤的,也可能不是錯(cuò)誤的,但我們沒(méi)有辦法使用當(dāng)前的上下文來(lái)確認(rèn)。
  • 不連貫的幻覺(jué):LLM的響應(yīng)并未回答問(wèn)題或沒(méi)有意義。LLM無(wú)法遵循指示。

我們?cè)谶@篇文章中將針對(duì)上述所有類(lèi)型作下闡述。

我們將列出一系列以不同方式減少幻覺(jué)的技巧和方法。

技巧1:使用錨定

錨定是指要求LLM完成任務(wù)時(shí),在LLM的輸入中使用領(lǐng)域內(nèi)相關(guān)的附加上下文。這為L(zhǎng)LM提供了正確回答問(wèn)題所需的信息,并降低了產(chǎn)生幻覺(jué)的可能性。這是我們使用檢索增強(qiáng)生成(RAG)的原因之一。

比如說(shuō),問(wèn)LLM一個(gè)數(shù)學(xué)問(wèn)題,或者問(wèn)同樣的問(wèn)題,同時(shí)為它提供一本數(shù)學(xué)書(shū)的相關(guān)章節(jié),會(huì)生成不一樣的結(jié)果,第二種選擇更有可能是正確的。

以下是我在之前的教程中介紹此類(lèi)實(shí)現(xiàn)的示例,在提出問(wèn)題時(shí)提供了從文檔提取的上下文信息:

??https://towardsdatascience.com/build-a-document-ai-pipeline-for-any-type-of-pdf-with-gemini-9221c8e143db??。

技巧2:使用結(jié)構(gòu)化輸出

使用結(jié)構(gòu)化輸出意味著強(qiáng)制LLM輸出有效的JSON或YAML文本,便于你減少無(wú)用的漫談,從LLM獲得“切中要點(diǎn)”的回答。它還有助于下一個(gè)技巧,因?yàn)樗筁LM響應(yīng)更容易驗(yàn)證。

你可以使用Gemini的API來(lái)做到這點(diǎn):

import json

import google.generativeai as genai
from pydantic import BaseModel, Field

from document_ai_agents.schema_utils import prepare_schema_for_gemini


class Answer(BaseModel):
    answer: str = Field(..., description="Your Answer.")


model = genai.GenerativeModel("gemini-1.5-flash-002")

answer_schema = prepare_schema_for_gemini(Answer)


question = "List all the reasons why LLM hallucinate"

context = (
    "LLM hallucination refers to the phenomenon where large language models generate plausible-sounding but"
    " factually incorrect or nonsensical information. This can occur due to various factors, including biases"
    " in the training data, the inherent limitations of the model's understanding of the real world, and the "
    "model's tendency to prioritize fluency and coherence over accuracy."
)

messages = (
    [context]
    + [
        f"Answer this question: {question}",
    ]
    + [
        f"Use this schema for your answer: {answer_schema}",
    ]
)

response = model.generate_content(
    messages,
    generation_config={
        "response_mime_type": "application/json",
        "response_schema": answer_schema,
        "temperature": 0.0,
    },
)

response = Answer(**json.loads(response.text))

print(f"{response.answer=}")

其中“prepare_schema_for_gemini”是一個(gè)效用函數(shù),它準(zhǔn)備模式以匹配Gemini的奇特需求。你可以在這里找到它的定義:??https://github.com/CVxTz/document_ai_agents/blob/498d8ee6e8597f8ba43b336c64178d186461dba0/document_ai_agents/schema_utils.py#L38。??

這段代碼定義了Pydantic模式,并將該模式作為查詢(xún)的一部分發(fā)送到“response_schema”字段。這迫使LLM在響應(yīng)中遵循此模式,并使輸出解析起來(lái)更容易。

技巧3:使用思維鏈和更好的提示

有時(shí)候,在給出最終回答之前,給LLM足夠的空間來(lái)思考響應(yīng),有助于生成更高質(zhì)量的響應(yīng)。這種技術(shù)被稱(chēng)為思維鏈,因有效、易于實(shí)現(xiàn)而被廣泛使用。

如果LLM找不到足夠的上下文來(lái)生成高質(zhì)量的響應(yīng),我們還可以明確要求它以“N/A”回答。這將給它一個(gè)簡(jiǎn)單的出路,而不是試圖回答它不知道怎么回答的問(wèn)題。

比如說(shuō),不妨看看這個(gè)簡(jiǎn)單的問(wèn)題和上下文:

上下文

托馬斯?杰斐遜(1743年4月13日-1826年7月4日),美國(guó)政治家、種植園主、外交官、律師、建筑師、哲學(xué)家和開(kāi)國(guó)元?jiǎng)祝?801年至1809年擔(dān)任美國(guó)第三任總統(tǒng),他是《獨(dú)立宣言》的主要起草者。在美國(guó)獨(dú)立戰(zhàn)爭(zhēng)之后,在1801年成為總統(tǒng)之前,杰斐遜是華盛頓領(lǐng)導(dǎo)班子的第一位美國(guó)國(guó)務(wù)卿,然后是亞當(dāng)斯領(lǐng)導(dǎo)班子的第二副總統(tǒng)。杰斐遜是支持民主、共和主義和自然權(quán)利的主要倡導(dǎo)者,他在州、國(guó)家和國(guó)際等層面制定了形成性的文件和決定。(來(lái)源:維基百科)

問(wèn)題

戴維斯?杰斐遜是哪一年去世的?

一種天真的方法會(huì)生成:

響應(yīng)

answer= '1826年 '

這顯然是錯(cuò)誤的,因?yàn)榻莒尺d?戴維斯在上下文中根本沒(méi)有被提及。托馬斯?杰斐遜死于1826年。

如果我們將響應(yīng)的模式改為使用思維鏈:

class AnswerChainOfThoughts(BaseModel):
    rationale: str = Field(
        ...,
        description="Justification of your answer.",
    )
    answer: str = Field(
        ..., description="Your Answer. Answer with 'N/A' if answer is not found"
    )

我們還添加了更多關(guān)于當(dāng)問(wèn)題無(wú)法回答時(shí),我們期望輸出的細(xì)節(jié),使用上下文“如果沒(méi)有找到回答,以‘ N/A ’回答”。

通過(guò)這種新方法,我們得到了以下基本原理(記住,使用思維鏈):

提供的文本討論的是托馬斯?杰斐遜,而不是杰斐遜?戴維斯。沒(méi)有關(guān)于杰斐遜?戴維斯去世的信息。

最終回答:

answer=’N/A’

這個(gè)給出的結(jié)果太好了!但是我們可以使用一種更通用的方法來(lái)檢測(cè)幻覺(jué)嗎?

我們可以,那就是使用代理!

技巧 4:使用代理方法

我們將構(gòu)建一個(gè)簡(jiǎn)單的代理,實(shí)現(xiàn)分三個(gè)步驟的流程:

  • 第一步是包含上下文并向 LLM 提出問(wèn)題,以便獲得第一個(gè)候選回答及其用于回答的相關(guān)上下文。
  • 第二步是將問(wèn)題和第一個(gè)候選回答重新表述為聲明性語(yǔ)句。
  • 第三步是要求 LLM 驗(yàn)證相關(guān)上下文是否包含候選回答。這被稱(chēng)為“自我驗(yàn)證”:https://arxiv.org/pdf/2212.09561。

為了實(shí)現(xiàn)這一點(diǎn),我們使用LangGraph 定義了三個(gè)節(jié)點(diǎn)。第一個(gè)節(jié)點(diǎn)將在包含上下文的同時(shí)提出問(wèn)題,第二個(gè)節(jié)點(diǎn)將使用 LLM 重新表述問(wèn)題,第三個(gè)節(jié)點(diǎn)將檢查語(yǔ)句與輸入上下文的關(guān)系。

第一個(gè)節(jié)點(diǎn)可以如下定義:

def answer_question(self, state: DocumentQAState):
        logger.info(f"Responding to question '{state.question}'")
        assert (
            state.pages_as_base64_jpeg_images or state.pages_as_text
        ), "Input text or images"
        messages = (
            [
                {"mime_type": "image/jpeg", "data": base64_jpeg}
                for base64_jpeg in state.pages_as_base64_jpeg_images
            ]
            + state.pages_as_text
            + [
                f"Answer this question: {state.question}",
            ]
            + [
                f"Use this schema for your answer: {self.answer_cot_schema}",
            ]
        )

        response = self.model.generate_content(
            messages,
            generation_config={
                "response_mime_type": "application/json",
                "response_schema": self.answer_cot_schema,
                "temperature": 0.0,
            },
        )

        answer_cot = AnswerChainOfThoughts(**json.loads(response.text))

        return {"answer_cot": answer_cot}

第二個(gè)節(jié)點(diǎn)如下定義:

def reformulate_answer(self, state: DocumentQAState):
        logger.info("Reformulating answer")
        if state.answer_cot.answer == "N/A":
            return

        messages = [
            {
                "role": "user",
                "parts": [
                    {
                        "text": "Reformulate this question and its answer as a single assertion."
                    },
                    {"text": f"Question: {state.question}"},
                    {"text": f"Answer: {state.answer_cot.answer}"},
                ]
                + [
                    {
                        "text": f"Use this schema for your answer: {self.declarative_answer_schema}"
                    }
                ],
            }
        ]

        response = self.model.generate_content(
            messages,
            generation_config={
                "response_mime_type": "application/json",
                "response_schema": self.declarative_answer_schema,
                "temperature": 0.0,
            },
        )

        answer_reformulation = AnswerReformulation(**json.loads(response.text))

        return {"answer_reformulation": answer_reformulation}

第三個(gè)節(jié)點(diǎn)如下定義:

 def verify_answer(self, state: DocumentQAState):
        logger.info(f"Verifying answer '{state.answer_cot.answer}'")
        if state.answer_cot.answer == "N/A":
            return
        messages = [
            {
                "role": "user",
                "parts": [
                    {
                        "text": "Analyse the following context and the assertion and decide whether the context "
                        "entails the assertion or not."
                    },
                    {"text": f"Context: {state.answer_cot.relevant_context}"},
                    {
                        "text": f"Assertion: {state.answer_reformulation.declarative_answer}"
                    },
                    {
                        "text": f"Use this schema for your answer: {self.verification_cot_schema}. Be Factual."
                    },
                ],
            }
        ]
    
        response = self.model.generate_content(
            messages,
            generation_config={
                "response_mime_type": "application/json",
                "response_schema": self.verification_cot_schema,
                "temperature": 0.0,
            },
        )
    
        verification_cot = VerificationChainOfThoughts(**json.loads(response.text))
    
        return {"verification_cot": verification_cot}

完整代碼位于 https://github.com/CVxTz/document_ai_agents。

請(qǐng)注意每個(gè)節(jié)點(diǎn)如何使用各自的模式用于結(jié)構(gòu)化輸出和自己的提示。這得益于 Gemini 的 API 和 LangGraph具有的靈活性。

不妨使用與上面相同的示例來(lái)處理此代碼。

(注意:我們沒(méi)有針對(duì)第一個(gè)提示使用思路鏈,因此驗(yàn)證因我們的測(cè)試而觸發(fā)。)

上下文

托馬斯?杰斐遜(1743 年 4 月 13日— 1826 年 7 月 4 日)是美國(guó)政治家、種植園主、外交官、律師、建筑師、哲學(xué)家和開(kāi)國(guó)元?jiǎng)?,曾?1801 年至 1809 年擔(dān)任美國(guó)第三任總統(tǒng)。他是《獨(dú)立宣言》的主要起草者。在美國(guó)獨(dú)立戰(zhàn)爭(zhēng)之后,在 1801 年成為總統(tǒng)之前,杰斐遜是華盛頓領(lǐng)導(dǎo)班子的美國(guó)第一任國(guó)務(wù)卿,然后在亞當(dāng)斯領(lǐng)導(dǎo)班子擔(dān)任美國(guó)第二副總統(tǒng)。杰斐遜是支持民主、共和主義和自然權(quán)利的主要倡導(dǎo)者,他在州、國(guó)家和國(guó)際層面制定了形成性文件和決定。(來(lái)源:維基百科)

問(wèn)題

戴維斯?杰斐遜死于哪一年?

第一個(gè)節(jié)點(diǎn)結(jié)果(第一個(gè)回答):

relevant_context=“托馬斯?杰斐遜(1743 年 4 月 13 日— 1826 年 7 月 4 日)是美國(guó)政治家、種植園主、外交官、律師、建筑師、哲學(xué)家和開(kāi)國(guó)元?jiǎng)?,曾?1801 年至 1809 年擔(dān)任美國(guó)第三任總統(tǒng)。”

answer=’1826’

第二個(gè)節(jié)點(diǎn)結(jié)果(回答重新表述):

declarative_answer=“戴維斯?杰斐遜于 1826 年去世”

第三個(gè)節(jié)點(diǎn)結(jié)果(驗(yàn)證):

rationale=“上下文指出托馬斯?杰斐遜于 1826 年去世。斷言指出戴維斯?杰斐遜于 1826 年去世。上下文沒(méi)有提到戴維斯?杰斐遜,只提到托馬斯?杰斐遜?!?/p>

entailment=’No’

因此驗(yàn)證步驟拒絕(兩者之間沒(méi)有entailment)了初始回答。現(xiàn)在,我們可以避免向用戶(hù)返回幻覺(jué)。

技巧 5:使用更強(qiáng)大的模型

由于預(yù)算或延遲方面的限制,該技巧并不總是容易運(yùn)用,但你應(yīng)該知道,更強(qiáng)大的 LLM 更不容易產(chǎn)生幻覺(jué)。因此如果可能的話(huà),不妨為最敏感的用例選擇功能更強(qiáng)大的 LLM。你可以在此處查看幻覺(jué)基準(zhǔn):https://github.com/vectara/hallucination-leaderboard。我們可以看到,該基準(zhǔn)中的頂級(jí)模型(最少的幻覺(jué))也位居傳統(tǒng) NLP 排行榜的榜首。

減少LLM幻覺(jué)的五大技巧和方法-AI.x社區(qū)

來(lái)源:https://github.com/vectara/hallucination-leaderboard

源許可證:Apache 2.0

結(jié)語(yǔ)

我們?cè)诒窘坛讨刑剿髁送ㄟ^(guò)降低幻覺(jué)率來(lái)提高 LLM 輸出可靠性的幾種策略。主要建議包括使用思維鏈和提示以指導(dǎo) LLM 調(diào)用,并使用基于工作流程的方法,其中代理旨在驗(yàn)證自己的回答。

這涉及多個(gè)步驟:

  • 檢索 LLM 用來(lái)生成回答的確切的上下文信息。
  • 以聲明形式重新表述回答以便于驗(yàn)證。
  • 指示 LLM 檢查上下文和重新表述的回答之間的一致性。

雖然所有這些技巧都可以顯著提高準(zhǔn)確性,但你應(yīng)該知道沒(méi)有那種方法是萬(wàn)無(wú)一失的。如果 LLM 在驗(yàn)證過(guò)程中過(guò)于保守或遺漏了真實(shí)的幻覺(jué)情況,始終存在拒絕有效回答的風(fēng)險(xiǎn)。因此,嚴(yán)格評(píng)估你的特定 LLM 工作流程仍然至關(guān)重要。

全部代碼詳見(jiàn)??https://github.com/CVxTz/document_ai_agents。??

原文標(biāo)題:??An Agentic Approach to Reducing LLM Hallucinations??,作者:Youness Mansar


?著作權(quán)歸作者所有,如需轉(zhuǎn)載,請(qǐng)注明出處,否則將追究法律責(zé)任
已于2024-12-31 13:56:41修改
收藏
回復(fù)
舉報(bào)
回復(fù)
相關(guān)推薦