ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

使用 LangChainGo 从零构建基础聊天应用:从单次调用到带记忆的对话链

2026/9/15 11:46:23 拓冰建站 浏览量
使用 LangChainGo 从零构建基础聊天应用:从单次调用到带记忆的对话链 使用 LangChainGo 从零构建基础聊天应用从单次调用到带记忆的对话链【免费下载链接】langchaingoLangChain for Go, the easiest way to write LLM-based programs in Go项目地址: https://gitcode.com/GitHub_Trending/la/langchaingo导读本文以 LangChainGo 官方教程 basic-chat-app.md 为核心骨架带你用 Go 语言从零搭建一个可运行的聊天应用先完成环境与 API Key 配置再依次实现单次问答 → 交互式对话 → 对话记忆 → 对话链四个递进版本并在每一步结合仓库源码llms/llms.go、memory/buffer.go、chains/conversation.go剖析底层调用机制。读完本文你将掌握openai.New()、llms.GenerateFromSinglePrompt、memory.NewConversationBuffer()与chains.NewConversation的核心用法并能直接运行仓库中完整的可执行示例 examples/tutorial-basic-chat-app。前置条件Go 1.21 或更高版本示例模块 go.mod 声明为go 1.23.8工具链go1.24.6OpenAI API Key用于调用 OpenAI 的对话补全接口Step 1初始化 Go 项目并安装 LangChainGo创建项目目录并初始化 Go modulemkdir langchain-chat-app cd langchain-chat-app go mod init chat-app拉取 LangChainGo 依赖go get github.com/tmc/langchaingo说明仓库中的示例项目是一个独立的 Go modulegithub.com/tmc/langchaingo/examples/tutorial-basic-chat-app其依赖版本为v0.1.14-pre.4你可以直接以它为参照或在自己的模块中执行上述go get获取最新版本。Step 2配置 OpenAI API KeyLangChainGo 的 OpenAI 客户端在初始化时通过环境变量读取凭证最简单的方式是导出环境变量export OPENAI_API_KEYyour-api-key-hereopenai.New()在缺少凭证或模型参数时会自动回退到环境变量配置同时支持OPENAI_API_KEY、OPENAI_BASE_URL等便于使用代理或 Azure OpenAI 兼容端点。如果需要自定义模型、温度、最大 token 等参数可结合 llms/openai/options.go 中的WithModel、WithTemperature等选项传入openai.New(...)。Step 3基础聊天——单次 Prompt 调用最小的聊天程序只做一件事初始化 LLM、构造 context、发一条消息、打印回复。核心代码如下完整文件见 step3_basic.gopackage main import ( context fmt log github.com/tmc/langchaingo/llms github.com/tmc/langchaingo/llms/openai ) func main() { // Initialize the OpenAI LLM llm, err : openai.New() if err ! nil { log.Fatal(err) } // Create a context ctx : context.Background() // Send a message to the LLM response, err : llms.GenerateFromSinglePrompt( ctx, llm, Hello! How can you help me today?, ) if err ! nil { log.Fatal(err) } fmt.Println(AI:, response) }底层原理GenerateFromSinglePrompt 做了什么llms.GenerateFromSinglePrompt是 llms/llms.go 中提供的一个便捷函数它把传入的字符串封装成一条Human角色消息MessageContent{Role: ChatMessageTypeHuman, Parts: []ContentPart{TextContent{Text: prompt}}}然后调用通用的llm.GenerateContent(ctx, messages...)接口完成推理最后从resp.Choices[0].Content中取出文本返回。这意味着你无需关心底层 HTTP 请求细节llms.Model接口屏蔽了各厂商的差异它适合单输入、单文本输出的简单场景更复杂的多轮、多模态输入请直接使用GenerateContent。Step 4交互式聊天——stdin 循环让程序活起来的办法是加入标准输入循环每次读取用户输入调用一次GenerateFromSinglePrompt再打印结果输入quit退出完整代码见 step4_interactive.gopackage main import ( bufio context fmt log os strings github.com/tmc/langchaingo/llms github.com/tmc/langchaingo/llms/openai ) func main() { // Initialize LLM llm, err : openai.New() if err ! nil { log.Fatal(err) } ctx : context.Background() reader : bufio.NewReader(os.Stdin) fmt.Println(Chat Application Started (type quit to exit)) fmt.Println(----------------------------------------) for { fmt.Print(You: ) input, _ : reader.ReadString(\n) input strings.TrimSpace(input) if input quit { break } response, err : llms.GenerateFromSinglePrompt(ctx, llm, input) if err ! nil { fmt.Printf(Error: %v\n, err) continue } fmt.Printf(AI: %s\n\n, response) } }该版本的两个实践要点请求失败不退出单次调用出错时打印Error: ...并continue保持会话继续无状态每一轮 Prompt 都是独立的模型不记得上一轮说过什么——这正是 Step 5 要解决的问题。Step 5加入对话记忆——ConversationBuffer要让 AI 记住上下文需要把历史消息拼进 Prompt 再发给模型。LangChainGo 提供了开箱即用的记忆组件memory.NewConversationBuffer()完整代码见 step5_memory.gopackage main import ( bufio context fmt log os strings github.com/tmc/langchaingo/llms github.com/tmc/langchaingo/llms/openai github.com/tmc/langchaingo/memory ) func main() { // Initialize LLM llm, err : openai.New() if err ! nil { log.Fatal(err) } // Create conversation memory chatMemory : memory.NewConversationBuffer() ctx : context.Background() reader : bufio.NewReader(os.Stdin) fmt.Println(Chat with Memory (type quit to exit)) fmt.Println(----------------------------------------) for { fmt.Print(You: ) input, _ : reader.ReadString(\n) input strings.TrimSpace(input) if input quit { break } // Get conversation history messages, _ : chatMemory.ChatHistory.Messages(ctx) // Format the conversation var conversation string for _, msg : range messages { conversation msg.GetContent() \n } // Add current input to the conversation fullPrompt : conversation Human: input \nAssistant: // Generate response response, err : llms.GenerateFromSinglePrompt(ctx, llm, fullPrompt) if err ! nil { fmt.Printf(Error: %v\n, err) continue } // Save to memory chatMemory.ChatHistory.AddUserMessage(ctx, input) chatMemory.ChatHistory.AddAIMessage(ctx, response) fmt.Printf(AI: %s\n\n, response) } }记忆组件的工作原理ConversationBuffer定义在 memory/buffer.go其核心是一个内嵌的ChatHistory schema.ChatMessageHistory字段。从源码可以确认它的完整行为NewConversationBuffer()通过applyBufferOptions应用默认选项MemoryKey默认为historyHumanPrefix/AIPrefix默认分别为Human/AIChatHistory的默认实现是 memory/chat.go 中的ChatMessageHistory它用内存切片messages []llms.ChatMessage保存消息AddUserMessage追加llms.HumanChatMessageAddAIMessage追加llms.AIChatMessageClear则清空全部历史LoadMemoryVariablesmemory/buffer.go会把历史消息格式化成Human: ...\nAI: ...这样的缓冲字符串或当ReturnMessagestrue时返回消息切片供 Prompt 模板填充。Step 5 是手动完成这三件事取出历史Messages→ 拼进 Prompt → 把新的一问一答写回历史。它虽能工作但每次都要自己拼接模板容易出错Step 6 的对话链会把这些细节全部自动化。Step 6进阶——用 Conversation Chain 自动管理记忆chains.NewConversation(llm, chatMemory)构建一条内置了默认 Prompt 模板与记忆管理的对话链完整代码见 step6_advanced.gopackage main import ( bufio context fmt log os strings github.com/tmc/langchaingo/chains github.com/tmc/langchaingo/llms/openai github.com/tmc/langchaingo/memory ) func main() { // Initialize LLM llm, err : openai.New() if err ! nil { log.Fatal(err) } // Create conversation memory chatMemory : memory.NewConversationBuffer() // Create conversation chain // The built-in conversation chain includes a default prompt template // and handles memory automatically conversationChain : chains.NewConversation(llm, chatMemory) ctx : context.Background() reader : bufio.NewReader(os.Stdin) fmt.Println(Advanced Chat Application (type quit to exit)) fmt.Println(----------------------------------------) for { fmt.Print(You: ) input, _ : reader.ReadString(\n) input strings.TrimSpace(input) if input quit { break } // Run the chain with the input result, err : chains.Run(ctx, conversationChain, input) if err ! nil { fmt.Printf(Error: %v\n, err) continue } fmt.Printf(AI: %s\n\n, result) } fmt.Println(Goodbye!) }对话链的源码构成NewConversation定义在 chains/conversation.go返回一个LLMChain包含四部分默认 Prompt 模板_conversationTemplate即 The following is a friendly conversation between a human and an AI...模板变量为{{.history}}与{{.input}}LLM传入的llms.ModelMemory传入的schema.Memory即 ConversationBuffer输出解析outputparser.NewSimple()直接取文本。chains.Runchains/chains.go在执行时自动完成加载历史memory key 从 Prompt 输入键中剔除→ 渲染模板 → 调用 LLM → 保存新消息的完整流程因此在循环里你只需要调用chains.Run(ctx, conversationChain, input)无需再手动读写ChatHistory。从源码结构看可扩展方向更换记忆类型ConversationBuffer之外仓库还提供了 memory/token_buffer.go按 token 上限截断历史、memory/window_buffer.go按窗口大小保留最近 N 轮等实现它们都实现schema.Memory接口可以直接替换传给NewConversation定制 Prompt需要调整 AI 人设时可自行构造prompts.NewPromptTemplate并构建自定义LLMChain参考 chains/llm.go 的NewLLMChain更换模型除 OpenAI 外本仓库还封装了 Anthropic、GoogleAI、Ollama、Mistral、Cohere、Ernie 等多家 LLM 提供方接口一致替换openai.New()即可切换后端。Step 7运行与完整示例将以上任意版本的代码保存为main.go后运行go run main.go仓库中已经提供了合并全部四个步骤的可执行示例examples/tutorial-basic-chat-app它把四个版本整合进一个main.go通过命令行参数切换入口逻辑见 main.go# Step 3单次问答 go run . step3 # 或 go run . basic # Step 4交互式聊天无记忆 go run . step4 # 或 go run . interactive # Step 5带记忆的聊天 go run . step5 # 或 go run . memory # Step 6基于对话链的进阶聊天无参数时默认运行此项 go run . step6 # 或 go run . advanced或直接 go run .一个真实的运行会话效果如下摘自 examples/tutorial-basic-chat-app/README.md$ go run . Step 6: Advanced Chat with Chains Advanced Chat Application (type quit to exit) ---------------------------------------- You: Hello! Who are you? AI: Hello! Im an AI assistant created to help answer questions and have conversations. Im here to provide helpful, accurate, and friendly responses to whatever youd like to discuss. How can I assist you today? You: Can you remember what I just asked? AI: Yes, I can remember our conversation! You just asked me Hello! Who are you? and I introduced myself as an AI assistant who is here to help answer questions and have conversations with you. You: quit Goodbye!总结与后续扩展至此你已用 LangChainGo 构建了一个功能完整的聊天应用其演进路径清晰可见步骤能力关键 APIStep 3单次问答llms.GenerateFromSinglePromptStep 4交互式循环bufio.ReaderGenerateFromSinglePromptStep 5手动记忆memory.NewConversationBufferChatHistoryStep 6自动记忆chains.NewConversationchains.Run在这套基础上你可以继续向以下方向扩展接入 tools 实现函数调用tool calling结合 vectorstores 与 chains/retrieval_qa.go 搭建 RAG 检索增强问答或使用 chains/sequential.go 串联多条链完成更复杂的多步任务。【免费下载链接】langchaingoLangChain for Go, the easiest way to write LLM-based programs in Go项目地址: https://gitcode.com/GitHub_Trending/la/langchaingo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考