第二章:會話圖(LangGraph)
在第一章中,我們學習了前端用戶界面——這是聊天機器人的"面孔",我們在這里輸入問題并查看答案。
我們看到了消息如何從聊天窗口傳遞到聊天機器人的"大腦"。現在,讓我們深入探索這個"大腦"本身!
聊天機器人的大腦:解決什么問題?
想象我們向一位超級聰明的朋友提出復雜問題:“什么是LangChain?如何用它構建聊天機器人?”
人類朋友不會直接拋出第一個想到的答案。他們可能會:
理解問題
:“好的,這是關于LangChain和構建聊天機器人的”制定研究計劃
:“首先需要解釋LangChain,然后說明如何用它構建聊天機器人”執行研究
(步驟1):“查找’什么是LangChain?'相關資料”執行研究
(步驟2):“搜索’LangChain構建聊天機器人示例’”整合信息
:“已經收集所有必要信息塊”- 給出清晰
答案
:“這是LangChain的定義,以及用它構建聊天機器人的方法…”
我們的聊天機器人需要實現類似的流程!它不能僅依賴大語言模型(LLM)一次性完成所有操作。
LLM擅長生成文本,但天然不擅長管理工作流,例如規劃研究步驟、搜索數據庫以及整合不同信息塊。
chat-langchain
項目的這個模塊要解決的核心問題是:我們的聊天機器人如何管理復雜對話和任務,將其分解為步驟、做出決策,并協調不同工具來找到最佳答案?
這就是會話圖(使用強大的LangGraph庫構建)的用武之地。它是聊天機器人的"大腦"和"工作流管理器"。
什么是會話圖(LangGraph)?
LangGraph可以看作聊天機器人行為的流程圖或配方。它定義了所有可能的執行步驟,以及步驟間的轉移決策邏輯。
核心概念解析:
- 圖(Graph):在計算機科學中,"圖"是由節點(圓形)和邊(連接線)組成的結構
- 節點(步驟/動作):聊天機器人可以執行的獨立任務,例如"分析問題"、“搜索信息"或"生成最終答案”
- 邊(規則/決策):節點間的連接邏輯,例如"完成問題分析后,如果是LangChain相關的問題,則跳轉到’搜索信息’節點"
- LangGraph:專門為對話式AI構建的流程圖庫,幫助設計包含狀態記憶的復雜工作流
- 狀態(大腦記憶):當聊天機器人執行流程圖時,需要記憶:
- 用戶對話歷史
- 待解決的研究問題列表
- 已找到的文檔資料
- LangGraph負責管理這些"記憶"以實現進度跟蹤
簡而言之,LangGraph幫助我們構建能夠執行多步計劃、使用不同工具(如搜索引擎)并做出智能決策的聊天機器人,而不是僅靠猜測生成答案。
會話圖工作原理:以"智能問題"為例
以問題"什么是LangChain?如何用它構建聊天機器人?"為例,演示LangGraph的協調過程:
- 接收消息(來自前端用戶界面)
- 分析和路由查詢:
- LangGraph"大腦"接收問題
- 使用LLM分類問題類型(普通聊天/需要更多信息/LangChain相關復雜問題)
- 決策:“這是關于LangChain的復雜問題”
- 創建研究計劃:
- 判定需要分步研究
- 使用另一個LLM拆分問題:
- 步驟1:“什么是LangChain?”
- 步驟2:“如何用LangChain構建聊天機器人?”
- 執行研究(步驟1):
- 將第一個研究步驟發送給專用"研究子腦"(也是LangGraph構建的流程圖)
- 研究子腦生成搜索查詢,通過檢索過程從向量存儲(Weaviate)獲取相關文檔
- 主腦更新記憶狀態(
存儲找到的文檔
)
- 檢查完成狀態:
- 查看研究計劃剩余步驟
- 決策:“步驟2待處理”
- 執行研究(步驟2):
- 重復研究子腦的文檔檢索過程
- 主腦更新記憶狀態
- 檢查完成狀態:
- 確認所有步驟已完成
- 生成響應:
- 將所有對話歷史和檢索文檔發送給最終LLM
- 生成綜合性的最終答案
- 返回前端(通過前端用戶界面展示答案)
整個過程由會話圖
協調管理。
幕后機制:LangGraph工作流
大腦流程圖(簡化版)
大腦記憶:AgentState
LangGraph通過AgentState
類管理記憶狀態,定義見backend/retrieval_graph/state.py
:
# backend/retrieval_graph/state.py(簡化版)
@dataclass(kw_only=True)
class AgentState:messages: Annotated[list[AnyMessage], add_messages] # 全部聊天消息router: Router = field(default_factory=lambda: Router(type="general", logic="")) # 查詢類型steps: list[str] = field(default_factory=list) # 研究計劃步驟documents: Annotated[list[Document], reduce_docs] = field(default_factory=list) # 檢索到的文檔answer: str = field(default="") # 最終答案# ...其他狀態字段...
messages
記錄對話歷史,steps
存儲研究計劃,documents
保存檢索結果。
構建大腦:節點與邊
主流程圖定義在backend/retrieval_graph/graph.py
,關鍵組件:
節點1:analyze_and_route_query(決策器)
async def analyze_and_route_query(state: AgentState, *, config: RunnableConfig) -> dict[str, Router]:# 使用LLM分類問題類型model = load_chat_model(config.query_model).with_structured_output(Router)messages = [{"role": "system", "content": config.router_system_prompt}] + state.messagesresponse = cast(Router, await model.ainvoke(messages))return {"router": response} # 存儲分類結果
節點2:create_research_plan(規劃器)
async def create_research_plan(state: AgentState, *, config: RunnableConfig) -> dict[str, list[str]]:# 生成分步研究計劃model = load_chat_model(config.query_model).with_structured_output(Plan)messages = [{"role": "system", "content": config.research_plan_system_prompt}] + state.messagesresponse = cast(Plan, await model.ainvoke(messages))return {"steps": response["steps"]} # 返回步驟列表
節點3:conduct_research(研究協調器)
async def conduct_research(state: AgentState) -> dict[str, Any]:# 委托研究子腦執行單個步驟result = await researcher_graph.ainvoke({"question": state.steps[0]})return {"documents": result["documents"], "steps": state.steps[1:]} # 更新文檔和步驟
節點4:respond(應答生成器)
async def respond(state: AgentState, *, config: RunnableConfig) -> dict[str, list[BaseMessage]]:# 整合信息生成最終答案model = load_chat_model(config.response_model)context = format_docs(state.documents) # 格式化文檔prompt = config.response_system_prompt.format(context=context)messages = [{"role": "system", "content": prompt}] + state.messagesresponse = await model.ainvoke(messages)return {"messages": [response], "answer": response.content}
流程圖裝配
builder = StateGraph(AgentState, input=InputState, config_schema=AgentConfiguration)# 添加所有節點
builder.add_node("analyze_and_route_query", analyze_and_route_query)
builder.add_node("create_research_plan", create_research_plan)
builder.add_node("conduct_research", conduct_research)
builder.add_node("respond", respond)
# ...其他節點...# 定義狀態轉移邏輯
builder.add_edge(START, "analyze_and_route_query")
builder.add_conditional_edges("analyze_and_route_query",route_query,{"create_research_plan": "create_research_plan","ask_for_more_info": "ask_for_more_info","general": "respond_to_general_query"}
)
# ...更多連接邏輯...graph = builder.compile()
graph.name = "RetrievalGraph"
結論
本章探討了**會話圖(LangGraph)**作為聊天機器人的核心決策系統。
通過節點
(執行步驟)、邊
(轉移邏輯)和狀態
(記憶管理)的協同工作,實現了復雜對話任務的分解與協調。
下一章將深入解析支撐這些功能的大語言模型(LLM)。
第三章:大語言模型(LLM)
第三章:大語言模型(LLM)
在第二章中,我們了解了會話圖(LangGraph)作為聊天機器人的"大腦
",它像熟練的項目經理般協調回答問題的各個步驟
。
但誰是真正執行理解、創造性思維并生成類人文本的智能專家?這正是本章的核心:大語言模型(LLM)。
聊天機器人的專家顧問:解決什么問題?
想象我們正在構建復雜項目:項目經理(LangGraph)負責組織協調,但遇到技術文檔理解、解決方案構思或撰寫清晰報告等專業任務時,我們需要聘請專家顧問。
大語言模型(LLM)在chat-langchain
中解決的核心理念是:我們的聊天機器人如何真正理解問題,通過創造性思維分解任務,并基于復雜信息生成類人化的智能答案?
LLM是系統的"專家顧問"和"對話專家",負責:
- 重述用戶問題(
查詢分析
):用戶可能基于上下文提出簡短追問,LLM能將其轉化為完整清晰的獨立問題 生成研究計劃
:針對復雜問題,LLM可像人類專家般拆解為分步研究計劃構建最終答案
:整合檢索過程獲取的信息后,LLM將其轉化為清晰易讀的答案
什么是大語言模型(LLM)?
大語言模型(LLM)本質上是基于海量互聯網文本數據(書籍/文章/網頁等)訓練的強大人工智能,可視為:
- 超級智能文本生成器:能撰寫文章/詩歌/代碼/摘要等類人化文本
- 卓越理解者:理解文本含義,識別詞語關系,掌握復雜語境
- 對話大師:憑借文本理解和生成能力,實現類人對話和問答
在chat-langchain
中,LLM賦予聊天機器人"智能"——實現文本解析、規劃和創造的能力。
LLM在chat-langchain
中的應用
1. 重述用戶問題(查詢分析)
當用戶提出"聊天機器人場景下如何應用?"等簡短追問時,LLM會結合:
- 完整對話歷史
- 當前簡短提問
生成獨立清晰的問題:“LangChain如何用于構建聊天機器人?”(參見CONCEPTS.md
中的REPHRASE_TEMPLATE
提示模板)
2. 生成研究計劃
面對"解釋LangChain代理及其工具使用機制"等復雜問題,會話圖(LangGraph)會請求LLM生成分步計劃,例如:
- “什么是LangChain代理?”
- “LangChain代理如何使用工具?”
3. 構建最終答案
當會話圖(LangGraph)通過檢索過程收集足夠信息后,LLM會:
- 整合對話歷史
- 融合檢索文檔
- 生成連貫答案(參見
MODIFY.md
中的RESPONSE_TEMPLATE
模板)
實現細節:LLM工作機制
工作流中的LLM(簡化版)
(LangGraph分解問題,列清單,LLM才是真正執行解答)
1. LLM選擇與加載
chat-langchain
支持多種LLM服務商(OpenAI/Anthropic/Google等),配置見backend/retrieval_graph/configuration.py
:
@dataclass(kw_only=True)
class AgentConfiguration(BaseConfiguration):# 查詢分析和計劃制定的LLMquery_model: str = field(default="anthropic/claude-3-5-haiku-20241022",metadata={"description": "用于查詢處理的語言模型"})# 最終答案生成的LLMresponse_model: str = field(default="anthropic/claude-3-5-haiku-20241022",metadata={"description": "用于生成響應的語言模型"})# 系統提示模板router_system_prompt: str = field(default=prompts.ROUTER_SYSTEM_PROMPT, ...)research_plan_system_prompt: str = field(default=prompts.RESEARCH_PLAN_SYSTEM_PROMPT, ...)response_system_prompt: str = field(default=prompts.RESPONSE_SYSTEM_PROMPT, ...)
通過backend/utils.py
的load_chat_model
函數加載模型:
def load_chat_model(fully_specified_name: str) -> BaseChatModel:"""根據模型名稱加載LLM(如'openai/gpt-4o-mini')"""if "/" in fully_specified_name:服務商, 模型 = fully_specified_name.split("/", maxsplit=1)else:服務商 = ""模型 = fully_specified_namereturn init_chat_model(模型, model_provider=服務商, temperature=0) # 溫度參數控制創造性
2. 核心功能實現
查詢分析(路由決策)
async def analyze_and_route_query(state: AgentState, config: RunnableConfig) -> dict[str, Router]:配置 = AgentConfiguration.from_runnable_config(config)模型 = load_chat_model(配置.query_model).with_structured_output(Router)消息 = [{"role": "system", "content": 配置.router_system_prompt}] + state.messages響應 = cast(Router, await 模型.ainvoke(消息))return {"router": 響應} # 存儲分類結果
研究計劃生成
async def create_research_plan(state: AgentState, config: RunnableConfig) -> dict[str, list[str]]:class 計劃(TypedDict):steps: list[str]模型 = load_chat_model(配置.query_model).with_structured_output(計劃)消息 = [{"role": "system", "content": 配置.research_plan_system_prompt}] + state.messages響應 = cast(計劃, await 模型.ainvoke(消息))return {"steps": 響應["steps"]}
最終答案生成
async def respond(state: AgentState, config: RunnableConfig) -> dict[str, list[BaseMessage]]:模型 = load_chat_model(配置.response_model)上下文 = format_docs(state.documents[:20]) # 取前20個相關文檔提示 = 配置.response_system_prompt.format(context=上下文)消息 = [{"role": "system", "content": 提示}] + state.messages響應 = await 模型.ainvoke(消息)return {"messages": [響應], "answer": 響應.content}
結論
本章深入解析了大語言模型(LLM)作為chat-langchain
系統的智能核心。LLM在查詢理解、研究規劃和答案生成中發揮關鍵作用,而會話圖(LangGraph)則負責整體協調。下一章將探討支撐LLM工作的檢索過程。
第四章:檢索過程