開源大語言模型作為 LangChain 智慧體

發表於2024-02-22

概要

開源大型語言模型 (LLMs) 現已達到一種效能水平,使它們適合作為推動智慧體工作流的推理引擎: Mixtral 甚至在我們的基準測試中 超過了 GPT-3.5,並且透過微調,其效能可以輕易的得到進一步增強。

引言

針對 因果語言建模 訓練的大型語言模型 (LLMs) 可以處理廣泛的任務,但它們經常在邏輯、計算和搜尋等基本任務上遇到困難。最糟糕的情況是,它們在某個領域,比如數學,表現不佳,卻仍然試圖自己處理所有計算。

為了克服這一弱點,除其他方法外,可以將 LLM 整合到一個系統中,在該系統中,它可以呼叫工具: 這樣的系統稱為 LLM 智慧體。

在這篇文章中,我們將解釋 ReAct 智慧體的內部工作原理,然後展示如何使用最近在 LangChain 中整合的 ChatHuggingFace 類來構建它們。最後,我們將幾個開源 LLM 與 GPT-3.5 和 GPT-4 進行基準測試。

什麼是智慧體?

LLM 智慧體的定義非常寬泛: 它們指的是所有將 LLMs 作為核心引擎,並能夠根據觀察對其環境施加影響的系統。這些系統能夠透過多次迭代“感知 ⇒ 思考 ⇒ 行動”的迴圈來實現既定任務,並常常融入規劃或知識管理系統以提升其表現效能。你可以在 Xi et al., 2023 的研究中找到對智慧體領域綜述的精彩評述。

今天,我們將重點放在 ReAct 智慧體 上。ReAct 採用一種基於“推理 (Reasoning)”與“行動 (Acting)”結合的方式來構建智慧體。在提示詞中,我們闡述了模型能夠利用哪些工具,並引導它“逐步”思考 (亦稱為 思維鏈 行為),以規劃並實施其後續動作,達成最終的目標。

ReAct 智慧體內部工作原理示例

上述圖解雖顯得有些抽象,但其核心原理其實相當直接。

參見 此筆記本: 我們藉助 Transformers 庫展示了一個最基礎的工具呼叫例項。

本質上,LLM 透過一個迴圈被呼叫,迴圈中的提示包含如下內容:

這裡是一個問題: “{question}”
你可以使用這些工具: {tools_descriptions}。
首先,你需要進行‘思考: {your_thoughts}’,接下來你可以:
- 以正確的 JSON 格式發起工具呼叫,
- 或者,以‘最終答案:’為字首來輸出你的答案。

接下來,你需要解析 LLM 的輸出:

  • 如果輸出中包含‘最終答案:’ 字串,迴圈便結束,並輸出該答案;
  • 若不包含,則表示 LLM 進行了工具呼叫: 你需解析此輸出以獲得工具的名稱及其引數,隨後根據這些引數執行相應工具的呼叫。此工具呼叫的結果將被追加至提示資訊中,然後你將帶有這些新增資訊的提示再次傳遞給 LLM,直至它獲得足夠的資訊來給出問題的最終答案。

例如,LLM 的輸出在回答問題: 1:23:45 中有多少秒? 時可能看起來像這樣:

思考: 我需要將時間字串轉換成秒。

動作:
{
    "action": "convert_time",
    "action_input": {
        "time": "1:23:45"
    }
}

鑑於此輸出未包含 ‘最終答案:’ 字串,它代表進行了工具呼叫。因此我們解析該輸出,獲取工具呼叫的引數: 以引數 {"time": "1:23:45"} 呼叫 convert_time 工具,執行該工具呼叫後返回 {'seconds': '5025'}

於是,我們將這整個資訊塊追加至提示詞中。

更新後的提示詞現在變為 (更為詳盡的版本):

這是一個問題: “1:23:45 包含多少秒?”
你可以使用以下工具:
    - convert_time: 將小時、分鐘、秒格式的時間轉換為秒。

首先,進行“思考: {your_thoughts}”,之後你可以:
- 使用正確的 JSON 格式呼叫工具,
- 或以“最終答案:”為字首輸出你的答案。

思考: 我需要把時間字串轉換成秒數。

行動:
{
    "action": "convert_time",
    "action_input": {
        "time": "1:23:45"
    }
}
觀測結果: {'seconds': '5025'}

➡️ 我們用這個新的提示再次呼叫 LLM,鑑於它可以訪問工具呼叫結果中的 觀測結果 ,LLM 現在最有可能輸出:

思考: 我現在有了回答問題所需的資訊。
最終答案: 1:23:45 中有 5025 秒。

任務就這樣完成了!

智慧體系統的挑戰

一般來說,執行 LLM 引擎的智慧體系統的難點包括:

  1. 從提供的工具中選擇一個能夠幫助實現目標的工具: 例如,當詢問“大於 30,000 的最小質數是什麼?” 時,智慧體可能會呼叫“K2 的高度是多少?”Search 工具,但這並無幫助。
  2. 以嚴格的引數格式呼叫工具: 例如,在嘗試計算一輛汽車 10 分鐘內行駛 3 公里的速度時,你必須呼叫Calculator 工具,透過distance 除以time 來計算: 即便你的 Calculator 工具接受 JSON 格式的呼叫{“tool”: “Calculator”, “args”: “3km/10min”} ,也存在許多陷阱,例如:

    • 工具名稱拼寫錯誤: “calculator”“Compute” 是無效的
    • 提供的是引數名稱而非其值: “args”: “distance/time”
    • 格式非標準化: “args": "3km in 10minutes”
  3. 高效地吸收和利用過去觀察到的資訊,無論是初始上下文還是使用工具後返回的觀察結果。

那麼,完整的智慧體設定會是怎樣的呢?

使用 LangChain 執行智慧體

我們剛剛在 🦜🔗LangChain 中整合了一個 ChatHuggingFace 封裝器,使你能夠基於開源模型建立智慧體。

建立 ChatModel 併為其配備工具的程式碼非常簡單,你可以在 Langchain 文件 中檢視所有相關程式碼。

from langchain_community.llms import HuggingFaceHub
from langchain_community.chat_models.huggingface import ChatHuggingFace

llm = HuggingFaceHub(
    repo_id="HuggingFaceH4/zephyr-7b-beta",
    task="text-generation",
)

chat_model = ChatHuggingFace(llm=llm)

你可以透過為其提供 ReAct 風格的提示詞和工具,將 chat_model 轉化為一個智慧體:

from langchain import hub
from langchain.agents import AgentExecutor, load_tools
from langchain.agents.format_scratchpad import format_log_to_str
from langchain.agents.output_parsers import (
    ReActJsonSingleInputOutputParser,
)
from langchain.tools.render import render_text_description
from langchain_community.utilities import SerpAPIWrapper

# 設定工具
tools = load_tools(["serpapi", "llm-math"], llm=llm)

# 設定 ReAct 風格的提示詞
prompt = hub.pull("hwchase17/react-json")
prompt = prompt.partial(
    tools=render_text_description(tools),
    tool_names=", ".join([t.name for t in tools]),
)

# 定義智慧體
chat_model_with_stop = chat_model.bind(stop=["\nObservation"])
agent = (
    {
        "input": lambda x: x["input"],
        "agent_scratchpad": lambda x: format_log_to_str(x["intermediate_steps"]),
    }
    | prompt
    | chat_model_with_stop
    | ReActJsonSingleInputOutputParser()
)

# 例項化 AgentExecutor
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

agent_executor.invoke(
    {
        "input": "Who is the current holder of the speed skating world record on 500 meters? What is her current age raised to the 0.43 power?"
    }
)

智慧體將處理如下輸入:

思考: 為了回答這個問題,我需要找出當前速滑世界紀錄保持者的年齡。我將使用搜尋工具來獲取這些資訊。
行動:
{
"action": "search",
"action_input": " 速滑 500 米世界紀錄保持者的年齡 "
}
觀察: ...

智慧體對決: 開源 LLM 作為通用推理智慧體的表現如何?

你可以在 這裡 找到這個基準測試的程式碼。

評估

我們旨在評估開源大型語言模型 (LLMs) 作為通用推理智慧體的表現。因此,我們選擇了需要運用邏輯和使用基本工具 (如計算器和網際網路搜尋訪問) 的問題。

最終資料集 是從其他三個資料集中選取樣本的組合:

  • 為了測試網際網路搜尋能力,我們選取了 HotpotQA 中的問題: 雖然這是一個檢索型資料集,但它也可用於需要網際網路訪問的通用問題解答。有些問題原本需要結合來自不同來源的資訊: 在我們的設定中,這意味著需要進行多步網際網路搜尋以整合結果。
  • 對於計算器的應用,我們加入了來自 GSM8K 的問題: 這個資料集測試小學數學能力,並且完全可以透過正確利用 4 個運算子 (加、減、乘、除) 來解決。
  • 我們還從 GAIA 中挑選了問題,這是一個對通用 AI 助理來說極具挑戰性的基準測試。原始資料集中的問題可能需要許多其他不同的工具,如程式碼直譯器或 PDF 閱讀器: 我們精選了那些僅需搜尋和計算器的問題。

