披上Agent盔甲的RAG,從此不再只是召回生成! 精華
嘿,大家好!這里是一個(gè)專注于AI智能體的頻道!
今天我要和大家聊聊一些實(shí)戰(zhàn)相關(guān)的內(nèi)容。大模型在實(shí)際的工業(yè)場(chǎng)景下最常見(jiàn)的2個(gè)場(chǎng)景分別為應(yīng)用助手(copilot), 文檔/知識(shí)庫(kù)問(wèn)答(RAG)。事實(shí)上后者也逐漸在往更復(fù)雜的Agentic方向發(fā)展了,今天我們來(lái)看以下如何搭建一個(gè)可控的RAG Agent。
RAG Agent核心是它的“大腦”,一個(gè)復(fù)雜的確定性圖,它能讓AI進(jìn)行復(fù)雜的推理。而且,這個(gè)系統(tǒng)一般還能防止“幻覺(jué)”。確保所有答案都基于提供的數(shù)據(jù),而不是憑空想象。
那我們要完成的這個(gè)系統(tǒng)需要具備哪些方面的能力呢?
- 可控自主,能夠回答自定義數(shù)據(jù)集中的重要問(wèn)題。
- 充當(dāng)系統(tǒng)的“大腦”agent ,能實(shí)現(xiàn)復(fù)雜的推理。
- 幻覺(jué)低,確保答案僅基于提供的數(shù)據(jù),避免人工智能幻覺(jué)。
- 多步驟推理,將復(fù)雜的用戶查詢分解為可管理的子任務(wù)。
- 適應(yīng)性規(guī)劃,根據(jù)新信息不斷更新其計(jì)劃。
大體的框架圖如下:
它是怎么工作的呢?簡(jiǎn)單來(lái)說(shuō),就是先把PDF文檔加載進(jìn)來(lái),然后進(jìn)行文本預(yù)處理,生成每個(gè)章節(jié)的摘要,再把這些內(nèi)容編碼到向量庫(kù)中。當(dāng)有人問(wèn)問(wèn)題時(shí),AI會(huì)先對(duì)問(wèn)題脫敏,生成一個(gè)規(guī)劃,然后再根據(jù)這個(gè)規(guī)劃進(jìn)行細(xì)化出執(zhí)行任務(wù),最后生成最終答案。詳細(xì)步驟如下:
S1:構(gòu)建adavanced RAG
數(shù)據(jù)準(zhǔn)備,召回的retriever,可以理解為給文檔建立出索引,用戶后續(xù)的召回。當(dāng)然在S1的搭建高級(jí)RAG中,我們只需要分段的即可。
接下來(lái),可以構(gòu)建標(biāo)準(zhǔn)的adavanced RAG的流程,召回塊 -> 保留與query相關(guān)的塊 -> 根據(jù)是否相關(guān)來(lái)決定是否需要改寫 -> 答案如果可用則結(jié)束了 (這里的很多函數(shù)都可以在langgraph的官方examples中找到)
S2:從adavanced RAG 到 Agent
對(duì)于更復(fù)雜的任務(wù),僅通過(guò)基于語(yǔ)義相似性檢索信息無(wú)法回答問(wèn)題,需要更復(fù)雜的pipeline。為了實(shí)現(xiàn)這一目標(biāo),我們先忘記adavanced rag的流程。我們需要定義出Agent的工具,一般RAG的tool就是S1中的retriever(召回)。(為了更復(fù)雜一些,我們?cè)赟1數(shù)據(jù)準(zhǔn)備中,準(zhǔn)備了3個(gè)retriever(文檔塊、摘要、引用)單獨(dú)作為不同的tool)
可以得到3個(gè)子圖:
有了工具,那接下來(lái)就是Agent的核心,planning部分了。
計(jì)劃制定
首先需要制定計(jì)劃->計(jì)劃細(xì)化到工具上。
制定計(jì)劃
計(jì)劃細(xì)化
示例:
question = {"question": "主人公是如何打敗反派的?"}
my_plan = planner.invoke(question) # Generate a plan to answer the question
print(my_plan)
refined_plan = break_down_plan_chain.invoke(my_plan.steps) # Refine the plan
print(refined_plan)
#### output
steps1 = [
'識(shí)別故事中的主人公和反派。',
'找到主人公和反派之間的高潮或最終對(duì)決。',
'分析主人公在這次對(duì)決中采取的行動(dòng)。',
'確定導(dǎo)致反派失敗的具體行動(dòng)或策略。',
'總結(jié)發(fā)現(xiàn),回答主人公是如何打敗反派的。'
]
steps2 = [
'通過(guò)從書籍塊的向量存儲(chǔ)、章節(jié)摘要或書籍引用中檢索相關(guān)信息來(lái)識(shí)別故事中的主人公和反派。',
'通過(guò)從書籍塊的向量存儲(chǔ)、章節(jié)摘要或書籍引用中檢索相關(guān)信息來(lái)定位主人公和反派之間的高潮或最終對(duì)決。',
'通過(guò)從書籍塊的向量存儲(chǔ)、章節(jié)摘要或書籍引用中檢索相關(guān)信息來(lái)分析主人公在這次對(duì)決中采取的行動(dòng)。',
'通過(guò)從書籍塊的向量存儲(chǔ)、章節(jié)摘要或書籍引用中檢索相關(guān)信息來(lái)確定導(dǎo)致反派失敗的具體行動(dòng)或策略。',
'通過(guò)根據(jù)給定上下文回答問(wèn)題來(lái)總結(jié)發(fā)現(xiàn),回答主人公是如何打敗反派的。'
]
計(jì)劃更新
給定原始問(wèn)題、當(dāng)前計(jì)劃、過(guò)去的步驟以及迄今為止匯總的信息,更新計(jì)劃 (這個(gè)類似于一個(gè)迭代用到的,一次計(jì)劃無(wú)法完成任務(wù),通過(guò)多次收集信息迭代)
任務(wù)處理
定義任務(wù)處理程序 - 決定是使用哪個(gè)工具來(lái)處理計(jì)劃中的每個(gè)任務(wù)
問(wèn)題脫敏
脫敏
為了生成一個(gè)總體計(jì)劃,不帶任何基于任何先驗(yàn)知識(shí)的偏見(jiàn)LLM,我們首先對(duì)輸入問(wèn)題進(jìn)行匿名化,并將名稱實(shí)體映射到變量中
還原
上面的串聯(lián)起來(lái):
# 用戶問(wèn)題
state1 = {'question': "how did the harry beat quirrell? \n"}
print(f'question: {state1["question"]}')
# 脫敏
anonymized_question_output = anonymize_question_chain.invoke(state1)
## 脫敏后的問(wèn)題和脫敏字段
anonymized_question = anonymized_question_output["anonymized_question"]
mapping = anonymized_question_output["mapping"]
print(f'anonimized_querry: {anonymized_question} \n')
print(f'mapping: {mapping} \n')
# 制定計(jì)劃
plan = planner.invoke({"question": anonymized_question})
print(text_wrap(f'plan: {plan.steps}'))
print("")
# 計(jì)劃的脫敏信息還原
deanonimzed_plan = de_anonymize_plan_chain.invoke({"plan": plan.steps, "mapping": mapping})
## 還原后的計(jì)劃
print(text_wrap(f'deanonimized_plan: {deanonimzed_plan.plan}'))
# output
question:harry是如何打敗Quirrell的?
anonimized_querry:X是如何打敗Y的?
mapping:{'X': 'harry', 'Y': 'Quirrell'}
plan:[
'確定查詢的上下文或領(lǐng)域(例如,體育、競(jìng)賽、游戲等)。',
'收集X和Y參加的事件或競(jìng)賽的信息。',
'找到X與Y競(jìng)爭(zhēng)的特定實(shí)例或比賽。',
'查找那個(gè)特定實(shí)例或比賽的結(jié)果。',
'分析比賽的細(xì)節(jié),以了解X是如何設(shè)法打敗Y的。',
'總結(jié)解釋X如何打敗Y的關(guān)鍵點(diǎn)。'
]
deanonimized_plan:[
'確定查詢的上下文或領(lǐng)域(例如,體育、競(jìng)賽、游戲等)。',
'收集harry和Quirrell參加的事件或競(jìng)賽的信息。',
'找到harry與Quirrell競(jìng)爭(zhēng)的特定實(shí)例或比賽。',
'查找那個(gè)特定實(shí)例或比賽的結(jié)果。',
'分析比賽的細(xì)節(jié),以了解harry是如何設(shè)法打敗Quirrell的。',
'總結(jié)解釋harry如何打敗Quirrell的關(guān)鍵點(diǎn)。'
]
最后在加一個(gè)判斷,確定是否能根據(jù)信息推出答案。
整體的流程圖如下:
本文轉(zhuǎn)載自 ??探索AGI??,作者: 獼猴桃
