LangChain:大模型框架的深度解析與應用探索

? ? ? ?在數字化的時代浪潮中,人工智能技術正以前所未有的速度蓬勃發展,而大模型作為其中的翹楚,以生成式對話技術逐漸成為推動行業乃至整個社會進步的核心力量。再往近一點來說,在公司,不少產品都戴上了人工智能的帽子,各種高大上人工對話界面,作為一個已經工作8年的老程序員來說,一種壓力感撲面而來,這使得我不得不去接受新的東西,在學習和使用Prompt、function-call和Rag后發現了一個對AI初學者極其友好的框架——Langchain,幫助我更好更快的使用大模型。

????????在接下來的文章里,我將帶著大家來分析和感受LangChain的發展和應用。通過深入了解,我們可以更好地利用LangChain的優勢和避免它的不足之處。

LangChain總結

面向大模型的開發框架(SDK)

????????LangChain是一套被設計成易于使用的軟件工具集,專門為程序員提供了使用大型模型的能力。它的主要目的是幫助程序員減少開發工作量,并且將底層的復雜和重復性工作封裝起來。使用LangChain,你可以簡單方便地利用這些封裝好的功能來開發軟件。這個框架的初衷就是讓你能夠更加高效地開發,并且更加輕松地使用大型模型的能力。

基于軟件工程思維,要更關注接口變更

????????使用這套框架確實需要一定的代碼能力,因為這個框架的設計本質是基于軟件工程思路的,對編程基礎有一定要求。另外,大模型技術和輔助工具正處于一個初級階段,發展時間并不長,大模型誕生也就好一年多的時間。因此,在學習這些工具時,我們最好不要過于專注于每個接口的具體用法,例如像前端框架vue對于這個功能怎么實現,這類工具不能這么學,因為大模型技術目前還處于初級階段,未來仍會有很多變化。我們更應該關注這些框架的設計思路和模塊結構,因為它們的模塊大部分可能不會改變,只是接口可能會有一些細微的調整。更應該關注它的設計思路在你的實際工作中能否得到參考,通過這些思考我到底是直接拿它來用,還是參考它來設計,還是完全做一個更新的設計,這些都會在實際開發中大有裨益。

?AGI 時代軟件工程的一個探索和原型,迭代速度快

????????LangChain的迭代速度明顯快于Semantic Kernel,幾乎每天都有一個新版本發布。LangChain的發展是一個學習和探索的過程,在早期存在許多不成熟的接口,以及一些設計過于復雜的函數或流程。但是通過這么多次的迭代,幾乎所有的問題都得到了修復,可以說它的成熟度是與日俱增的,目前來看,LangChain已經具備了一定的可用性的。一些模塊在設計上非常成熟,具備拿來就用的,甚至在生產機使用時沒問題的,而有些模塊設計的還是很粗糙,例如第三方功能實現的一些模塊,不建議使用的。還有一些模塊在設計上沒有問題,但在實際工作中可能并不是必需的,完全取決于你的需求。接下來我將帶著大家來分析和感受。

與其他開發框架的對比

數據來源:GitHub Star History

????????Github的平行樹的對比,LangChain的歡迎程度明顯還是遙遙領先的,之所以會形成這個情況,是因為LangChain最早期設計是比較簡單易懂,不像Semantic-kernel是有一套宏大的理念導致整個抽象程度太高,導致它的可讀性或感受上很晦澀。所以Langchain比較方便大家知道怎么用,拿來就知道好不好用,都能很直接的評估出來。

LangChain 的核心組件

模型 I/O 封裝

  • LLMs:大語言模型,因為它對模型、檢索都做了統一的封裝,調用llama或其他大模型實現本地的Rag會更加簡單。
  • Chat Models:一般基于 LLMs,但按對話結構重新封裝,
  • PromptTemple:提示詞模板,對提示詞模板的操作給以了封裝。
  • OutputParser:解析輸出,模型的輸出結果,給了不同的解析工具,這個是Semantic-kernel所沒有的,也是它方便使用的功能之一。

