大模型上層工具鏈調研 - langchain, llama-index

langchain 基于 0.0.109 版本

一個基于LLMs的應用程序開發框架, 通過可組合性來使用LLM構建應用程序. 其重點在于"可組合性"

大型語言模型 (LLM) 正在作為一種變革性技術出現,使開發人員能夠構建他們以前無法構建的應用程序。但是單獨使用這些 LLM 通常不足以創建真正強大的應用程序,當可以將它們與其他計算或知識來源相結合時,就有真的價值了。LangChain 旨在協助開發這些類型的應用程序.

其主要包含六個部分:

  1. LLMs和prompt, 對所有大模型的通用交互接口, 以及prompt管理,優化等等
  2. chains, 一系列的調用(LLMs或者其他, 如網絡, 操作系統), chains提供了標準的接口和設置來組合這些調用.
  3. data augmented generation 基于特定數據的內容生成, 一種特殊的chain, 提供了一種能力: 先從外部的源獲取信息, 然后喂給LLMs
  4. agents, 代理, 非常重要的一環, 關于對LLMs做何種action, 如何做
  5. memory 標準的接口, 在chains/call之間保存狀態
  6. Evaluation 提供了一些prompts/chains來利用模型來評估自身

prompt templates

ChatGPT 提供了通過 prompts 來進行提示的方法,也就是在發起請求時,可以帶上一段信息。由于是一個聊天接口,因此可以包含多個聊天的內容。其中包括來自系統的提示:例如用來描述一下 ChatGPT 現在是什么角色,應該具有什么樣的語言風格等。另外還可以包含一些用戶的歷史聊天記錄,就像背景知識一類的,都可以作為用戶的輸入帶進去,這樣可以使得 ChatGPT 在本次聊天中具有了領域知識與上下文信息。通過這種 prompts 的方式,可以對 ChatGPT 有一定的定制能力,并使用其大模型的自然語言能力來組織回答信息。

prompt template是簡化和用戶的交互, 用戶提出核心問題, template 渲染問題, 增加上下文信息, 歷史聊天信息, 背景知識等等.

chains

簡單應用可能對LLM進行一次調用即可, 而復雜應用往往需要串聯LLMs(相互連接或者和其他的專家系統). langchain為此提供了一套標準的接口和通用的實現.

chain還細分為兩類: 通用任務chain 和 專有工具chain ,前者更多用來組織任務順序, 后者則專注在對某個工具的調用上.

  • LLMChain: 簡單接受template和用戶輸入, 調用LLM, 返回輸出
  • SequentialChain: 組合chains, 發起一系列且有順序的調用請求
    SimpleSequentialChain(chains=[chain, chain_two], verbose=True)
  • BashChain: 使用LLMs 以及 調用bash命令
  • LLMRequestsChain: 發起調用, 之后將結果輸送給后來的chain.
  • .........
  • 自定義chain:
    • 繼承Chain
    • 實現input_keys和output_keys (前者接收先前chains的輸出, 后者給到后來chains作為輸入)
    • 補全調用實現_call ( _call是chain運行會調用的方法)

chain可以很簡單地理解為 過程的抽象, chains的可組合性, 就是過程的組合.

agents

use LLM to determine which actions to take and in what order. An action can either be using a tool and observing its output, or returning to the user.

搭配上能理解用戶輸入的大模型, agents接受大模型輸出的指令, 可以打造強大的個人助理程序.

concepts

Tool : A function that performs a specific duty. This can be things like: Google Search, Database lookup, Python REPL, other chains. The interface for a tool is currently a function that is expected to have a string as an input, with a string as an output.
工具, 可以執行某種特定任務. 當下, 可以理解為一個 string => string的函數. 內置的工具:
https://langchain.readthedocs.io/en/latest/modules/agents/tools.html
可以: 發起調用, http請求, 搜索內容, 執行代碼(python), etc.

LLM : The language model powering the agent.

Agent : The agent to use. This should be a string that references a support agent class. Because this notebook focuses on the simplest, highest level API, this only covers using the standard supported agents. If you want to implement a custom agent, see the documentation for custom agents (coming soon).
用來調用工具的代理, 如果標準庫里沒有合適的工具代理, 可以自定義.
內置代理類型:

  • zero-shot-react-description 根據工具的描述, 和請求的string 來決定使用哪個工具
  • react-docstore 使用react框架, 和docstore交互, 使用SearchLookup 工具, 前者用來搜, 后者尋找term, 舉例: Wipipedia工具
  • self-ask-with-search 此代理只使用一個工具: Intermediate Answer, 它會為問題尋找事實答案(指的非gpt生成的答案, 而是在網絡中,文本中已存在的), 如 Google search API 工具
  • conversational-react-description 為會話設置而設計的代理, 它的prompt會被設計的具有會話性, 且還是會使用 ReAct框架來決定使用來個工具, 并且將過往的會話交互存入內存.

