ARTICLE DETAIL

建站实战干货

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

如何用 langchaingo 在 Go 服务里构建 LLM 应用:RAG 与 Agent 实战指南

2026/9/18 10:09:28 拓冰建站 浏览量
如何用 langchaingo 在 Go 服务里构建 LLM 应用:RAG 与 Agent 实战指南 如何用 langchaingo 在 Go 服务里构建 LLM 应用RAG 与 Agent 实战指南【免费下载链接】langchaingoLangChain for Go, the easiest way to write LLM-based programs in Go项目地址: https://gitcode.com/GitHub_Trending/la/langchaingo你的 Go 服务已经稳定跑在生产环境现在产品提了个需求接一个大模型让用户能对着公司文档提问。如果手写 HTTP 调用你不仅要拼各家供应商的 JSON 请求体、处理流式响应、管理多轮对话状态还得在 OpenAI 和 Claude 之间留个切换的余地——换一家模型厂商整个调用层就要重写一遍。langchaingo 就是为解决这个问题而生的它是 LangChain 的 Go 语言实现把 LLM 调用、提示词模板、检索增强、记忆、工具调用拆成可组合的标准构件让你用 Go 的接口和类型系统来写 LLM 应用。它到底是什么langchaingo 的核心定位是LLM 应用编排层它不训练模型而是把调模型这件事抽象成接口再在接口之上叠加快照式的组合能力提示词、链、记忆、检索器、Agent。它解决的是Go 生态里没有一个像样的 LLM 应用框架的问题域——你不用为了写 RAG 把服务改写成 Python。和同类方案的关键差异在于Python 版 LangChain 以动态语言特性元类、动态属性著称而 langchaingo 用 Go 的 interface 重新实现了同一套概念所有抽象都是显式的、可静态检查的。比如模型就是一个带GenerateContent方法的接口而不是魔法对象。架构怎么搭的跟一条数据流走别把 langchaingo 理解成一堆功能模块的堆叠它更像一条装配线。以一次带记忆的问答链为例从你调用chains.Call开始数据流是这样的记忆注入链执行前先从 Memory 取出历史变量合入输入 map这一步在 chains/chains.go 的Call函数里先LoadMemoryVariables再交给链本体提示词渲染Chain 内部用 PromptTemplate 把输入变量填进模板字符串产出最终发给模型的 prompt模型调用渲染好的 prompt 交给实现了llms.Model接口的具体厂商客户端OpenAI、Ollama、Anthropic、Google 等各在 llms/ 下的独立子包统一走GenerateContent进出消息回调与落记忆执行过程通过callbacks.Handler发 start/end/error 事件callbacks/ 包结束后SaveContext把本轮输入输出写回 Memory。换句话说Chain 是流水线Memory 是流水线旁边的状态仓Prompt 是工序间的物料单Callbacks 是全程埋点。各层都通过schema/包里定义的接口解耦——这也是你自定义任何一环的挂载点。真实场景下它怎么跑起来的场景一企业内部文档问答RAG约束答案必须来自你自己的文档库不能靠模型编单次查询延迟要求在秒级且不能把整个语料塞进上下文。对应机制是 chains/question_answering.go 里的 RetrievalQA用户问题先交给 Retriever 做向量相似度检索只取 top-k 相关文档段落再连同问题一起填进模板模板里明确写着不知道就说不知道别编最后由 LLM 生成答案。检索环节由 vectorstores/vectorstores.go 的VectorStore接口支撑——AddDocuments写入、SimilaritySearch检索Pinecone、Qdrant、pgvector、Chroma 等十几家后端都实现了同一接口换向量库只需换构造函数检索逻辑一行不用动。文档入库前的清洗切分由 textsplitter/按字符递归切分、按 markdown 结构切分和 documentloaders/PDF、HTML、CSV、目录批量加载负责。场景二让模型自主调用工具Function Calling Agent约束用户问北京今天限行尾号是多少模型本身不知道必须让它主动去调一个真实函数而不是幻觉一个答案。这里用 agents/openai_functions_agent.go 的 Functions Agent你把工具注册成带 JSON Schema 的函数描述随请求发给模型模型返回 tool callAgent 执行对应的 Go 函数比如 tools/calculator.go 里的计算器、tools/sqldatabase/里的 SQL 查询工具把结果塞回对话继续推理直到模型给出最终答案。tools.Tool接口只有三个方法——Name()、Description()、Call()——所以你自己写一个工具就是实现这三个方法的事tools/ 下的 duckduckgo 搜索、wikipedia、scraper 都是现成参照。跑在生产上的 Go 服务和 Python 侧最大的不同是模型调用变成普通的带context.Context的方法调用超时、取消、日志中间件全走 Go 的既有套路。从零跑起来前置条件Go 1.24以及一个 LLM 供应商的 API Key以 OpenAI 为例。第一步引入模块注意 langchaingo 的 go.mod 虽然很大但 Go 的模块图裁剪机制保证你只 import 了哪个包就拉哪个包的依赖不会全量拖进来go get github.com/tmc/langchaingo第二步写最小可运行的调用参考 examples/openai-completion-example/llm, err : openai.New() // 默认读 OPENAI_API_KEY 环境变量 if err ! nil { log.Fatal(err) } ctx : context.Background() resp, err : llms.GenerateFromSinglePrompt(ctx, llm, What would be a good company name for a company that makes colorful socks?)第三步验证设置好OPENAI_API_KEY后go run .能看到模型返回的公司名示例输出是Socktastic即跑通。没有 OpenAI 账号的话examples/ollama-completion-example/ 演示了用本地 Ollama 跑通同样流程llms/ollama/包指向本地localhost:11434不需要任何外部 Key。更多完整示例按主题放在 examples/ 下llm-chain-example链提示词模板、tutorial-basic-chat-app带记忆的多轮对话从 step3 逐步演进到 step6、prompt-caching提示词缓存省钱技巧。官方文档站入口在 docs/入门章节docs/getting-started/按 chat、RAG、agent 分条写了完整教程。进阶与踩坑注意 Memory 不是自动生效的链不会凭空带上记忆要用memory.NewChatMessageHistory()memory/chat.go建好历史对象后显式注入链否则多轮对话里模型对上一句一无所知。这是最常见的为什么模型不记得刚才说了什么的根因。建议用 callbacks 做可观测性callbacks.Handler会在链、模型、检索器、工具每一层的 start/end/error 时触发。生产环境里把 token 用量、延迟埋进去才能回答这个月 LLM 成本花在哪这类问题。配合 API 网关侧的观测工具如 Helicone 这类代理面板可以看到按 Key 维度的请求与成本分布下图是它的 Key 管理界面常见坑把 provider 逻辑写死在业务代码里。一旦openai.New()散落在各处切换模型的成本会指数上升。保持业务代码只依赖llms.Model接口具体 provider 在 main 里注入的分层后面换厂商或做 A/B 测试才不用动业务层。写在最后langchaingo 适合的场景很明确你主力栈是 Go需要把 LLM 能力对话、RAG、Agent、流式输出编进现有服务并且不想为此引入 Python 运行时。它不太适合纯原型探索——如果只是快速验证 prompt 效果Notebook 类工具迭代更快另外它的抽象对齐的是 LangChain 的成熟期概念个别前沿特性如最新模型的原生多模态细节可能滞后于各厂商官方 SDK 几天。下一步建议先把examples/tutorial-basic-chat-app从 step3 一路跑到 step6能直观看到对话链是怎么一层层长出记忆和工具的然后对照 docs/docs/modules/ 下 chains、agents、memory 三篇文档把接口定义读一遍基本就能上手自己搭了。【免费下载链接】langchaingoLangChain for Go, the easiest way to write LLM-based programs in Go项目地址: https://gitcode.com/GitHub_Trending/la/langchaingo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考