數據連接封裝

  • Document Loaders:如何加載各種格式文檔,集結了各種格式文件的加載器。
  • Document Transformers:封裝了對文檔的常用操作工具,如:split, filter, translate, extract metadata, etc
  • Text Embedding Models:對不同的embedding模型做了統一的封裝,不管你底層是什么,基本都是統一的接口都可以去使用。然后對各種各樣的三方的向量數據庫做了封裝,也就是說你不用太關心,背后向量數據庫到底是啥,通過Langchain的統一的接口去調用。文本向量化表示,用于檢索等操作。
  • Verctorstores: (面向檢索的)向量的存儲,就是將向量數據庫的封裝后轉成一個檢索器
  • Retrievers: 向量的檢索,一個用于檢索的工具。

記憶封裝

  • Memory:這里不是物理內存,從文本的角度,可以理解為“上文”、“歷史記錄”或者說“記憶力”的管理。對上下文的管理做了一層封裝或賦予了一組工具。

架構封裝

????????最核心的是在架構上做了一層封裝,包括了調用一系列組合的pipeline。

  • Chain:實現一個功能或者一系列順序功能組合,pipeline順序調用。
  • Agent:智能體架構的封裝,根據用戶輸入,自動規劃執行步驟,自動選擇每步需要的工具,最終完成用戶指定的功能
    • Tools:調用外部功能的函數,例如:調 google 搜索、文件 I/O、Linux Shell 等等
    • Toolkits:操作某軟件的一組工具集,例如:操作 DB、操作 Gmail 等等

Callbacks

??????他每個模塊內部到底發生了什么,它都給了你一些Callback事件。具體可參考官網,里面有更為詳細的講解。

? ? ? ? 可參考官網:Callbacks | 🦜?🔗 LangChain

主要用途

解決Chain的問題

? ? ? ? 以一個Pipline (一種既定流程去調用不同組件) 的維度去看。核心解決的是一個查詢(Query)進來后,可以將問題填充到提示詞(Prompt)模板中去,然后通過Prompt去調用大語言模型(LLM)輸出的模型結果,其結果(Json / List / Text / Code ...)可以通過Output Parser進行解析提取核心數據放到下個輸入環節中,以填充新的Prompt模板,如此反復,不斷提煉輸出內容。

? ? ? ? 在前面套流程之上還賦予了上下文管理(Memory)能力和連接外部數據(Retriever)能力及工具。連接外部數據最典型的方式就是以向量數據進行向量檢索。核心利用了這幾大模塊,解決了和大模型打交道常見的功能,然后將這些功能做了統一的封裝。做了統一封裝的好處就是語言模型我可以換不同的模型的同時還不用該接口,整個代碼不用變我就把這個大預言模型就給換了。

構成智能體(Agent)

????????智能體就是經過自己反復思考,選擇不同的工具,通過多步(調用工具 -> 拿到工具結果 ->分析結果 -> 選擇工具)處理一個復雜任務,這樣一個流程作為大模型誕生后的一個新的模式。而里面一個反復思考都是在調用大模型(LLM),這個調用流程其實就是用上面的Chain來進行封裝組成的,而LangChain也對智能體架構也做了一個標準化的封裝。

相關文檔(以 Python 版為例)

? ? ? ? 官方文檔還是比較清晰的,Docs是LangChain自己提供的核心組件所有得文檔和例子;Integrations是所有跟三方的服務和組件的連接,比如你要連接各種各種的語言模型Llama,或不同的向量數據等都在這里面可以找到;Use cases則是Langchain封裝好的流程和功能,例如怎么實現Rag、怎么實現Sql查數據庫、怎么實現checkout和怎么實現摘要這類的例子;更深一點比如說怎么做debugging、調試部署、評估這類相關的文檔里沒有的技巧和方法都在Guides里邊。