評估採用了 GPT-4 作為評判員,基於 Prometheus 提示格式 的提示進行,結果以 5 點李克特量表 (5-point Likert Scale) 表示: 具體的提示內容可在 此處 檢視。

模型

我們評估了一些強大的開源模型:

這些模型透過 LangChain 的 ReAct 實現 進行了評估

這意味著我們引導它們按照以下格式輸出函式呼叫:

{
  "action": $TOOL_NAME,
  "action_input": $INPUT
}

作為比較,我們還利用 LangChain 的 專為 OpenAI 設計的智慧體 對 GPT-3.5 和 GPT-4 在相同的例子上進行了評估。

由於這涉及到它們自己的函式呼叫模板,並在此基礎上進行了微調,這意味著 OpenAI 模型應當展現出最佳效能。

結果

鑑於開源模型並沒有針對特定的輸出格式進行特別的函式呼叫微調,相較於 OpenAI 智慧體,它們處於稍微不利的位置。

儘管存在這樣的不利條件,某些模型的表現依然非常優秀!💪

這是 Mixtral-8x7B 回答“貴陽和塔城哪個城市人口更多?”問題的示例:

思考: 為了回答這個問題,我需要找到貴陽和塔城當前的人口數。我將利用搜尋工具來查詢這些資訊。
操作:
{
    "action": "search",
    "action_input": " 貴陽當前人口 "
}
4.697 百萬 (2016 年)

思考: 我已獲得貴陽的人口數,為 4.697 百萬 (截至 2016 年)。現在,我將再次使用搜尋工具來確定塔城的人口數。
操作:
{
    "action": "search",
    "action_input": " 塔城當前人口 "
}
人口: 新疆: 塔城的資料在 2021 年報告為 1,110,000 人。這比 2020 年的 1,138,638 人有所下降。
人口: 新疆: 塔城的資料每年更新,從 2005 年 12 月到 2021 年,平均人口為 1,023,000 人,共 17 次觀察。

我已確定塔城的人口約為 1.11 百萬 (截至 2021 年)。對比兩地人口,貴陽的人口超過塔城。

思考: 我現在清楚最終答案了
最終答案: 貴陽的人口更多,約為 4.697 百萬 (截至 2016 年),而塔城的人口約為 1.11 百萬 (截至 2021 年)。

這是各模型在我們的評估資料集上的基準測試結果 (原始平均分按 1-5 的評分量表,已轉換為 0-100%的量表以便閱讀):

正如所見,一些開源模型在推動智慧體工作流程方面表現欠佳: 雖然對於小型的 Zephyr-7b 而言這是預期之中的,但令人驚訝的是 Llama2-70b 的表現相當差。

👉 然而,Mixtral-8x7B 的表現非常出色: 它甚至超越了 GPT-3.5!🏆

這是即開即用的效能: 與 GPT-3.5 不同的是,據我們所知,Mixtral 沒有針對智慧體工作流程進行過微調 ,這在一定程度上影響了其效能。例如,在 GAIA 上,因為 Mixtral 嘗試使用格式不正確的引數呼叫工具,導致 10%的問題失敗。 如果對功能呼叫和任務規劃技能進行適當的微調,Mixtral 的得分可能會更高。

➡️ 我們強烈建議開源開發者開始針對智慧體對 Mixtral 進行微調,以超越下一個挑戰者: GPT-4!🚀

結語:

  • 雖然 GAIA 基準測試僅在一小部分問題和少數工具上進行了嘗試,但它似乎是智慧體工作流程整體模型效能的一個非常強大的指標,因為它通常涉及多個推理步驟和嚴格的邏輯。
  • 智慧體工作流程使 LLMs 能夠提升效能: 例如,在 GSM8K 上,GPT-4 的技術報告 顯示,使用 5 次 CoT 提示的情況下得分為 92%: 透過提供一個計算器,我們能夠在零次提示的情況下達到 95%。對於 Mixtral-8x7B,LLM 排行榜 報告了使用 5 次提示的情況下為 57.6%,而我們在零次提示的情況下達到了 73%。 (記住,我們僅測試了 GSM8K 的 20 個問題)

英文原文: https://hf.co/blog/open-source-llms-as-agents

作者: Aymeric Roucher, Joffrey THOMAS, Andrew Reed

譯者: Evinci

相關文章