鏈接:https://python.langchain.com/docs/tutorials/qa_chat_history/
Chat-LangChain技術棧 :
- LangChain
- LangGraph
- Next.js
- Weaviate (向量存儲)
- OpenAI (嵌入模型)
docs:chat-langchain
Chat LangChain 是一個智能聊天機器人,專為解答LangChain技術文檔相關問題設計。
它如同智能研究助手,首先將海量信息整合為可搜索知識庫,隨后通過AI核心處理模塊(LangGraph
)理解用戶問題、檢索
相關細節并生成
清晰專業的解答*。
該系統還集成可觀測性工具實現持續優化。
架構
章節導航
- 前端用戶界面
- 會話圖譜(LangGraph)
- 大語言模型(LLM)
- 檢索流程
- 向量存儲(Weaviate)
- 文檔攝取
- 記錄管理器
- LangSmith集成
第一章:前端用戶界面
想象我們正在與一臺超級智能機器人對話!
正如我們看到機器人的"面部"并聽到其語音,聊天機器人也需要一個交互界面。這個"面部"或交互屏幕就是我們所說的前端用戶界面。
chat-langchain
項目這部分解決的問題很簡單:如何讓人輕松與聊天機器人交流并理解其行為邏輯?
本章的目標是理解用戶如何通過可視化界面與聊天機器人互動——從輸入問題到獲取答案,甚至觀察機器人的"思考過程"。
何為前端用戶界面?
前端用戶界面(常簡稱為"前端"或"UI")可視為屏幕上的控制面板或聊天窗口,是用戶直接交互的可視化部分。其核心功能包括:
- 聊天輸入框:用戶在此輸入問題或消息,如同與機器人對話的"嘴巴"
- 對話歷史記錄:展示完整的聊天記錄,形成對話"文字實錄"
- AI響應區:顯示機器人的回答內容
- 內部思考可視化:有時會展示后臺處理過程,例如:
- 進度狀態:顯示"思考中"、“檢索中”、"響應中"等狀態提示
- 文檔引用:當使用外部信息時顯示參考文檔來源
讓我們通過chat-langchain
的交互流程來具體理解。
首次交互指南
使用chat-langchain
應用的典型流程:
- 啟動應用:訪問網站或打開應用程序
- 輸入問題:在底部輸入框鍵入內容,例如:“什么是LangChain?”
- 發送消息:點擊回車鍵或發送按鈕
- 獲取響應:界面顯示處理進度,最終呈現機器人的完整回答
這種流暢的交互體驗完全依賴于前端用戶界面的有效運作!
幕后流程:消息傳遞機制
當我們輸入"Hello!"并發送時,后臺將觸發以下處理流程:
- 用戶觸發:在輸入框完成內容輸入
- 前端封裝:界面代碼識別操作并進行消息封裝
- 核心處理:通過會話圖譜(LangGraph)進行智能解析(下一章詳述)
- 流式響應:后端通過API代理返回處理結果片段
- 實時渲染:前端逐步更新界面顯示內容
現在讓我們解析支撐這些功能的代碼結構。
應用入口文件(frontend/app/page.tsx
)
該文件作為應用的主入口,負責初始化聊天環境:
// frontend/app/page.tsx
"use client";import React from "react";
import { GraphProvider } from "./contexts/GraphContext";
import { ChatLangChain } from "./components/ChatLangChain";export default function Page(): React.ReactElement {return (<main className="w-full h-full"><React.Suspense fallback={null}>{/* GraphProvider注入核心數據處理邏輯 */}<GraphProvider>{/* ChatLangChain承載可視化聊天界面 */}<ChatLangChain /></GraphProvider></React.Suspense></main>);
}
其中GraphProvider
作為數據引擎管理聊天邏輯,ChatLangChain
作為可視化組件呈現交互界面,二者協同工作。
核心交互組件(frontend/app/components/ChatLangChain.tsx
)
該組件實現消息收發與呈現的核心邏輯:
// frontend/app/components/ChatLangChain.tsx
"use client";import React, { useState } from "react";
import { AppendMessage, AssistantRuntimeProvider } from "@assistant-ui/react";
import { HumanMessage } from "@langchain/core/messages";
import { useGraphContext } from "../contexts/GraphContext";
import { ThreadChat } from "./chat-interface";function ChatLangChainComponent(): React.ReactElement {const { graphData } = useGraphContext(); // 獲取數據上下文const { messages, setMessages, streamMessage } = graphData;const [threadId, setThreadId] = useState<string | null>(null); // 會話線程管理async function onNew(message: AppendMessage): Promise<void> {// 用戶消息處理const humanMessage = new HumanMessage({ content: message.content[0].text });setMessages((prevMessages) => [...prevMessages, humanMessage]); // 更新消息列表await streamMessage(threadId!, { messages: [humanMessage] }); // 觸發消息處理流}const runtime = { messages, onNew, isRunning: false }; // 運行時配置return (<div><AssistantRuntimeProvider runtime={runtime}>{/* 渲染聊天窗口組件 */}<ThreadChat submitDisabled={false} messages={messages} /></AssistantRuntimeProvider></div>);
}export const ChatLangChain = React.memo(ChatLangChainComponent);
onNew
函數作為消息處理中樞:
- 將用戶輸入轉換為標準消息格式
- 實時更新界面消息列表
- 調用流式消息處理接口
會話流管理(frontend/app/contexts/GraphContext.tsx
)
該上下文管理完整的會話生命周期:
// frontend/app/contexts/GraphContext.tsx
import { createContext, useContext, useState } from "react";
import { AIMessage, BaseMessage, HumanMessage } from "@langchain/core/messages";
import { createClient } from "./utils"; // 服務端連接工具// ... 接口定義及其他依賴 ...export function GraphProvider({ children }: { children: React.ReactNode }) {const [messages, setMessages] = useState<BaseMessage[]>([]);const [isStreaming, setIsStreaming] = useState(false); // 流式狀態標識const streamMessage = async (currentThreadId: string,params: { messages?: Record<string, any>[] },): Promise<void> => {const client = createClient(); // 建立服務連接// 初始化流式會話const stream = client.runs.stream(currentThreadId, "chat", {input: params, // 輸入參數streamMode: "events", // 事件流模式});setIsStreaming(true); // 激活處理狀態try {for await (const chunk of stream) {// 處理響應數據塊if (chunk.data.event === "on_chat_model_stream") {const message = chunk.data.data.chunk;setMessages((prevMessages) => {// 動態更新消息內容const existingIndex = prevMessages.findIndex(msg => msg.id === message.id);if (existingIndex !== -1) {// 增量更新現有消息return [...prevMessages.slice(0, existingIndex),new AIMessage({ ...prevMessages[existingIndex], content: prevMessages[existingIndex].content + message.content }),...prevMessages.slice(existingIndex + 1)];} else {// 新增AI消息return [...prevMessages, new AIMessage({ ...message })];}});}// ... 其他事件處理 ...}} finally {setIsStreaming(false); // 終止處理狀態}};// ... 上下文值傳遞 ...
}
streamMessage
函數通過事件流機制實現:
- 建立與LangGraph服務的持久化連接
- 動態處理響應數據塊
- 實時更新界面渲染狀態
界面渲染引擎(frontend/app/components/chat-interface/index.tsx
)
該組件實現可視化布局:
// frontend/app/components/chat-interface/index.tsx
"use client";import { ThreadPrimitive } from "@assistant-ui/react";
import { type FC } from "react";
import { AssistantMessage, UserMessage } from "./messages"; // 消息組件
import { ChatComposer } from "./chat-composer"; // 輸入組件export interface ThreadChatProps extends ChatComposerProps {}export const ThreadChat: FC<ThreadChatProps> = (props: ThreadChatProps) => {const isEmpty = props.messages.length === 0;// 可視化增強鉤子// useProgressToolUI(); // 進度指示// useSelectedDocumentsUI(); // 文檔引用展示// useRouterLogicUI(); // 路由邏輯return (<ThreadPrimitive.Root className="flex flex-col h-screen overflow-hidden w-full">{!isEmpty ? (<ThreadPrimitive.Viewport className="flex-1 overflow-y-auto w-full">{/* 消息列表容器 */}<ThreadPrimitive.Messagescomponents={{UserMessage: UserMessage, // 用戶消息樣式AssistantMessage: AssistantMessage, // AI消息樣式}}/></ThreadPrimitive.Viewport>) : null}{/* 輸入框組件 */}<ChatComposer submitDisabled={props.submitDisabled} messages={props.messages} /></ThreadPrimitive.Root>);
};
組件架構包含:
- 響應式滾動容器
- 動態消息列表渲染
- 可擴展的可視化增強模塊
消息呈現組件(frontend/app/components/chat-interface/messages.tsx
)
定義具體消息樣式:
// frontend/app/components/chat-interface/messages.tsx
"use client";import { MessagePrimitive, useMessage } from "@assistant-ui/react";
import { type FC } from "react";
import { MarkdownText } from "../ui/assistant-ui/markdown-text"; // Markdown渲染export const UserMessage: FC = () => {// 用戶消息模板return (<MessagePrimitive.Root className="your-message-styling"><div className="bg-inherit text-white break-words"><MessagePrimitive.Content /></div></MessagePrimitive.Root>);
};export const AssistantMessage: FC = () => {// AI消息模板const isLast = useMessage((m) => m.isLast); // 末條消息標識return (<MessagePrimitive.Root className="ai-message-styling"><div className="bg-inherit text-white max-w-full break-words"><MessagePrimitive.Content components={{ Text: MarkdownText }} />{isLast && (// <FeedbackButtons /> // 反饋功能組件null)}</div></MessagePrimitive.Root>);
};
功能特性:
- 支持
Markdown語法
渲染 - 消息內容自適應布局
- 擴展反饋功能接口
API代理服務(frontend/app/api/[..._path]/route.ts
)
實現安全通信中轉:
// frontend/app/api/[..._path]/route.ts
import { NextRequest, NextResponse } from "next/server";export const runtime = "edge"; // 邊緣計算優化async function handleRequest(req: NextRequest, method: string) {try {const path = req.nextUrl.pathname.replace(/^\/?api\//, ""); // 路徑解析const url = new URL(req.url);const options: RequestInit = {method,headers: {"x-api-key": process.env.LANGCHAIN_API_KEY || "", // 認證密鑰},};if (["POST", "PUT", "PATCH"].includes(method)) {options.body = await req.text(); // 請求體處理}// 請求轉發至核心服務const res = await fetch(`${process.env.API_BASE_URL}/${path}`, options);// 響應回傳return new NextResponse(res.body, { status: res.status, headers: res.headers });} catch (e: any) {return NextResponse.json({ error: e.message }, { status: e.status ?? 500 });}
}// HTTP方法代理
export const GET = (req: NextRequest) => handleRequest(req, "GET");
export const POST = (req: NextRequest) => handleRequest(req, "POST");
// ... 其他方法代理 ...
代理層功能:
- 請求路徑重定向
- 安全認證處理
- 異常狀態攔截
- 協議方法適配
總結
-
Chat-LangChain是一個基于LangChain技術棧的智能聊天機器人,專為解答LangChain文檔問題設計。
-
它采用
Next.js
構建前端交互界面,通過Weaviate向量存儲
和OpenAI嵌入模型
實現高效檢索,并利用LangGraph進行核心對話處理。 -
系統架構包含用戶界面、對話圖譜、大語言模型、檢索流程等模塊,支持流式響應和思考過程可視化。
-
前端代碼通過React組件管理消息傳遞和會話狀態,后端則負責語義理解和知識檢索,形成完整的問答系統。項目還集成了
LangSmith等工具進行性能監控
和優化。
本章深入解析了chat-langchain
的前端用戶界面,揭示其如何通過可視化組件實現人機交互。
我們追蹤了從用戶輸入到響應呈現的完整流程,剖析了核心代碼模塊的協作關系。盡管前端承擔著界面呈現的重要角色,真正的智能處理依賴于會話圖譜(LangGraph)這一"大腦",這將是下一章的重點解析對象。