主要幾大核心文檔

  • 功能模塊:主要模塊有Model I/O、Retrieval、Agents、Chains、Memory、Callbacks這類

?直通車:https://python.langchain.com/docs/get_started/introduction

  • API 文檔:針對以上更細的內容,如每個函數、每個類,參數、響應的接口文檔描述。

直通車:https://api.python.langchain.com/en/latest/langchain_api_reference.html

  • 三方組件集成:提供程序具有獨立的langchain-{provider}包,用于改進版本控制、依賴關系管理和測試。

直通車:https://python.langchain.com/docs/integrations/platforms/

  • 官方應用案例:包含常見對接技術和例子

直通車:https://python.langchain.com/docs/use_cases

  • 調試部署等指導:https://python.langchain.com/docs/guides/debugging

小試牛刀

安裝最新LangChain依賴

pip install --upgrade langchain
pip install --upgrade langchain-openai # v0.1.0新增的底包
pip install qianfan #安裝文言千帆模型Api

OpenAI?vs Langchain

????????接下來會用以下這兩個例子對比Langchain的優勢。

多輪對話實現

OpenAI

? ? ? ? 原生的Openai通過一個json數組,每一輪都一個任務一個content來去表示一個對話上下文。


# 加載 .env 文件到環境變量
from dotenv import load_dotenv, find_dotenv
from openai import OpenAI_ = load_dotenv(find_dotenv())# 初始化 OpenAI 服務。會自動從環境變量加載 OPENAI_API_KEY 和 OPENAI_BASE_URL
client = OpenAI()# 消息格式
messages = [{"role": "system","content": "你是AI助手小京。"},{"role": "human","content": "我是Csdn的一名博主,我叫Muller"},{"role": "assistant","content": "歡迎!"},{"role": "user","content": "我是誰?"},]# 調用 GPT-3.5
chat_completion = client.chat.completions.create(model="gpt-3.5-turbo",messages=messages
)# 輸出回復
print(chat_completion.choices[0].message.content)
# 您自己告訴我您是CSDN的博主Muller。
Langchian

? ? ? ? 那么在langchain的框架下,可以通過它定義的結構來去表示一個對話。然后呢我們還是把這個對話通過invoke接口來傳給大模型。

# 加載 .env 到環境變量
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())from langchain_openai import ChatOpenAIllm = ChatOpenAI()  # 默認是gpt-3.5-turbofrom langchain.schema import (AIMessage, #等價于OpenAI接口中的assistant roleHumanMessage, #等價于OpenAI接口中的user roleSystemMessage #等價于OpenAI接口中的system role
)
messages = [SystemMessage(content="從現在開始你叫AI助手-小京。"),HumanMessage(content="我是Csdn的一名博主,我叫Muller"),AIMessage(content="歡迎!"),HumanMessage(content="我是誰")
]
response = llm.invoke(messages)
print(response.content)#你是Muller,一名CSDN的博主。

Langchains實現會更加的簡潔,且可以輕松實現一個Pipline。

國產模型調用

OpenAi
import json
import requests
import os# 通過鑒權接口獲取 access token
def get_access_token():"""使用 AK,SK 生成鑒權簽名(Access Token):return: access_token,或是None(如果錯誤)"""url = "https://aip.baidubce.com/oauth/2.0/token"params = {"grant_type": "client_credentials","client_id": "ERNIE_CLIENT_ID","client_secret": "ERNIE_CLIENT_SECRET"}return str(requests.post(url, params=params).json().get("access_token"))# 調用文心4.0對話接口
def get_completion_ernie(prompt):url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro?access_token=" + get_access_token()payload = json.dumps({"messages": [{"role": "user","content": prompt}]})headers = {'Content-Type': 'application/json'}response = requests.request("POST", url, headers=headers, data=payload).json()return response["result"]class RAG_Bot:def __init__(self,  llm_api, n_results=2):self.llm_api = llm_apiself.n_results = n_resultsdef chat(self, user_query):# 3. 調用 LLMresponse = self.llm_api(user_query)return response# 創建一個RAG機器人
new_bot = RAG_Bot(llm_api=get_completion_ernie
)user_query = "你是誰?"response = new_bot.chat(user_query)print(response)
Langchain
# 其它模型分裝在 langchain_community 底包中
from langchain_community.chat_models import QianfanChatEndpoint
from langchain_core.messages import HumanMessage
import osllm = QianfanChatEndpoint(qianfan_ak=os.getenv('ERNIE_CLIENT_ID'),qianfan_sk=os.getenv('ERNIE_CLIENT_SECRET')
)messages = [HumanMessage(content="你是誰")
]ret = llm.invoke(messages)print(ret.content)

