
LangChain
简介
开发由语言模型驱动的应用程序的框架
详细介绍
LangChain
- 出现的原因不难理解:大模型本身只会吐文本,而取数、拼提示、管上下文、调外部工具、把多步串起来这几件事,原本都得开发者自己写胶粘代码。LangChain 就是替开发者扛这一层的东西——官方对它的定义是「用在开发由大型语言模型(LLMs)驱动的应用程序的框架」,目标是把开发、生产化、部署这条路上的重复劳动收掉。
- 官方把好处归纳成三点:快速上手的开发体验、有人管的那部分生产化支撑、以及灵活的部署选项。落到权责上是这样分工:开发层提供大量开源组件和第三方集成,用来把 LLM 应用迅速搭起来;生产化层由 LangSmith 承担,负责评估、监控和优化,盯的是上线之后的性能与稳定性;部署层负责把应用转成生产级 API 和智能代理,要求能扛高并发、能做持久执行,对应企业级部署那一类需求。
- 库的切法是:langchain-core 放着最底层的抽象与接口,langchain 是常用的链和 agent 组装层,langgraph 管有状态、可持续执行的编排。从基础的提示抽象一路到复杂应用的调度都在这套分层里,集成 LangSmith 与 LangGraph 之后,从原型走到生产不必中途换框架。
- 装上哪些包:生态按模型厂商拆成独立包,用哪家装哪家,不必一次全量引入。主包 pip install langchain;对接 OpenAI 装 pip install langchain-openai,对接 Anthropic 装 pip install langchain-anthropic;其余零散的社区工具集中在 pip install langchain-community。
密钥走环境变量,例如 export OPENAI_API_KEY=your_openai_api_key,好处是敏感串不会跟着代码进版本库,换 key 也不必改源码。最短的一条链:ChatOpenAI(model_name="gpt-3.5-turbo") 建模型实例,把厂商接口包成统一的聊天模型;ChatPromptTemplate.from_template("You are a helpful assistant. Answer the user's question: {question}") 建模板,把变量位留到运行时注入;LLMChain(llm=model, prompt=prompt_template) 把模板输出接到模型入口;chain.invoke({"question": "What is the capital of France?"}) 拿到返回值。
不到十行的链路,是 LangChain 里最常被当作起手式的形状。让模型自己去挑工具:把普通 Python 函数包成 Tool 再交给 create_agent,官网示例里的 get_weather(city: str) -> str 返回的是一句固定的字串 "It's always sunny in {city}!",纯粹用来演示调用形状,真实场景里这段会换成查库或调内部接口。
调用写法是 agent.invoke({"messages": [{"role": "user", "content": "What is the weather in Paris?"}]}),入参是 role 与 content 组成的消息列表,与主流对话接口的格式一致。自写工具的门槛同样不高:一个带说明文字的 Python 函数配上 name 和 description 就能注册成 Tool,模型靠 description 判断何时调用它,所以那段描述的措辞会直接影响命中率。
- 链、代理、图这三个词值得先分清:链把若干步骤按固定顺序串起来,输入一路流过去,适合流程已经想清楚的任务;代理把决定下一步的权力交给模型,它会根据返回内容判断要不要再调工具,代价是行为不那么可预测;图则把节点、边和状态显式画出来,分支、循环、人工介入和中途恢复都能表达,LangGraph 所支持的持久执行也只有在这样的结构下才有意义——进程重启之后状态还在,长任务不会被一次超时打断。
- 换个角度看清它的位置:不引这套框架时,一个聊天应用要自己做提示拼接、自己做历史裁剪、自己解析模型返回里夹带的调用意图,每接一个新模型还得重写一遍适配层。用了之后这些细节被收在同一批接口背后,换模型改的往往只是初始化那一行,工具注册也套进了统一形状。代价是抽象层自带学习成本——得先理清链、代理、图各自解决什么问题,才不会被文档里的名词绕晕;而流程极短的小脚本,扛这套抽象反而显重。
改提示之后到底变好还是变坏,需要凭据,LangSmith 干的就是这件事:from langchain.smith import LangSmith 引入,langsmith = LangSmith() 实例化,langsmith.evaluate(chain, input={"question": "What is the capital of France?"}) 输出评估结果,配合调用轨迹能一路看到每次调用的输入与输出,工具被误调、或者某一步反复重试的情况多半在这一步暴露。
对外提供服务时官方示例交给
- LangGraph:from langchain.graph import LangGraph,graph = LangGraph(),graph.add_chain(chain),api = graph.deploy_as_api(),print(api.url) 拿到地址,外部调用方拿这个地址接入即可。
- 集成面决定了这套东西能铺多宽:多家模型和大量第三方工具可以直接挂进来,其中不少由社区成员共同维护,用户自己的工具和模型也能随时注册进去;官方文档按组件、集成、指南分类,遇到某个向量库或某家模型缺示例时,通常能在 langchain-community 里找到对应实现。它常被用去的方向集中在几处:文本生成、文本分类、摘要这类自然语言处理任务;聊天机器人与虚拟助手;企业内部的工作流自动化,把过去靠人工串起来的复杂步骤交给代理;个性化学习工具与智能辅导系统;以及医疗侧的咨询应答与数据分析辅助。
按这份分工,团队里的角色可以对应到具体包上:写提示、拼链路的人主看 langchain 与 langchain-core;做评测和质量把关的人主要泡在 LangSmith;要把服务挂出去、关心并发和进程恢复的人才会碰到 LangGraph。这种对应关系让排错顺序变得清楚——一次线上回答变差,先去 LangSmith 看调用轨迹定位是哪一步,再回到对应层去改,不必把整条链路推倒重排。
- 另一个容易被忽略的点:LangChain 只管编排这一层,模型自身的推理延迟、上下文长度限制和计费方式不会因为接了它就消失,抽象反而容易掩盖单步成本,因此把每一步的输入输出长度记进轨迹,是之后核对账单和排查慢请求的第一步。动手之前有两件现实的事要算清。一是版本节奏:LLMChain、Tool、create_agent 在不同版本之间改过名字和签名,官方维护了迁移指南,照抄之前先对着当前版本的文档核一遍包名,chain 这一层正往 LangGraph 收拢,新项目可以直接从图的方式起步。
- 二是开销:链路里每多一步就多一次模型调用,延迟和 token 花费都在累加,把节点摊开找找哪几步能用规则或多路合并替代,常常比反复改提示更有效。找答案最快的三个地方是 GitHub 仓库、文档站和社区论坛。开源属性还有一项实际好处:遇到文档没写清的实现细节可以翻源码确认,不必在邮件列表里等答复。它的更新节奏不慢,隔一阵回头扫一遍变更说明是值得的。