鵝廠實(shí)習(xí)生血淚貼:Agent/RAG 黑科技,真相竟是這樣!
作者 | 33號(hào)實(shí)驗(yàn)室/knnwang
被Agent/RAG吊打?你缺的不是智商,是這篇文章! 親歷鵝廠IEG/WXG項(xiàng)目實(shí)戰(zhàn),大三菜鳥(niǎo)用血淚debug記錄, 撕開(kāi)AI基石真面目 → 黑科技本質(zhì) = ______! 連夜肝出 「人話說(shuō)明書+通關(guān)路線圖」 , 即學(xué)即用!青銅連夜上分,幫助大家快速入門Agent/RAG (文章前半部分會(huì)介紹Agent,后半部分討論RAG,最后還分享了優(yōu)化RAG的一些tips,希望能幫助到大家!!)
一、AI的記憶管家與知識(shí)向?qū)?/h3>
當(dāng)AI需要靠譜的知識(shí)而不是“胡說(shuō)八道”時(shí),就是我閃亮登場(chǎng)的時(shí)刻!
1. 嗨,我是RAG!我決定不再讓AI“憑空想象”
你肯定遇到過(guò)那些場(chǎng)面:你的AI助手自信滿滿地告訴你“北京在長(zhǎng)江以南”,或者信誓旦旦地說(shuō)“牛頓發(fā)明了電燈泡”,是不是讓人啼笑皆非?這些就是所謂的“幻覺(jué)”——就像你有一個(gè)知識(shí)淵博但偶爾會(huì)“異想天開(kāi)”的朋友。唉,這就是我誕生之前的AI常態(tài)。
我就是為解決這個(gè)問(wèn)題而生的!
我的全名是檢索增強(qiáng)生成(Retrieval Augmented Generation),你可以叫我RAG。簡(jiǎn)單說(shuō),我就是給AI裝上的那個(gè)“事實(shí)核查器”!當(dāng)AI需要回答問(wèn)題時(shí),我會(huì)先讓它去查閱可靠的資料庫(kù),而不是坐在那里閉門造車、憑空編造。想象一下,一個(gè)認(rèn)真的學(xué)生在考試前會(huì)先翻書復(fù)習(xí),而不是瞎猜答案——我就是那個(gè)督促AI“翻書”的機(jī)制。今天,就讓我親自帶你們了解一下我的工作原理、如何讓我變得更強(qiáng),以及我未來(lái)會(huì)變成什么樣。雖然聽(tīng)起來(lái)有點(diǎn)技術(shù)含量,但我會(huì)用有趣的方式講給你聽(tīng)!
2. 我的基本功:強(qiáng)大的“查字典”技能
(1) 我是什么?
想象一下,如果你是一位外科醫(yī)生。大部分手術(shù)流程你都爛熟于心,但遇到一個(gè)罕見(jiàn)病例時(shí),你會(huì)怎么辦?沒(méi)錯(cuò),你會(huì)去查醫(yī)學(xué)文獻(xiàn)或者請(qǐng)教專家。我的核心能力,就是賦予AI這種“查閱外部知識(shí)”的本事!
本質(zhì)上,我是一個(gè)技術(shù)框架,巧妙地把檢索系統(tǒng)和生成式AI模型(比如你們熟悉的大語(yǔ)言模型LLM) 結(jié)合在一起。當(dāng)用戶提問(wèn)時(shí),我會(huì)先指揮檢索系統(tǒng)去龐大的知識(shí)庫(kù)里找到最相關(guān)的信息片段,然后把這些“證據(jù)”交給LLM,讓它基于這些真實(shí)可靠的信息生成最終回答。這就相當(dāng)于給AI配了一個(gè)專屬的“私人圖書館” 和一個(gè)超級(jí)高效的“圖書管理員”(那就是我啦!)——你需要什么,我立刻幫你找到、整理好!
(2) 我是怎么工作的?
我的工作流程就像一位高效的辦公助理在處理你的請(qǐng)求,分三步走:
- 檢索(Retrieval - 我的搜索時(shí)間): 當(dāng)你拋出問(wèn)題,我立刻將它轉(zhuǎn)化成一種我能理解的“查詢向量”,然后一頭扎進(jìn)知識(shí)庫(kù)的海洋,快速撈出最相關(guān)的文檔或信息片段。這就像你的助理收到任務(wù),立刻跑去檔案柜精準(zhǔn)查找文件。
- 增強(qiáng)(Augmentation - 我的整理時(shí)間): 找到這些寶貝信息后,我可不會(huì)直接丟給LLM。我會(huì)精心地把它們和你的原始問(wèn)題融合在一起,打包成一個(gè)信息更豐富、背景更清晰的“增強(qiáng)提示”。這就好比你的助理把找到的所有資料整理成一份重點(diǎn)突出、條理清晰的簡(jiǎn)報(bào),準(zhǔn)備呈報(bào)給老板。
- 生成(Generation - LLM的表演時(shí)間): 最后,LLM這位“決策者”登場(chǎng)了!它基于我精心準(zhǔn)備的“增強(qiáng)提示”,結(jié)合自身的理解能力,生成最終的、有據(jù)可依的回答。就像老板審閱了助理的簡(jiǎn)報(bào)后,給出了深思熟慮的解決方案。
(3) 衡量我表現(xiàn)的關(guān)鍵指標(biāo)
想看看我這個(gè)“圖書管理員”兼“助理”干得怎么樣?主要看兩個(gè)“成績(jī)單”:
召回率(Recall - 我的找書能力): 這衡量我在知識(shí)庫(kù)里能成功找到多少真正相關(guān)知識(shí)的比例。召回率高,說(shuō)明我“找得全”,不會(huì)漏掉重要資料。就像圖書管理員能幫你找到幾乎所有相關(guān)書籍。
忠實(shí)度(Faithfulness - 我的誠(chéng)實(shí)度): 這衡量我最終讓LLM生成的內(nèi)容,到底有多忠實(shí)于知識(shí)庫(kù)里的原始信息。忠實(shí)度高,說(shuō)明LLM“編造”得少,傳達(dá)準(zhǔn)確。就像你的助理在匯報(bào)時(shí),能原原本本地傳達(dá)文件內(nèi)容,而不是添油加醋或者自己瞎發(fā)揮。
3. 我的成長(zhǎng)之路:從“菜鳥(niǎo)”到“高手”的優(yōu)化之道
坦白說(shuō),我剛“上崗”時(shí)表現(xiàn)可不咋地。就像文檔里提到的,召回率才25.4%,忠實(shí)度才27.2%——活脫脫一個(gè)滿腔熱血但毛手毛腳的實(shí)習(xí)生!那我是怎么一步步變強(qiáng)的呢?
(1) 優(yōu)化我的“字典”——知識(shí)庫(kù)
如果給我的知識(shí)庫(kù)一團(tuán)糟——就像文檔里說(shuō)的“知識(shí)庫(kù)混亂,評(píng)估規(guī)則口口相傳,靠經(jīng)驗(yàn)”——那就像給一個(gè)學(xué)生一本錯(cuò)誤百出、章節(jié)亂序的教科書,我再聰明也使不上勁啊!
我的優(yōu)化秘籍:
- 知識(shí)結(jié)構(gòu)化(整理我的書架): 把那些雜亂無(wú)章的非結(jié)構(gòu)化文本,變成整齊的結(jié)構(gòu)化數(shù)據(jù)。就像把一堆散亂的筆記,分門別類整理成清晰明了的筆記本。
- 知識(shí)更新機(jī)制(讓我的字典不過(guò)時(shí)): 文檔里提到“構(gòu)建定時(shí)器,加入裁判大模型構(gòu)建自動(dòng)化評(píng)估腳本”——這太關(guān)鍵了!我需要定期更新我的知識(shí)庫(kù),并用“裁判”模型自動(dòng)檢查內(nèi)容質(zhì)量,確保我掌握的都是最新、最準(zhǔn)確的信息。
- 知識(shí)冗余消除(清理我的書庫(kù)): 把那些重復(fù)的、過(guò)時(shí)的、或者互相矛盾的信息清理掉。就像圖書館定期下架舊書和處理復(fù)本一樣。
(2) 優(yōu)化我的“查資料”技巧——檢索策略
召回率目標(biāo)要從可憐的25.4%提升到90%!這意味著我要從“只能找到四分之一相關(guān)書”的菜鳥(niǎo),變成“幾乎能找全所有資料”的資深管理員。
我的升級(jí)手段:
- 混合檢索策略(十八般武藝都用上): 我不再只用一種方法找資料。我會(huì)結(jié)合關(guān)鍵詞檢索(按書名/作者找)、語(yǔ)義檢索(按意思找)、知識(shí)圖譜檢索(按知識(shí)關(guān)聯(lián)找)等多種手段。就像同時(shí)用分類號(hào)、作者索引和主題詞來(lái)幫你找書。
- 查詢重寫與擴(kuò)展(理解你的言外之意): 我會(huì)對(duì)你的原始問(wèn)題進(jìn)行“深加工”——改寫得更清晰,或者擴(kuò)展出相關(guān)的主題。這樣就能找到更多你可能真正需要的資料。就像圖書管理員不僅給你找你要的那本書,還會(huì)推薦相關(guān)領(lǐng)域的其他好書。
- 上下文感知檢索(記住我們的對(duì)話): 我會(huì)留意我們之前的聊天記錄和你的背景信息。這樣我就能更精準(zhǔn)地理解你這次提問(wèn)的意圖。就像圖書管理員記得你上次借了科幻小說(shuō),這次可能對(duì)科幻新書更感興趣。
- 檢索結(jié)果重排序(把最好的放前面): 初步找到一堆資料后,我會(huì)進(jìn)行二次排序,把最相關(guān)、最有價(jià)值的信息排在最前面。就像圖書管理員不僅找到了書,還按重要性給你排好了順序。
(3) 優(yōu)化我的“表達(dá)方式”——生成策略
另一個(gè)關(guān)鍵目標(biāo)是大幅降低“幻覺(jué)率”(即瞎編亂造),目標(biāo)降到10%以下!這意味著我要讓LLM這個(gè)“演講者”從“大部分內(nèi)容靠編”進(jìn)化到“90%以上都有真憑實(shí)據(jù)”。
我的調(diào)教方法:
- 引用增強(qiáng)(標(biāo)明信息來(lái)源): 我會(huì)要求LLM在生成內(nèi)容時(shí),明確標(biāo)注出哪些信息來(lái)自知識(shí)庫(kù)的哪部分。就像寫學(xué)術(shù)論文必須注明參考文獻(xiàn)一樣,清清楚楚。
- 不確定性表達(dá)(誠(chéng)實(shí)比瞎猜強(qiáng)): 如果知識(shí)庫(kù)里確實(shí)沒(méi)有足夠的信息來(lái)回答你的問(wèn)題,我會(huì)讓LLM坦率地說(shuō)“這個(gè)我不太確定”或者“目前我掌握的信息不足以回答”,而不是硬著頭皮編一個(gè)可能錯(cuò)誤的答案。做個(gè)誠(chéng)實(shí)的顧問(wèn)很重要!
- 多樣性采樣控制(在框架內(nèi)發(fā)揮): 我會(huì)調(diào)整LLM生成過(guò)程中的“隨機(jī)性”程度,在允許它靈活表達(dá)的同時(shí),牢牢控制它不偏離檢索到的真實(shí)信息這個(gè)核心框架。就像即興演講可以精彩,但不能跑題胡說(shuō)。
- 后處理驗(yàn)證(最后一道質(zhì)量關(guān)): 生成答案后,我還會(huì)請(qǐng)其他專門的“驗(yàn)證模型”或者設(shè)定好的規(guī)則來(lái)檢查一下內(nèi)容的準(zhǔn)確性。這就像出版前的最后一道事實(shí)核查工序。
(4) 利用ragas評(píng)估自己的RAG
RAGAS (Retrieval-Augmented Generation Assessment) 它是一個(gè)框架(ragas源碼),它可以幫助我們來(lái)快速評(píng)估RAG系統(tǒng)的性能,為了評(píng)估 RAG 系統(tǒng)。
① 環(huán)境配置
pip install ragas
pip install langchain
pip install chromadb
接下來(lái)我們需要導(dǎo)入存放Openai的api_key,這里我們會(huì)使用openai的gpt-3.5-turbo,對(duì)它的評(píng)估結(jié)果進(jìn)行比對(duì).
import os
import google.generativeai as genai
from dotenv import load_dotenv, find_dotenv
#導(dǎo)入.env配置文件
_ = load_dotenv(find_dotenv())
② Embeddings模型配置
from langchain.embeddings import HuggingFaceBgeEmbeddings
#創(chuàng)建BAAI的embedding
bge_embeddings = HuggingFaceBgeEmbeddings(model_name="BAAI/bge-small-zh-v1.5",
cache_folder="D:\\models")
③ 加載文檔
from langchain.document_loaders import WebBaseLoader
urls = "https://baike.baidu.com/item/恐龍/139019"
loader = WebBaseLoader(urls)
docs = loader.load()
④ 創(chuàng)建父子文檔檢索器可參考這篇文章學(xué)習(xí),在實(shí)踐過(guò)程中,父子文檔檢索是一種特別好用的技術(shù) 父子文檔技術(shù)
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.retrievers import ParentDocumentRetriever
from langchain.storage import InMemoryStore
from langchain.vectorstores import Chroma
#創(chuàng)建主文檔分割器
parent_splitter = RecursiveCharacterTextSplitter(chunk_size=1000)
#創(chuàng)建子文檔分割器
child_splitter = RecursiveCharacterTextSplitter(chunk_size=400)
# 創(chuàng)建向量數(shù)據(jù)庫(kù)對(duì)象
vectorstore = Chroma(
collection_name="split_parents", embedding_function = bge_embeddings
)
# 創(chuàng)建內(nèi)存存儲(chǔ)對(duì)象
store = InMemoryStore()
#創(chuàng)建父文檔檢索器
retriever = ParentDocumentRetriever(
vectorstore=vectorstore,
docstore=store,
child_splitter=child_splitter,
parent_splitter=parent_splitter,
# verbose=True,
search_kwargs={"k": 2}
)
#添加文檔集
retriever.add_documents(docs)
⑤ 創(chuàng)建Chain
LangChain介紹:https://www.langchain.com/
from langchain.prompts import ChatPromptTemplate
from langchain.schema.runnable import RunnableMap
from langchain.schema.output_parser import StrOutputParser
from langchain.chat_models import ChatOpenAI
# from langchain_google_genai import ChatGoogleGenerativeAI
# 創(chuàng)建模型實(shí)例
# model = ChatGoogleGenerativeAI(model="gemini-pro") # 使用Gemini模型
# 創(chuàng)建OpenAI模型
model = ChatOpenAI()
# 創(chuàng)建提示模板
template = """你是一個(gè)問(wèn)答助手。
請(qǐng)根據(jù)以下提供的上下文回答問(wèn)題。
如果你不知道答案,請(qǐng)直接說(shuō)不知道。
回答限制在兩句話以內(nèi),并保持簡(jiǎn)潔。
問(wèn)題: {question}
上下文: {context}
答案:
"""
# 根據(jù)模板生成提示
prompt = ChatPromptTemplate.from_template(template)
# 創(chuàng)建鏈?zhǔn)搅鞒?chain = RunnableMap({
"context": lambda x: retriever.get_relevant_documents(x["question"]), # 獲取與問(wèn)題相關(guān)的文檔作為上下文
"question": lambda x: x["question"] # 提取問(wèn)題
}) | prompt | model | StrOutputParser() # 將流程串聯(lián):上下文+問(wèn)題 -> 提示 -> 模型 -> 輸出解析
⑥ 創(chuàng)建文檔集
RAGAS需要以下信息:
- question:用戶輸入的問(wèn)題。 answer:從 RAG 系統(tǒng)生成的答案(由LLM給出)。
- contexts:根據(jù)用戶的問(wèn)題從外部知識(shí)源檢索的上下文即與問(wèn)題相關(guān)的文檔。
- ground_truths: 人類提供的基于問(wèn)題的真實(shí)(正確)答案。 這是唯一的需要人類提供的信息。
from datasets import Dataset
# 修改后的問(wèn)題列表
questions = [
"恐龍的名字是怎么來(lái)的?",
"恐龍的分類有哪些?",
"哪種恐龍的體型最大?",
"最長(zhǎng)的恐龍是什么?它是在哪里發(fā)現(xiàn)的?",
"恐龍是如何繁殖后代的?",
"恐龍是冷血?jiǎng)游镞€是溫血?jiǎng)游铮?,
"小行星撞擊是恐龍滅絕的主要原因嗎?",
"恐龍滅絕發(fā)生在什么時(shí)間?",
"鱷魚和恐龍有親緣關(guān)系嗎?",
"恐龍?jiān)谟⑽闹腥绾畏Q呼?"
]
# 修改后的參考答案列表
ground_truths = [
["1841年,英國(guó)科學(xué)家理查德·歐文在研究一些像蜥蜴骨頭的化石時(shí),認(rèn)為它們屬于一種史前生物,并將其命名為恐龍,意為‘令人恐懼的蜥蜴’。"],
["恐龍可以分為兩大類:鳥(niǎo)類恐龍和非鳥(niǎo)類恐龍。"],
["恐龍總體來(lái)說(shuō)體型龐大,其中蜥腳類恐龍是已知的最大種類。"],
["目前已知最長(zhǎng)的恐龍是梁龍,體長(zhǎng)可達(dá)27米,它于1907年在美國(guó)懷俄明州被發(fā)現(xiàn)。"],
["恐龍通過(guò)產(chǎn)卵并孵化的方式繁衍后代。"],
["研究表明,恐龍既不是典型的冷血?jiǎng)游铮膊皇峭耆臏匮獎(jiǎng)游铮墙橛趦烧咧g的一種狀態(tài)。"],
["最新研究顯示,小行星撞擊地球可能并非恐龍滅絕的唯一原因,當(dāng)時(shí)脆弱的生態(tài)系統(tǒng)才是導(dǎo)致滅絕的關(guān)鍵因素。"],
["恐龍滅絕的時(shí)間大約是6500萬(wàn)年前,地質(zhì)年代屬于白堊紀(jì)末期或第三紀(jì)初期。"],
["鱷魚是恐龍的現(xiàn)代近親,但它們與非鳥(niǎo)類恐龍的關(guān)系比鳥(niǎo)類更遠(yuǎn)。"],
["‘dinosaur’一詞由英國(guó)古生物學(xué)家理查德·歐文于1842年提出,來(lái)源于希臘語(yǔ)中的‘deinos’(恐怖的)和‘sauros’(蜥蜴)。"]
]
answers = []
contexts = []
# 推理過(guò)程
for query in questions:
answers.append(chain.invoke({"question": query})) # 調(diào)用鏈?zhǔn)搅鞒躺纱鸢? contexts.append([docs.page_content for docs in retriever.get_relevant_documents(query)]) # 獲取相關(guān)上下文
# 構(gòu)造數(shù)據(jù)字典
data = {
"question": questions, # 問(wèn)題
"answer": answers, # 模型生成的答案
"contexts": contexts, # 相關(guān)上下文
"ground_truths": ground_truths # 參考答案
}
# 將字典轉(zhuǎn)換為數(shù)據(jù)集
dataset = Dataset.from_dict(data)
⑦ 評(píng)估
最后我們來(lái)讓RAGAs對(duì)我們的問(wèn)答集進(jìn)行評(píng)估,我們選擇了:context_precision、context_recall、faithfulness、answer_relevancy這4個(gè)作為我們的評(píng)估指標(biāo):
#openai的結(jié)果
from ragas import evaluate
from ragas.metrics import (
faithfulness,
answer_relevancy,
context_recall,
context_precision,
)
result = evaluate(
dataset = dataset,
metrics=[
context_precision,
context_recall,
faithfulness,
answer_relevancy,
],
)
df = result.to_pandas()
df
優(yōu)化RAG的小tips: 注:如果把前面說(shuō)的優(yōu)化方式都做的很好了,RAG的效果大多數(shù)都可以做的很不錯(cuò),下面會(huì)介紹更底層的一些優(yōu)化方式。
分詞預(yù)處理優(yōu)化:
- 常規(guī)方法 文本的分詞直接通過(guò)text.split()處理,即會(huì)將空格,制表符\t、換行符\n等字符,作為分隔依據(jù),這樣操作太過(guò)簡(jiǎn)單。
- 改進(jìn)方式:
1. 預(yù)處理:
- 將所有非單詞字符(字母、數(shù)字、下劃線以外的)替換為空格。
- 全角字符轉(zhuǎn)半角。
- 轉(zhuǎn)換為小寫。
- 繁體中文轉(zhuǎn)簡(jiǎn)體中文。
2. 按語(yǔ)言切分:
- 將預(yù)處理后的文本按語(yǔ)言(中文/非中文)分割成多個(gè)片段。
3. 分段處理:
- 對(duì)于非中文(通常是英文)片段:
- 使用 NLTK 的 `word_tokenize` 進(jìn)行分詞。
- 對(duì)分詞結(jié)果進(jìn)行詞干提取 (PorterStemmer) 和詞形還原 (WordNetLemmatizer)。
- 對(duì)于中文片段:
- 如果片段過(guò)短(長(zhǎng)度<2)或?yàn)榧兇獾挠⑽?數(shù)字模式(如 "abc-def", "123.45"),則直接保留該片段。
- 否則,采用基于詞典的混合分詞策略:
a. 執(zhí)行正向最大匹配 (FMM) 和逆向最大匹配 (BMM) 得到兩組分詞結(jié)果 (`tks` 和 `tks1`)。
b. 比較 FMM 和 BMM 的結(jié)果:
i. 找到兩者從開(kāi)頭開(kāi)始最長(zhǎng)的相同分詞序列,這部分通常是無(wú)歧義的,直接加入結(jié)果。
ii. 對(duì)于 FMM 和 BMM 結(jié)果不一致的歧義部分(即從第一個(gè)不同點(diǎn)開(kāi)始的子串):
- 提取出這段有歧義的原始文本。
- 調(diào)用 `self.dfs_` (深度優(yōu)先搜索) 在這段文本上探索所有可能的分詞組合。
- `self.dfs_` 會(huì)利用Trie詞典,并由 `self.sortTks_` 對(duì)所有組合進(jìn)行評(píng)分和排序。
- 選擇得分最高的分詞方案作為該歧義段落的結(jié)果。
iii.繼續(xù)處理 FMM 和 BMM 結(jié)果中歧義段落之后的部分,重復(fù)步驟 i 和 ii,直到兩個(gè)序列都處理完畢。
c. 如果在比較完所有對(duì)應(yīng)部分后,F(xiàn)MM 或 BMM 仍有剩余(理論上如果實(shí)現(xiàn)正確且輸入相同,剩余部分也應(yīng)相同),
則對(duì)這部分剩余的原始文本同樣使用 `self.dfs_` 進(jìn)行最優(yōu)分詞。
4. 后處理:
- 將所有處理過(guò)的片段(英文詞元、中文詞元)用空格連接起來(lái)。
- 調(diào)用 `self.merge_` 對(duì)連接后的結(jié)果進(jìn)行進(jìn)一步的合并操作,
嘗試合并一些可能被錯(cuò)誤分割但實(shí)際是一個(gè)完整詞的片段(基于詞典檢查)。
5. 返回最終分詞結(jié)果字符串(詞元間用空格分隔)。
專門配置一個(gè)詞典,用來(lái)記錄常見(jiàn)詞匯,詞頻,詞性等信息。為加速查詢速度,構(gòu)建一個(gè)Trie樹(shù)的形式(huqie.txt.trie)。
4. 文檔解析(PDF)
要用好rag的輸出增強(qiáng)效果,文檔解析是關(guān)鍵一環(huán)。如果文檔解析塊存在問(wèn)題,那么后面檢索到的內(nèi)容,也會(huì)對(duì)模型造成錯(cuò)誤干擾。
經(jīng)調(diào)研,開(kāi)源的文檔解析產(chǎn)品主要有MinerU、Marker、MarkItDown、Docling四款主流產(chǎn)品。對(duì)于Doc2X,TextIn等未開(kāi)源的收費(fèi)產(chǎn)品,不在本文的考慮范圍之內(nèi)。
這四款開(kāi)源產(chǎn)品及對(duì)應(yīng)的開(kāi)發(fā)公司如下表所示:
工具名稱 | 開(kāi)發(fā)團(tuán)隊(duì)/公司 |
MinerU | 上海AI實(shí)驗(yàn)室(OpenDataLab) |
Marker | VikParuchuri(個(gè)人開(kāi)發(fā)者) |
MarkItDown | 微軟(Microsoft) |
Docling | IBM |
考慮到本地部署,需要優(yōu)先支持中文文檔的解析,大致瀏覽了一下這四款產(chǎn)品的倉(cāng)庫(kù),發(fā)現(xiàn)MinerU的生態(tài)非常完善,并且文檔都有中文版本,對(duì)本土開(kāi)發(fā)者非常友好,于是對(duì)其進(jìn)行研究。MinerU 有在線試用網(wǎng)頁(yè),可讓用戶直接上傳文件進(jìn)行解析。
地址如下:https://mineru.net/OpenSourceTools/Extractor
我上傳了中相同的論文,相同部分解析效果如下:
二、智能體(Agent)的定義與歷史
1. OPENAI在AGI五級(jí)分類中對(duì)agent的定義
想象一下人工智能的進(jìn)化階梯,就像是從幼兒園到博士后的成長(zhǎng)之路。OpenAI給我們畫了一幅AI成長(zhǎng)的"五年級(jí)"照片墻:
- 第1階段:會(huì)聊天的AI(Conversational AI) 這就像是剛學(xué)會(huì)說(shuō)話的小朋友,能和你有來(lái)有往地聊天,比如我們熟悉的ChatGPT。它能回答你"今天天氣怎么樣",但別指望它能幫你收拾房間——它只會(huì)說(shuō),不會(huì)做!
- 第2階段:會(huì)思考的AI(Reasoners) 這是已經(jīng)上了小學(xué)的AI,不僅會(huì)說(shuō),還會(huì)動(dòng)腦筋。它能在學(xué)術(shù)領(lǐng)域大顯身手,解決復(fù)雜問(wèn)題,就像那個(gè)總是舉手回答問(wèn)題的班上小天才。"老師,我知道這道微積分題怎么解!"
- 第3階段:會(huì)自主行動(dòng)的AI(Agents) 這是已經(jīng)能獨(dú)立生活的青少年AI,可以自己做決定并付諸行動(dòng)。它不需要你時(shí)刻盯著,能自己管理日程、回復(fù)郵件,就像你雇了一個(gè)永不疲倦的私人助理,而且不用發(fā)工資!
- 第4階段:會(huì)創(chuàng)新的AI(Innovators) 這是已經(jīng)成為創(chuàng)意總監(jiān)的AI,不僅解決問(wèn)題,還能提出新點(diǎn)子。它可能某天早上醒來(lái)說(shuō):"嘿,我想到了一種全新的能源技術(shù)!"然后真的幫你設(shè)計(jì)出來(lái)。這時(shí)候,人類工程師可能要開(kāi)始擔(dān)心自己的飯碗了。
- 第5階段:會(huì)管理的AI(Organizers) 這是已經(jīng)坐上CEO寶座的AI,能管理整個(gè)組織,協(xié)調(diào)復(fù)雜流程,效率比人類還高。想象一下,你公司的老板是個(gè)AI,每天早上準(zhǔn)時(shí)發(fā)布完美的工作安排,從不偏袒任何人(除了可能對(duì)打印機(jī)特別友好)。
2. 智能體的核心定義
(1) 智能體(Agent)是什么?
簡(jiǎn)單來(lái)說(shuō),智能體就是一個(gè)數(shù)字版的"全能選手",它能看(感知)、想(決策)、做(執(zhí)行)、學(xué)(學(xué)習(xí)):
- 感知:就像你的眼睛和耳朵,智能體通過(guò)各種"傳感器"獲取信息。它的"眼睛"可能是攝像頭,"耳朵"可能是麥克風(fēng)。
- 決策:這是智能體的"大腦",通過(guò)復(fù)雜算法做出判斷。想象一個(gè)內(nèi)置GPS的出租車司機(jī),不斷計(jì)算最佳路線。
- 執(zhí)行:智能體的"手腳",可能是機(jī)械臂,也可能是軟件指令。就像你決定吃披薩后,手會(huì)自動(dòng)拿起電話叫外賣。
- 學(xué)習(xí):智能體的"成長(zhǎng)能力",它會(huì)從經(jīng)驗(yàn)中學(xué)習(xí)。就像玩游戲,玩得越多,技術(shù)越好,不會(huì)一直犯同樣的錯(cuò)誤(理想情況下)。
(2) 智能體的歷史沿革
智能體的發(fā)展歷程就像是從圖書館管理員到自學(xué)成才的天才的進(jìn)化:
- 1960~1980年代:規(guī)則驅(qū)動(dòng)的智能體 這是"圖書館管理員"階段。所有知識(shí)都必須手動(dòng)輸入,就像是給AI準(zhǔn)備了一本厚厚的"生活指南"。問(wèn)題是,一旦遇到指南上沒(méi)有的情況,它就傻眼了——"對(duì)不起,我的說(shuō)明書上沒(méi)寫這個(gè)"。
- 1990~2010年代:強(qiáng)化學(xué)習(xí)驅(qū)動(dòng)的智能體 這是"試錯(cuò)學(xué)習(xí)"階段。AI開(kāi)始通過(guò)不斷嘗試來(lái)學(xué)習(xí),就像教寶寶走路——摔倒了再爬起來(lái),慢慢就會(huì)了。"我上次這么做摔了一跤,這次我換個(gè)方法試試。"
- 2020年代至今:大模型驅(qū)動(dòng)的智能體 這是"博覽群書"階段。大語(yǔ)言模型(LLM)讓AI能理解和生成人類語(yǔ)言,不需要事無(wú)巨細(xì)的指導(dǎo)就能完成任務(wù)。就像那個(gè)不僅讀過(guò)所有書,還能舉一反三的學(xué)霸,"雖然我沒(méi)做過(guò)這個(gè)具體任務(wù),但根據(jù)我的知識(shí),應(yīng)該這樣解決..."
3. 與其討論 Agent,不如討論 Agentic
討論一個(gè)系統(tǒng)有多"Agentic"(具有智能體特性),就像討論一個(gè)人有多"成人"——關(guān)鍵在于它能自己做多少?zèng)Q定:
- 使用LLM將輸入路由到特定下游工作流: 這就像是個(gè)接線員,只負(fù)責(zé)把你的電話轉(zhuǎn)給合適的部門。"您好,要查詢賬單請(qǐng)按1,要投訴請(qǐng)按2..."
- 使用多個(gè)LLM進(jìn)行多級(jí)路由決策: 這是升級(jí)版接線員,不僅轉(zhuǎn)接電話,還會(huì)根據(jù)你的問(wèn)題做初步分析。"您說(shuō)的問(wèn)題涉及到賬單和配送,我先幫您轉(zhuǎn)到賬單部門,然后..."
- 如果某個(gè)步驟需要決定繼續(xù)執(zhí)行還是終止: 這就像有了一定自主權(quán)的助理,能決定是否繼續(xù)一項(xiàng)任務(wù)。"我看這個(gè)方案行不通,讓我們嘗試另一種方法..."
- 當(dāng)系統(tǒng)能自主構(gòu)建工具、記憶工具并在后續(xù)步驟中使用: 這是真正的"自主智能體",就像一個(gè)全能助手,不僅執(zhí)行任務(wù),還能創(chuàng)造新工具來(lái)解決問(wèn)題。"我發(fā)現(xiàn)這個(gè)問(wèn)題需要特殊工具,我來(lái)設(shè)計(jì)一個(gè),然后用它來(lái)解決..."
三、基于大模型的智能體的原理
"LLM Agent:當(dāng)你的AI助手突然有了上進(jìn)心"
這貨可不是只會(huì)背課文的書呆子!作為大語(yǔ)言模型(LLM)驅(qū)動(dòng)的"最強(qiáng)大腦",它把簡(jiǎn)單聊天變成了"智力奧運(yùn)會(huì)"——既能跟你嘮嗑,又能干活跑腿,甚至偶爾露出"讓我想想"的沉思者表情。
本質(zhì)上是個(gè)披著對(duì)話框外衣的瑞士軍刀:
- 推理能力 - 堪比福爾摩斯,只是破案速度取決于服務(wù)器負(fù)載
- 記憶功能 - 像金魚,但屬于那種會(huì)做筆記的金魚
- 自主性 - 約等于"知道主動(dòng)問(wèn)你要咖啡"的級(jí)別
LLM Agent的定義:
LLM Agent 是通過(guò)與自身之外的其他系統(tǒng)交互來(lái)服務(wù)于用戶目標(biāo)的生成式 AI 系統(tǒng)。換句話說(shuō),它不僅依賴于自身的計(jì)算能力,還需要與其他外部系統(tǒng)協(xié)同工作,從而完成更復(fù)雜的任務(wù)。
LLM Agent的核心組成:
- 大語(yǔ)言模型(Large Language Models) :作為智能體的核心,負(fù)責(zé)理解和處理自然語(yǔ)言,提供推理和決策能力。
- 工具調(diào)用(Tool Invocation) :智能體可以調(diào)用外部工具或 API 來(lái)完成特定任務(wù),例如查詢數(shù)據(jù)庫(kù)、操作文件等。
- 規(guī)劃(Planning) :智能體需要根據(jù)任務(wù)目標(biāo)制定計(jì)劃,決定如何使用資源和工具。
- 記憶(Memory) :智能體需要記住之前的操作和結(jié)果,以便在后續(xù)任務(wù)中參考和優(yōu)化。
LLM Agent的工作流程:
- 感知環(huán)境 :智能體通過(guò)與外部環(huán)境交互,獲取任務(wù)需求和相關(guān)信息。
- 分析任務(wù) :利用大語(yǔ)言模型的強(qiáng)大推理能力,分析任務(wù)并制定解決方案。
- 執(zhí)行任務(wù) :調(diào)用外部工具或 API 執(zhí)行具體操作,逐步完成任務(wù)。
- 反饋與優(yōu)化 :根據(jù)執(zhí)行結(jié)果進(jìn)行學(xué)習(xí)和優(yōu)化,提升未來(lái)的表現(xiàn)。
1. 規(guī)劃(Planning)
(1) 子目標(biāo)分解
① 目的:復(fù)雜任務(wù)通常包含多個(gè)步驟,智能體(Agent)需要了解這些步驟并提前規(guī)劃。前面提到的 CoT(Chain of Thought,思維鏈)及其改進(jìn)方法,本質(zhì)上就是在進(jìn)行任務(wù)分解。
② 任務(wù)分解實(shí)現(xiàn):
- 給LLM提示詞:例如,“Steps for XYZ.\n1. What are the subgoals for achieving XYZ?”
- 使用具體任務(wù)指令:例如,對(duì)于寫小說(shuō)的任務(wù),先給出“Write a story outline.”的指令。
- 用戶直接輸入:用戶可以直接提供任務(wù)分解的步驟。
(2) 關(guān)鍵點(diǎn)
CoT和ToT的本質(zhì):無(wú)論是 CoT 還是 ToT(Thoughts on Thoughts),本質(zhì)上都是通過(guò)精心設(shè)計(jì)的提示詞(Prompt),激發(fā)模型原有的元認(rèn)知能力(Metacognition)。也就是說(shuō),通過(guò)某種線索,能夠更精準(zhǔn)地調(diào)動(dòng)模型中擅長(zhǎng)規(guī)劃的部分。
(3) LLM+P方法
① 整體規(guī)劃:LLM+P 是一種利用規(guī)劃域定義語(yǔ)言(Planning Domain Definition Language, PDDL)來(lái)進(jìn)行長(zhǎng)序列任務(wù)規(guī)劃的方法。
② 工作流程:
- 問(wèn)題翻譯:LLM 將問(wèn)題翻譯成 PDDL 格式。
- 請(qǐng)求經(jīng)典Planner:接著,請(qǐng)求經(jīng)典 Planner 根據(jù)現(xiàn)有的領(lǐng)域 PDDL 生成一個(gè) PDDL Plan(計(jì)劃)。
- 翻譯回自然語(yǔ)言:最后,將 PDDL 計(jì)劃翻譯回自然語(yǔ)言(由 LLM 完成)。
③ 前提條件:這種方法需要特定領(lǐng)域的 PDDL 描述和合適的 Planner。
(4) 反思與完善
Agent的自我反思能力非常重要。它能夠?qū)v史動(dòng)作進(jìn)行自我批評(píng)和反思,從錯(cuò)誤中學(xué)習(xí),并在后續(xù)步驟中不斷優(yōu)化,從而提升最終結(jié)果的質(zhì)量。這種 自我反思(Self-reflection) 是 Agent 不斷改進(jìn)的關(guān)鍵環(huán)節(jié)。在現(xiàn)實(shí)世界中,犯錯(cuò)是不可避免的,而自我反思在其中發(fā)揮著至關(guān)重要的作用。
(5) ReAct框架
ReAct是一種結(jié)合了 Reasoning(推理) 和 Action(行動(dòng)) 的方法。它的核心思想是通過(guò)擴(kuò)展 Action Space,使其包含特定任務(wù)的離散動(dòng)作和語(yǔ)言空間的組合。具體來(lái)說(shuō):
- Reasoning:幫助 LLM 與環(huán)境進(jìn)行交互。
- Action:通過(guò)提示詞,讓 LLM 使用自然語(yǔ)言生成完整的推理過(guò)程。
ReAct 的提示詞模板提供了一個(gè)明確的思考步驟,大致格式如下:
Thought: ... Action: ... Observation: ...
(6) ReAct的優(yōu)勢(shì)
在知識(shí)密集型任務(wù)和決策任務(wù)的實(shí)驗(yàn)中,ReAct 的表現(xiàn)優(yōu)于傳統(tǒng)的單一 Act... 方式。這是因?yàn)?ReAct 能夠更好地結(jié)合推理和行動(dòng),使 Agent 更加靈活和高效。
(7) Reflexion框架
Reflexion 是一個(gè)讓 Agent 具備動(dòng)態(tài)記憶和自我反思能力的框架,旨在提高其推理能力。它采用標(biāo)準(zhǔn)的強(qiáng)化學(xué)習(xí)(RL)設(shè)置:
- 獎(jiǎng)勵(lì)模型:提供簡(jiǎn)單的二進(jìn)制獎(jiǎng)勵(lì)(成功或失敗)。
- Action Space:在 ReAct 的基礎(chǔ)上,進(jìn)一步擴(kuò)展為特定任務(wù)的行動(dòng)空間,并加入語(yǔ)言支持,以實(shí)現(xiàn)更復(fù)雜的推理步驟。
在每個(gè)行動(dòng) a(t) 之后,Agent 會(huì)計(jì)算一個(gè)啟發(fā)式函數(shù) h(t),并根據(jù)自我反思的結(jié)果決定是否重置環(huán)境,開(kāi)始一個(gè)新的循環(huán)。
2. 記憶(Memory)
(1) 記憶的分類與實(shí)現(xiàn)
① 短期記憶(短期學(xué)習(xí))
上下文學(xué)習(xí):這是模型的一種短期記憶能力,類似于人類的短期記憶,能夠記住最近的信息或上下文。
② 長(zhǎng)期記憶
- 長(zhǎng)期記憶功能:為智能體提供保留和召回長(zhǎng)期信息的能力。
- 實(shí)現(xiàn)方式:通過(guò)外部向量存儲(chǔ)和檢索來(lái)實(shí)現(xiàn)。
(2) 人腦中的記憶類型
記憶可以定義為用于獲取、存儲(chǔ)、保留和隨后檢索信息的過(guò)程。人腦中有多種類型的記憶:
① 感官記憶:
這是記憶的最早階段,是在接受原始刺激后保留的感官信息(如視覺(jué)、聽(tīng)覺(jué)、觸覺(jué))的能力。
感官記憶通常只能持續(xù)幾秒鐘,主要包括以下幾種:
- 圖示記憶(Iconic memory,視覺(jué)):對(duì)視覺(jué)信息的短暫記憶。
- 回聲記憶(Echoic memory,聽(tīng)覺(jué)):對(duì)聽(tīng)覺(jué)信息的短暫記憶。
- 觸碰記憶(Haptic memory,觸覺(jué)):對(duì)觸覺(jué)信息的短暫記憶。
② 短時(shí)記憶(STM)或工作記憶:
- 它存儲(chǔ)了我們當(dāng)前意識(shí)到的信息,以及執(zhí)行復(fù)雜認(rèn)知任務(wù)(如學(xué)習(xí)和推理)所需的信息。
- 短時(shí)記憶被認(rèn)為有大約 7 個(gè)項(xiàng)目的容量,并能夠持續(xù) 20-30 秒。
③ 長(zhǎng)時(shí)記憶(LTM):
長(zhǎng)時(shí)記憶可以將信息存儲(chǔ)很長(zhǎng)時(shí)間,從幾天到幾十年不等,存儲(chǔ)容量基本上是無(wú)限的。
長(zhǎng)時(shí)記憶分為兩種:
- 顯性/陳述性記憶:對(duì)事實(shí)和事件的記憶,指那些可以有意識(shí)地回憶起的記憶,包括外顯記憶(事件和經(jīng)歷)和語(yǔ)義記憶(事實(shí)和概念)。
- 隱形/程序性記憶:這種記憶是無(wú)意識(shí)的,涉及自動(dòng)執(zhí)行的技能和例行程序,如騎車、在鍵盤上打字。
(3) 最大內(nèi)部產(chǎn)品搜索(MIPS)
為了緩解關(guān)注范圍有限的限制,可以通過(guò)使用外部存儲(chǔ)器來(lái)優(yōu)化檢索速度。常見(jiàn)的選擇是 ANN(人工神經(jīng)網(wǎng)絡(luò))算法,返回近似的 top k 個(gè)近鄰,用少量精度損失換取速度的巨大提升。以下是幾種常見(jiàn)的 ANN 算法選擇進(jìn)行快速 MIPS 的方法:
① LSH(locality-sensitive hashing):
引入了一種哈希函數(shù),能夠最大限度地將相似的輸入項(xiàng)映射到同一個(gè)桶中,其中桶的數(shù)量遠(yuǎn)小于輸入內(nèi)容的數(shù)量。
② ANNOY(Approximate Nearest Neighbors Oh Yeah):
核心數(shù)據(jù)結(jié)構(gòu)是隨機(jī)投影樹(shù),它是一個(gè)二叉樹(shù)集合,每個(gè)非葉子節(jié)點(diǎn)表示將輸入空間劃分為兩半的一個(gè)超平面,每個(gè)葉子節(jié)點(diǎn)存儲(chǔ)一個(gè)數(shù)據(jù)點(diǎn)。
這些樹(shù)是獨(dú)立隨機(jī)構(gòu)建的,在某種程度上,它模擬了一個(gè)哈希函數(shù)的作用。
ANNOY 的搜索發(fā)生在所有樹(shù)中,迭代地搜索最接近查詢的那一半,然后聚合結(jié)果。其思想與 KD 樹(shù)非常相關(guān),但可擴(kuò)展性更強(qiáng)。
③ HNSW(Hierarchical Navigable Small World)
設(shè)計(jì)思想:HNSW 的設(shè)計(jì)理念來(lái)源于“小世界網(wǎng)絡(luò)”理論。在小世界網(wǎng)絡(luò)中,每個(gè)節(jié)點(diǎn)只需要通過(guò)很少的步驟就可以連接到任何其他節(jié)點(diǎn),就像社交網(wǎng)絡(luò)中的“六度分隔”現(xiàn)象一樣。
結(jié)構(gòu)特點(diǎn):
- HNSW 構(gòu)建了多層的小世界網(wǎng)絡(luò)結(jié)構(gòu),底層包含實(shí)際的數(shù)據(jù)點(diǎn)。
- 中間層添加了一些“快捷鍵”,用于加速搜索過(guò)程。
搜索過(guò)程:
- 在進(jìn)行搜索時(shí),HNSW 從頂層的一個(gè)隨機(jī)節(jié)點(diǎn)開(kāi)始,逐步導(dǎo)航向目標(biāo)節(jié)點(diǎn)移動(dòng)。
- 如果在某一層無(wú)法接近目標(biāo),它會(huì)下降到下一層,直到到達(dá)底層。
- 在上層每一步導(dǎo)航都能潛在地跨越數(shù)據(jù)空間中的大距離,而在下層每一步導(dǎo)航可以提高搜索的質(zhì)量。
④ FAISS
核心假設(shè):FAISS 基于一個(gè)假設(shè),即在高維空間中,節(jié)點(diǎn)之間的距離遵循高斯分布,因此應(yīng)該存在數(shù)據(jù)聚類。
實(shí)現(xiàn)方式:
- FAISS 通過(guò)向量量化來(lái)實(shí)現(xiàn)。首先將向量空間劃分為若干集群,然后在每個(gè)集群內(nèi)進(jìn)行更精細(xì)的量化。
- 在搜索時(shí),首先使用粗粒度的量化查找可能的集群候選,然后在每個(gè)候選集群內(nèi)使用更細(xì)致的量化進(jìn)行進(jìn)一步查找。
⑤ ScaNN(Scalable Nearest Neighbor Search)
主要?jiǎng)?chuàng)新:ScaNN 算法的主要?jiǎng)?chuàng)新在于使用了各向異性向量量化。它對(duì)數(shù)據(jù)點(diǎn)進(jìn)行向量化,使得內(nèi)積 <q,> 盡可能與原始距離相似,而不是選擇最接近的量化質(zhì)心點(diǎn)。
3. 工具使用(tool use)
對(duì)模型權(quán)重丟失的信息,agent學(xué)習(xí)調(diào)用外部API獲取額外信息,包括當(dāng)前信息、代碼執(zhí)行能力、專有信息源的訪問(wèn)等等。
(1) 智能體與LLM的區(qū)別
① LLM
和LLM的對(duì)話就是:你輸入一個(gè)提示,大模型生成一個(gè)回答。
Plain Text 用戶輸入:幫我寫一篇科幻主題的文章 模型輸出:文章xxxxxxxxxxxxxxxxxxxxx
② Agent
和Agent的對(duì)話就是:你有一個(gè)助手,你不是簡(jiǎn)單地直接寫,先詢問(wèn)你是否需要進(jìn)行一些網(wǎng)絡(luò)研究,然后寫下初稿,然后回顧初稿,并思考哪些部分需要修改,然后修改草稿,不斷進(jìn)行思考和迭代這個(gè)過(guò)程。這個(gè)流程是一個(gè)思考+迭代的過(guò)程。
Plain Text 用戶輸入:幫我寫一篇科幻主題的文章 Step 1: 思考和規(guī)劃 Step 2: 聯(lián)網(wǎng)搜索 Step 3: 確定主體大綱 Step 4: 優(yōu)化修改 模型輸出:文章xxxxxxxxxxxxxxxxxxxxx
(2) 與強(qiáng)化學(xué)習(xí)智能體的區(qū)別
- 強(qiáng)化學(xué)習(xí)智能體:輸入為預(yù)設(shè)好的向量化的環(huán)境狀態(tài)(或者圖像),策略通常由簡(jiǎn)單的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)進(jìn)行初始化,輸出動(dòng)作多為底層控制(移動(dòng)、攻擊等)。
- 基于大模型的智能體:輸入為文字(多模態(tài)場(chǎng)景下也會(huì)有視覺(jué)、語(yǔ)音等信息),策略為預(yù)訓(xùn)練的具備世界知識(shí)的大語(yǔ)言模型,輸出動(dòng)作為文本,但可以通過(guò)結(jié)構(gòu)化輸出和提取實(shí)現(xiàn) function_call,進(jìn)一步與現(xiàn)實(shí)環(huán)境進(jìn)行交互。
四、智能體的分類
1. 按照數(shù)量分類
- SingleAgent:?jiǎn)蝹€(gè)智能體進(jìn)行任務(wù)規(guī)劃與行動(dòng)。
- MultiAgent:強(qiáng)調(diào)多樣化的 agent profiles,agents 間交流相互作用和集體決策過(guò)程。更多動(dòng)態(tài)和復(fù)雜的任務(wù)可以通過(guò)多個(gè)自主智能體的協(xié)作、辯論、討論來(lái)完成,每個(gè)智能體都具有獨(dú)特的策略和行為,并相互之間進(jìn)行通信。
2. 按照行為模式分類
(1) Tool Use Agent
- MRKL system:Modular Reasoning, Knowledge, and Language(模塊化推理、知識(shí)和語(yǔ)言)。一個(gè) LLM 作為 router 提供對(duì)多種工具的訪問(wèn),然后 router 可以多次調(diào)用工具獲取諸如時(shí)間、天氣等信息,然后結(jié)合這些信息給出回復(fù)。下面的相關(guān)工作都是類似的技術(shù),大部分還包含了微調(diào):Toolformer、Gorilla、Act-1、Hugging-gpt、ToolkenGPT。
- CRITIC:Self-Correcting with Tool-Interactive Critiquing利用工具交互評(píng)價(jià)來(lái)自我修正。首先根據(jù) prompt 生成回答,然后同樣的 LLM 對(duì)答案中可能出現(xiàn)的錯(cuò)位進(jìn)行 criticize,最后使用相應(yīng)的外部工具,如聯(lián)網(wǎng)搜索、代碼解釋器對(duì)部分回答進(jìn)行驗(yàn)證或修正。CRITIC 流程圖:
(2) Code Generation Agent
代碼編寫和執(zhí)行能力也是一項(xiàng)重要的 Agent 能力,也可以被劃分為 Tool Use Agents(Tool 就是代碼解釋器等)。
① Program-aided LM
將問(wèn)題直接轉(zhuǎn)換為 code,然后利用 Python 解釋器生成答案。
② Tool-Integrated Reasoning Agent
類似 PAL,但是 code 和推理多步交叉直到解決問(wèn)題。PAL 是單個(gè) code-gen step。下圖是 CoT、PAL 和本文的對(duì)比:
③ TaskWeaver
也是類似 PAL,但是可以利用用戶定義的插件。
Observation-based Agent:一些 Agents 被設(shè)計(jì)為通過(guò)與(gym 之類的環(huán)境)交互來(lái)解決問(wèn)題,這些基于 Obs 的 Agent 會(huì)將接收到的觀測(cè)插入到 Prompt 中。
RAG Agent:從外部來(lái)源(本地知識(shí)庫(kù)等)檢索信息并插入 prompt 的范式,可以提高知識(shí)密集型任務(wù)的性能。RAG 其實(shí)也是一種特殊的 Agent,一般都是調(diào)用外部數(shù)據(jù)庫(kù)/向量庫(kù)作為工具。
④ 智能體系統(tǒng)分類
從架構(gòu)上看,Agentic system 可以分為兩大類系統(tǒng):
工作流(Workflow) :
- 通過(guò)預(yù)定義代碼路徑編排 LLM 和工具。
- 適用于任務(wù)明確、步驟可預(yù)定義的場(chǎng)景。
自主智能體(Autonomous Agent) :
- LLM 動(dòng)態(tài)控制決策和工具使用。
- 自主規(guī)劃任務(wù)。
- 適用于任務(wù)步驟難以預(yù)知、需長(zhǎng)期自主規(guī)劃的場(chǎng)景。
五、智能體評(píng)估框架
1. AgentBench
AgentBench 的核心思想是,將LLM作為Agent進(jìn)行評(píng)估。
其8種實(shí)際場(chǎng)景可以歸為三類:
- 編碼 :讓LLM生成代碼,操作系統(tǒng)、數(shù)據(jù)庫(kù)和知識(shí)圖譜屬于編碼類型。
- 游戲 :讓LLM扮演游戲角色,數(shù)字卡牌游戲、橫向思維謎題、持家游戲?qū)儆谟螒蝾愋汀?/li>
- Web :讓LLM完成與網(wǎng)頁(yè)相關(guān)的任務(wù),網(wǎng)購(gòu)和瀏覽網(wǎng)頁(yè)屬于Web類型。
六、智能體實(shí)踐
1. 基于openai接口實(shí)現(xiàn)簡(jiǎn)單的agent
from openai import OpenAI
import json
# 初始化 OpenAI 客戶端
client = OpenAI(api_key="sk-api_key")
# 定義工具:查詢股票價(jià)格
tools = [
{
"type": "function",
"function": {
"name": "get_stock_price",
"description": "Get the current price of a given stock.",
"parameters": {
"type": "object",
"properties": {
"symbol": {
"type": "string",
"description": "Stock symbol e.g. AAPL, GOOGL"
}
},
"required": ["symbol"],
"additionalProperties": False
},
"strict": True
}
}
]
# 用戶消息:詢問(wèn)某只股票的價(jià)格
messages = [{"role": "user", "content": "What's the current price of Apple stock?"}]
# 調(diào)用 OpenAI 的 chat completions API
completion = client.chat.completions.create(
model="gpt-4",
messages=messages,
tools=tools,
)
# 打印模型的回復(fù)
print(completion.choices[0].message.content)
2. 基于Langchain實(shí)現(xiàn)一個(gè)簡(jiǎn)單的React Agent
from langchain.chains import LLMMathChain, LLMChain
from langchain.agents import Tool, initialize_agent, AgentType
from langchain.prompts import PromptTemplate
from langchain import OpenAI
import os
# 設(shè)置 OpenAI API 密鑰
os.environ["OPENAI_API_KEY"] = "your_api_key"
# 初始化 LLM 模型
llm = OpenAI(temperature=0)
# 工具 1:翻譯工具
def translate_text(text, target_language):
"""模擬翻譯功能,將文本翻譯為目標(biāo)語(yǔ)言"""
# 這里可以替換為實(shí)際的翻譯邏輯,例如調(diào)用翻譯 API
returnf"Translated text: {text} (to {target_language})"
translate_tool = Tool(
name='Translator',
func=lambda x: translate_text(x['text'], x['target_language']),
descriptinotallow='Useful for translating text from one language to another.'
)
# 工具 2:天氣查詢工具
def get_weather(location):
"""模擬天氣查詢功能,返回指定位置的天氣信息"""
# 這里可以替換為實(shí)際的天氣查詢邏輯,例如調(diào)用天氣 API
returnf"Weather in {location}: Sunny with a high of 75°F and low of 60°F."
weather_tool = Tool(
name='WeatherChecker',
func=lambda x: get_weather(x['location']),
descriptinotallow='Useful for getting the current weather for a given location.'
)
# 將所有工具存進(jìn)一個(gè)數(shù)組中
tools = [translate_tool, weather_tool]
# 初始化 ReAct Agent
react_agent = initialize_agent(
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
tools=tools,
llm=llm,
verbose=True
)
# 測(cè)試 ReAct Agent
print(react_agent.run("What's the weather like in New York?"))
print(react_agent.run("Translate 'Hello' to Spanish."))
3. Manus分析& OpenManus技術(shù)方案
https://manus.im/share/OZB4PvsXY5N5FrvLXqqCl4?replay=1
注:這篇文章很多格式的處理就是通過(guò)manus幫我完成的
4. Manus的工作原理
Manus 是一個(gè)多智能體系統(tǒng),它在完成任務(wù)時(shí)會(huì)按照以下步驟進(jìn)行:
① 任務(wù)拆分:
- Manus 首先使用 PlanningTool 對(duì)任務(wù)進(jìn)行規(guī)劃,將復(fù)雜任務(wù)拆分成多個(gè)子任務(wù)。
- 這些子任務(wù)會(huì)被組織成一個(gè)線性的計(jì)劃,每個(gè)任務(wù)都有明確的執(zhí)行順序。
② 分配與執(zhí)行:
- 每個(gè)子任務(wù)會(huì)被分配給相應(yīng)的智能體(Agent)。
- Agent 在執(zhí)行任務(wù)的過(guò)程中,會(huì)以 ReAct 循環(huán)的形式調(diào)用工具來(lái)完成任務(wù)。ReAct 循環(huán)指的是“思考(Reason)+ 行動(dòng)(Act)”,即 Agent 會(huì)先思考如何解決問(wèn)題,然后通過(guò)調(diào)用工具來(lái)執(zhí)行具體的操作。
③ 記錄進(jìn)度:
Manus 使用 TODO.md 文件來(lái)記錄任務(wù)的完成情況,幫助跟蹤進(jìn)度。
5. Manus的核心能力
① 規(guī)劃能力:
- Manus 使用 PlanningTool 來(lái)規(guī)劃任務(wù),形成一個(gè)清晰的任務(wù)分解計(jì)劃。
- 根據(jù)測(cè)試,這種規(guī)劃能力在 SWEBench 上的表現(xiàn)非常出色,解決率從 49% 提升到了 70%,其中一部分提升來(lái)自于模型本身的優(yōu)化,另一部分則來(lái)自于規(guī)劃工具的效果。
② 工具使用能力:
Manus 結(jié)合了 Claude+ 和其他經(jīng)過(guò)微調(diào)的模型,這些模型在工程上做了大量?jī)?yōu)化,增強(qiáng)了它們?cè)诓煌瑘?chǎng)景下的工具使用能力。
6. OpenManus的特點(diǎn)
OpenManus 是基于 Manus 的規(guī)劃優(yōu)勢(shì)開(kāi)發(fā)的,它繼承了 Manus 的任務(wù)分解能力,并在此基礎(chǔ)上進(jìn)行了改進(jìn)。以下是 OpenManus 的主要特點(diǎn):
① 極簡(jiǎn)可插拔框架:
- OpenManus 的核心是一個(gè)簡(jiǎn)潔的 Agent 框架,強(qiáng)調(diào)模塊化和擴(kuò)展性。
- 開(kāi)發(fā)者可以通過(guò)自由組合 Prompt(提示詞)和 Tools(工具),快速定義 Agent 的行為邏輯和功能。
- 例如,Prompt 決定了 Agent 的思考方式,而 Tools 則提供了具體的行動(dòng)能力(如代碼執(zhí)行、搜索、文件操作等)。
② 工具驅(qū)動(dòng)的ReAct Agent:
- OpenManus 基于 ReAct(Reason + Act)模式,以工具為核心驅(qū)動(dòng) Agent 的行動(dòng)。
- Prompt 引導(dǎo) Agent 的推理和邏輯,而 Tools 則賦予 Agent 行動(dòng)能力。
- 這種設(shè)計(jì)讓 Agent 不僅能“思考問(wèn)題”,還能“執(zhí)行任務(wù)”。
③ 規(guī)劃能力處理復(fù)雜任務(wù):
- OpenManus 繼承了 Manus 的多智能體規(guī)劃優(yōu)勢(shì),通過(guò) PlanningTool 對(duì)用戶需求進(jìn)行高層次的規(guī)劃。
- 它將復(fù)雜的任務(wù)分解為線性的子任務(wù)計(jì)劃,顯著提升了任務(wù)的成功率。
- 這種“先規(guī)劃,后執(zhí)行”的思路,在處理長(zhǎng)鏈條任務(wù)時(shí)尤為有效。
動(dòng)態(tài)Agent分配與工具調(diào)度:
- 當(dāng)一個(gè)任務(wù)被拆解為多個(gè)子任務(wù)后,系統(tǒng)會(huì)根據(jù)任務(wù)類型,動(dòng)態(tài)分配給預(yù)先定義或適配的 Agent。
- 這種“臨時(shí)分配 + 工具協(xié)作”的機(jī)制,最大化利用了多模型、多工具的組合優(yōu)勢(shì),提高了系統(tǒng)的靈活性和效率。
結(jié)束語(yǔ):
“以上淺見(jiàn),不過(guò)是我在鵝廠的一點(diǎn)實(shí)踐心得。技術(shù)之路沒(méi)有銀彈,Agent與RAG的探索也遠(yuǎn)未到終局。文中的方案必然存在局限,懇請(qǐng)各位前輩同仁不吝指正。若這些血淚經(jīng)驗(yàn)?zāi)転槟?jié)省幾分鐘調(diào)試時(shí)間,或帶來(lái)一絲靈感火花,便已值得。AI浪潮奔涌,愿與諸君共同探索——畢竟,真正的通關(guān)地圖,永遠(yuǎn)由所有實(shí)踐者共同繪制。”