通過模型封裝,實現不同模型的統一接口調用

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/10681.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/10681.shtml
英文地址,請注明出處:http://en.pswp.cn/web/10681.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

初識C語言——第十八天

循環while/do while while 語法結構 while(表達式) 循環語句; break:在while循環中,break用于永久的終止循環 continue:在while循環中,continue的作用是跳過本次循環continue后面的代碼 直接去判斷部分,看是否進行下一次循環。 注意事項…

Logstash詳解

Logstash詳解:構建強大日志收集與處理管道的利器 一、引言 在大數據和云計算的時代,日志數據作為企業運營和故障排查的重要依據,其收集、處理和分析能力顯得尤為重要。Logstash,作為一款強大的日志收集、處理和轉發工具&#xf…

[AI OpenAI-doc] 安全最佳實踐

使用我們的免費 Moderation API OpenAI 的 Moderation API 是免費使用的,可以幫助減少您完成中不安全內容的頻率。或者,您可能希望開發自己的內容過濾系統,以適應您的使用情況。 對抗性測試 我們建議對您的應用進行“紅隊測試”&#xff0…

即插即用篇 | YOLOv8引入軸向注意力 Axial Attention | 多維變換器中的軸向注意力

本改進已集成到 YOLOv8-Magic 框架。 我們提出了Axial Transformers,這是一個基于自注意力的自回歸模型,用于圖像和其他組織為高維張量的數據。現有的自回歸模型要么因高維數據的計算資源需求過大而受到限制,要么為了減少資源需求而在分布表達性或實現的便捷性上做出妥協。相…

解決wangEditor使用keep-alive緩存后,調用editor.cmd.do()失敗

前提:wangeditor版本:4.7.11 vue版本:vue2 問題:在使用wangeditor富文本編輯器時,需求需要通過點擊一個按鈕,手動插入定義好的內容,所以使用了 editor.cmd.do(insertHTML, ....) 方法新增…

青少年軟件編程(Python)等級考試試卷(二級)2024年3月

2024.03電子學會青少年軟件編程 Python二級 等級考試試卷 一、單選題 1.期末考試結束了,全班的語文成績都儲存在列表score 中,班主任老師請小明找到全班最高分,小明準備用Python 來完成,以下哪個選項,可以獲取最高分…

較難題 鏈表的回文結構

本題來自鏈表的回文結構_牛客題霸_牛客網 (nowcoder.com) 234. 回文鏈表 - 力扣(LeetCode) 題面: 對于一個鏈表,請設計一個時間復雜度為O(n),額外空間復雜度為O(1)的算法,判斷其是否為回文結構。 給定一個鏈表的頭…

03.Linux文件操作

1.操作系統與Linux io框架 1.1 io與操作系統 1.1.1 io概念 io 描述的是硬件設備之間的數據交互,分為輸? (input) 與輸出 (output)。 輸?:應?程序從其他設備獲取數據 (read) 暫存到內存設備中;輸出:應?程序將內存暫存的數據…

FANUC機器人基本保養概述

對于工業機器人來說,定期保養機器人可以延長機器人的使用壽命。對于FANUC機器人來說,FANUC機器人的常規保養周期可以分為日常、三個月、六個月、一年、兩年、三年。以下是FANUC機器人的基本保養周期概覽: 在實際生產應用中,可以參…