https://langchain.readthedocs.io/en/latest/modules/agents/agents.html

舉例

與向量數據庫交互

希望應用程序, 在使用LLM的過程中, 和向量數據庫交互(其實, 不用langchain庫, 自己編寫很簡單的代碼就可以做到) 只是langchain庫在多數向量庫之上, 包裝了一層統一的交互接口.
https://langchain.readthedocs.io/en/latest/modules/agents/examples/agent_vectorstore.html

如下代碼所示 , 兩個tool被創建, 組合成工具包, 兩個工具, 分別是"SOU的qa"和 "Ruff的qa", 他們會分別閱讀SOU和Ruff網站的內容, 并且調用LLM的向量接口, 生成向量, 存于本地數據庫. 然后使用特定種類的agent作為某種路由, 可以按工具描述使用他們.

tools = [
    Tool(
        name = "State of Union QA System",
        func=state_of_union.run,
        description="useful for when you need to answer questions about the most recent state of the union address. Input should be a fully formed question."
    ),
    Tool(
        name = "Ruff QA System",
        func=ruff.run,
        description="useful for when you need to answer questions about ruff (a python linter). Input should be a fully formed question."
    ),
]

agent = initialize_agent(tools, llm, agent="zero-shot-react-description", verbose=True)
agent.run("What did biden say about ketanji brown jackson is the state of the union address?")
先搜再問 - data agumented generation

對于某些大模型沒有的信息或者知識, 如果要補充這些信息, 需要重新訓練模型, 成本比較高, 但是可以通過prompt的方式給到它, langchain為了方便上層開發應用, 設計了self-ask-with-search代理, 即先到某個知識庫去獲取相關的信息和知識, 然后利用LLM來理解這些知識和信息,然后回答用戶的問題.

memory

chain和agent是無狀態的, LLM模型也是, 所以需要prompt來進行歷史提示.
Chains and Agents are stateless, meaning that they treat each incoming query independently (as are the underlying LLMs and chat models).
memory模塊提供了兩種能力:

  1. 模塊化管理和操作先前的對話的工具
  2. 將這些工具集成到chain里的設施

示例

https://langchain.readthedocs.io/en/latest/modules/memory/types/buffer.html
從示例中可以看出, langchain將對話保存在模塊化的memory中, 并且在predict的時候, 自動帶上歷史會話, 作為prompt.

總結

關于agent和chains的差異,尤其是utils chain
agent是關于對LLM做何種action, 怎么做action, 在于挑選工具. chain重點是對輸入做處理 , 并且組織各個過程的順序.

data augemented generation

LLMs是基于大量非結構化的語料訓練的, 所以對通用的nlp任務有很好的的效果, 然而很多時候, 我們需要的不是在利用通用數據來生成結果, 而是基于特定的數據來產生結果.

  • Summarization of a specific piece of text (a website, a private document, etc.)
  • Question answering over a specific piece of text (a website, a private document, etc.)
  • Question answering over multiple pieces of text (multiple websites, multiple private documents, etc.)
  • Using the results of some external call to an API (results from a SQL query, etc.)
    即, 不希望模型僅僅通過其訓練的數據來生成文本, 而要把某些外部的數據也結合進去, 所以步驟可以拆解為兩步:
  1. fetching: 取回
  2. user provided
  3. document retrival
  4. api querying
  5. augmenting: 傳遞給LLM

fetching

在fetching過程中, 比較重要的是取回的文檔不能太大, 因為目前的模型都對輸入的長度有限制, 所以 langchain提供了各種工具來split文檔成一片一片, 并且控制每片中的內容重疊(保持上下文). 另外一個是, 不能取回太多的文檔, 最好只選取和問題相關的文檔, 即相關度要高, 有比較多的方式來做這件事, 當下比較流行的是:
在語義搜索和Q&A系統中, 將語料的doc切分成chunk, 將chunk向量化, 然后存儲, 之后用戶的輸入到來后, 首先進行向量化的相關性搜索, 將搜索的結果以及用戶數據一起作為prompt作為輸入喂給LLM, 這是目前常見的做法, 但業界也在考慮轉為大模型設計的數據結構和索引技術, 詳見 LlamaIndex

幾個開源項目:

LlamaIndex -> 專注在數據層

對于私有數據, 受限于LLM的無狀態, 訓練代價大, token個數限制, 甚至fine-tune的接口不開放等等, 對于私有數據上的內容生成, 現在常見的做法是embedding文檔, 先搜后問, 也即上文提到的langchain的一個核心模塊: data augementing generation. 與此同時, LlamaIndex在考慮為LLM設計的數據結構和索引.

現在想要增強LLM在私有數據上的表現能力, 有兩種方式: fine-tune 和 in-context learning (即將上下文放入輸入的prompt中) .
為了更好地(高效,便宜)進行data augmentation, 想要解決: 數據攝取和索引. LlamaIndex提供的工具:

  • data connectors : 連接到數據源, 和不同的數據格式
  • 利用LLM來給結構化,非結構化數據做索引. 簡化了in-context learning過程中繁瑣的細節: prompt長度, 文本拆分,etc
  • 用戶優化的索引query 接口 和 模型調用接口的結合
  • 一個權衡成本和性能的全面的工具集

不同于langchain的全面開發, 均衡發展策略, llama-index更像是專注在data augmentation generation, 圍繞它來開發周邊對應的能力. 即豐富的數據源和數據格式的讀取器, 統一的index表示, 花式的index讀取, 寫入.

smart agents -> 專注在agents

https://www.fixie.ai/

Build natural language agents that connect to your data, talk to APIs, and solve complex problems.

和Llama-index類似, 不過專注在agents, 準備構建一個agents market, 在大模型之上構建一個軟件系統, 可以和其它系統交互, 完成復雜任務.

目前資料較少

總結

GPT Index vs LangChain 的區別:

根本上是因為 大語言模型支持的context有限,比如ChatGPT的Davinci model只有 4096 tokens,對應中文,可能只有2000

“A big limitation of LLMs is context size (e.g. Davinci's limit is 4096 tokens. Large, but not infinite).”

  1. 如果單純的跟GPT模型對接,那直接用 GPT 的 Davinci 模型直接對話就行;ChatGPT 只是 GPT 其中一個 chat-model 而已

  2. 如果需要借助GPT語言模型+私有數據,那就需要突破 4096 tokens 的限制,也就是 feed "knowledge" to LLMs,所以需要用上 GPT Index

與此同時,在用 ChatGPT 時,單次輸入的 prompt 也有限制,所以 GPT Index 可以簡化這個 feed 喂數據的過程。

  1. 如果 GPT 直接就滿足要求,可以用 GPT Index,就夠了。

那為什么還有用上 LangChain 呢?就是因為 LLMs 不止 OpenAI 的 GPT 模型,LangChain 可以對接多種模型,即 Lang

而 Chain 的意思就是把多個 LLM 調用,而且是調用序列,標準化,集成等工作,最后串起來

  1. LangChain 還做了很多框架層面的工作:Prompt、Loader、Chain、Agent、Memory

比如 Loader 部分,它也推出了跟 https://llamahub.ai 類似的 https://github.com/hwchase17/langchain-hub,用來集成外部數據。區別就在于 GPT Index 能用的,LangChain 都能用,LangChain 的 Loader 能加載其他語言模型,是 GPT 的超集。

再比如 Memory 部分,就是用來持久化 內存 狀態,所以能實現 ChatGPT 聊天機器人這樣的功能,記住以前的交互非常重要,無論是短期的還是長期的。

Agent 部分就更有趣了,可以根據用戶輸入,再來決定調用這些工具中的哪一個,比如 LangChain 的 GPT+WolframAlpha 示例,甚至還可以根據輸入去調用 WolframAlpha,解答你的數學提問,彌補GPT 數學弱智的問題。

當然,它也可以去做 Google 搜索、數據庫查找 等操作,通過需要跟 Document Loader 結合起來用,你可以找到類似 https://llamahub.ai/l/file-pdf 等不少例子。

應用

  • chatpdf : 和書籍對話, 也是類似llama index的做法, 將內容embedding, 利用LLM進行提煉總結.
  • chatexcel: https://chatexcel.com/convert, 上傳excel, 利用自然語言描述需求, 自動改表, 總結內容. (私人表格助手)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,837評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,196評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,688評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,654評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,456評論 6 406
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,955評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,044評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,195評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,725評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,608評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,802評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,318評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,048評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,422評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,673評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,424評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,762評論 2 372

推薦閱讀更多精彩內容