具身智能論文

目錄 1. PoSE: Suppressing Perceptual Noise in Embodied Agents for Enhanced Semantic Navigation2. Embodied Intelligence: Bionic Robot Controller Integrating Environment Perception, Autonomous Planning, and Motion Control3. Can an Embodied Agent Find Your “…

7.STL_string(詳細)

1. 什么是STL STL(standard template libaray-標準模板庫):是C標準庫的重要組成部分,不僅是一個可復用的組件庫,而且 是一個包羅數據結構與算法的軟件框架。 2. STL的版本 原始版本 Alexander Stepanov、Meng Lee 在惠普實驗室完成的原始版…

maven遠程倉庫訪問順序

首先需要了解一下各個配置文件,主要分為三類: 全局配置文件(${maven.home}/conf/settings.xml),maven安裝路徑下的/conf/settings.xml用戶配置文件(%USER_HOME%/.m2/settings.xml),windows用戶文件夾下項目配置文件:p…

C/C++ 入門(10)list類(STL)

個人主頁:仍有未知等待探索-CSDN博客 專題分欄:C 歡迎來指教! 目錄 一、標準庫中的list 1、了解 2、常用接口說明 a.常見的構造函數 b.迭代器 c. Capacity?編輯 d.Element access e.Modifiers 二、實現 1、框架 a.節點 b.迭代器 …

簡單易懂的Java Queue入門教程!

哈嘍,各位小伙伴們,你們好呀,我是喵手。運營社區:C站/掘金/騰訊云;歡迎大家常來逛逛 今天我要給大家分享一些自己日常學習到的一些知識點,并以文字的形式跟大家一起交流,互相學習,一…

如何建設智慧黨校

隨著信息技術的飛速展開,特別是近年移動互聯網技術,物聯網技術,人工智能技術,大數據數據的深入展開,我國快速的進入信息化社會,信息化對各行各業的改造越來越深入,任何職業,任何安排…

SSM【Spring SpringMVC Mybatis】—— Spring(一)

目錄 1、初識Spring 1.1 Spring簡介 1.2 搭建Spring框架步驟 1.3 Spring特性 1.5 bean標簽詳解 2、SpringIOC底層實現 2.1 BeanFactory與ApplicationContexet 2.2 圖解IOC類的結構 3、Spring依賴注入數值問題【重點】 3.1 字面量數值 3.2 CDATA區 3.3 外部已聲明be…

淺談ArrayList和LinkedList的區別

ArrayList和LinkedList在Java中都是常用的List接口的實現類,但它們之間存在一些顯著的區別。 實現方式: ArrayList:基于數組實現。內部使用一個動態數組來存儲元素,這意味著可以通過索引快速訪問元素,時間復雜度為O(1)…

算法學習筆記(Nim游戲)

N i m Nim Nim游戲 n n n堆物品,每堆有 a i a_i ai?個,每個玩家輪流取走任意一堆的任意個物品,但不能不取,取走最后一個物品的人獲勝。 N i m Nim Nim游戲是一種經典的公平組合游戲。現在對它進行分析。 首先定義兩個博弈中的狀…

【Chisel】chisel中怎么處理類似verilog的可變位寬和parameter

在 Chisel 中處理可變位寬和參數的方式與 Verilog 有一些不同,因為 Chisel 是建立在 Scala 語言之上的。以下是如何在 Chisel 中處理這些概念的方法: 參數化(Parameters) 在 Chisel 中,參數化是通過在模塊構造函數中定…

VUE使用餓了么的上傳組件時實現圖片預覽

創作靈感 最近在寫項目時,遇到了上傳頭像的需求,我使用的是element組件中的upload組件。但是在使用時,我需要實現預覽、手動上傳頭像等功能。然而在使用餓了么組件時,這些功能還是需要我們自己去手動實現的,在手動實現…