news 2026/7/10 5:04:06

【LangChain】4.快速上手-编码

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【LangChain】4.快速上手-编码

4. 快速上手-编码


1. 调用大模型的基本流程

抛开链式结构不谈,调用大语言模型的基本逻辑分为三步:

定义/接入大模型

构造消息

调用模型获取结果

  1. 定义大模型——选择并配置要使用的大模型(如 GPT-4o-mini)
  2. 构造消息——组合系统提示和用户输入
  3. 调用模型——将消息传递给模型,获取响应

下面围绕这个流程逐步展开代码编写。


2. 申请 API Key 并配置环境变量

2.1 申请 API Key

以 OpenAI 为例,前往 platform.openai.com(需科学上网)注册或登录账号。

  • 进入 Settings → API keys 页面:

  • 点击 “Create new secret key” 按钮创建新密钥:

  • 将生成的 API Key 保存在本地,后续接入时需要用到。

2.2 配置环境变量

将 API Key 配置到系统环境变量中,避免在代码中直接暴露密钥。

环境变量名称OPENAI_API_KEY

# Windows 系统setOPENAI_API_KEY=your-api-key-here# Linux/macOS 系统exportOPENAI_API_KEY=your-api-key-here

Tip:重启编译器
如果在编译器(如 VS Code、PyCharm)打开后才配置环境变量,需要重启编译器才能读取到最新的环境变量。

LangChain 的ChatOpenAI默认从系统环境变量OPENAI_API_KEY读取密钥,无需在代码中显式传入。


3. 定义大模型

3.1 安装依赖包

pipinstall-Ulangchain-openai

-U表示升级到最新版本,首次安装可不带此选项。

3.2 定义模型

fromlangchain_openaiimportChatOpenAI model=ChatOpenAI(model="gpt-4o-mini")

ChatOpenAI会从环境变量OPENAI_API_KEY自动读取密钥。如果环境变量未配置,也可显式传入:

model=ChatOpenAI(model="gpt-4o-mini",api_key="your-api-key-here"# 不推荐硬编码)

Note:远程调用
通过 API Key 调用 OpenAI 模型属于远程调用,模型在 OpenAI 服务器上运行,非本地部署。

3.3 ChatOpenAI 常用参数

ChatOpenAI提供了丰富的初始化参数来控制模型行为:

参数说明
model模型名称(如gpt-4o-minigpt-5
temperature采样温度。值越高回答越天马行空,越低越保守
max_tokens最大输出令牌数,None表示由模型自动决定
timeout请求超时时间(秒)
max_retries请求失败时的最大重试次数
api_keyAPI 密钥,默认从环境变量OPENAI_API_KEY读取
base_urlAPI 请求的基础 URL,用于兼容第三方服务商
organizationOpenAI 组织 ID,默认从环境变量OPENAI_ORG_ID读取
temperature(采样温度)

temperature 是控制模型输出随机性的核心参数:

# 保守模式:适合代码生成model=ChatOpenAI(model="gpt-4o-mini",temperature=0)# 创意模式:适合故事创作model=ChatOpenAI(model="gpt-4o-mini",temperature=1.5)
max_tokens(最大输出令牌数)与 Token 概念

max_tokens控制模型单次回复的最大长度。理解它需要先了解Token的概念。

Token 是自然语言处理中文本的基本计量单位,并非简单对应一个词或一个字:

  • 英文:1 Token ≈ 4 个英文字符 ≈ 0.75 个单词
  • 中文:1 个汉字 ≈ 1.5 ~ 2 个 Token

这意味着中文调用大模型消耗的 Token 更多,成本也更高。这也是"用英文调用大模型更省钱"说法的底层原因。

# 限制输出为约 10 个 Token(约 5~6 个汉字)model=ChatOpenAI(model="gpt-4o-mini",max_tokens=10)
超时与重试
model=ChatOpenAI(model="gpt-4o-mini",timeout=30,# 30 秒超时max_retries=3,# 失败重试 3 次)

3.4 通过 base_url 接入兼容模型(如 DeepSeek)

许多第三方模型兼容 OpenAI 的 API 格式,可通过base_urlapi_key直接使用ChatOpenAI接入:

model=ChatOpenAI(base_url="https://api.deepseek.com/v1",api_key="your-deepseek-api-key",model="deepseek-chat",)

Note:base_url 中的 v1
此处v1是 OpenAI 兼容 API 的前缀,与模型版本无关。DeepSeek 原生 API 不带此路径,加v1是为了兼容 OpenAI 的调用格式。


4. 定义消息

LangChain 使用标准化的消息类型来区分不同角色,常见的消息类型有以下几种:

消息类型角色说明
SystemMessage系统提示通常作为输入消息序列的第一条,用于设定 AI 的行为和任务
HumanMessage用户消息来自用户的输入,传递给模型进行处理
AIMessageAI 回复模型返回的响应消息

4.1 定义消息列表

fromlangchain_core.messagesimportHumanMessage,SystemMessage messages=[SystemMessage(content="Translate the following from English into Chinese"),HumanMessage(content="hi!"),]
  • SystemMessage:定义 AI 的角色和行为,如"将英文翻译为中文"
  • HumanMessage:用户的实际输入内容,如"hi!"

之后只需构造新的HumanMessage(如 “my name is xiaoming”),系统提示词无需重复编写,模型会自动结合系统消息进行处理。


5. 调用大模型

在上面的代码中,model是 LangChainRunnable(可运行接口)的实例,提供了标准化的交互方式。对于什么是 Runnable 我们在下一小节中学习

5.1 使用 .invoke() 调用

result=model.invoke(messages)print(result)

输出结果:

content='你好!' additional_kwargs={'refusal': None} ...

5.2 输出说明

result的类型为AIMessage,包含以下关键字段:

字段说明用途场景
content消息的内容——模型返回的文本结果提取最终答案
additional_kwargs额外有效负载(如工具调用编码)工具调用场景
response_metadata响应元数据:请求 ID、模型版本、服务商原始返回数据调试、日志、获取请求上下文
usage_metadata资源消耗:本次调用消耗的 Token 数量成本计算、监控、预算控制

Tip:response_metadata vs usage_metadata

  • response_metadata侧重于响应本身的信息,如请求 ID、模型版本
  • usage_metadata侧重于资源消耗的量化信息,如input_tokensoutput_tokenstotal_tokens

输出示例(格式化后):

# response_metadata{'model_name':'gpt-4o-mini-2024-07-18','system_fingerprint':'fp_...','finish_reason':'stop','logprobs':None}# usage_metadata{'input_tokens':20,'output_tokens':2,'total_tokens':22}

6. 输出解析

有时我们只关心模型返回的文本内容,而非完整的AIMessage对象。LangChain 提供了输出解析器(Output Parser)来提取和格式化结果。

6.1 使用 StrOutputParser

fromlangchain_core.output_parsersimportStrOutputParser parser=StrOutputParser()result_str=parser.invoke(result)print(result_str)# 输出: 你好!

StrOutputParserAIMessage解析为最可能的字符串输出,只保留content部分。

后续还会学习其他类型的输出解析器,用于输出 JSON、结构化数据等格式。


7. 链式执行

以上每一步都需要手动调用.invoke():先调模型,取结果,再调解析器。LangChain 提供了链式执行能力,将多个组件串联,一次调用即可得到最终结果。

7.1 定义链

chain=model|parser

|(管道操作符)是 LangChain Expression Language (LCEL) 的核心语法,model | parser表示将model的输出作为parser的输入。

7.2 执行链

result=chain.invoke(messages)print(result)# 输出: 你好!

链的执行流程:

链式方式(LCEL)

messages

chain

chain.invoke

最终结果

传统方式(手动编排)

messages

model.invoke

取 result

parser.invoke

最终结果

Tip:链的顺序
链按照从前到后的顺序执行:先执行第一个组件(model),再将结果传递给下一个组件(parser)。顺序不能颠倒。

7.3 链式 vs 非链式对比

对比项传统方式链式方式
调用方式每个组件手动.invoke()定义链后一次.invoke()
代码量较多,需手动传递中间结果简洁,组件通过 `

7.4 Runnable 接口:一切组件的基础

为什么modelparserchain都可以调用.invoke()?因为它们都实现了Runnable 接口

理解 Runnable,关键在于理解为什么需要它。下面从"面临的问题→解决方案→设计理念"这条线展开。


7.4.1 为什么需要 Runnable?——旧 Chain 时代的痛点

在 LangChain 早期版本(0.0.x)中,核心抽象是各自独立的 Chain 类(如LLMChainSequentialChainRetrievalQA),存在几个突出问题:

痛点具体表现
接口不统一LLMChain.run()Retriever.get_relevant_docs()OutputParser.parse()——每个组件有自己的一套调用方式
组合困难链与链之间靠input_variables/output_variables字段名匹配,改一个字段名牵一发动全身
流式/批量/异步支持零散每个组件各自实现,不原生,开发者需手动封装
扩展性差想加一个"重试机制"或"日志中间件"需要继承重写整个 Chain 类
可观测性缺失无法统一注入回调、追踪、标签,调试困难

这些问题的根源在于:组件之间缺乏统一的交互协议。就像 U 盘、键盘、显示器各自用不同的接口——每次连接都在找不同的口、找不同的转接头。Runnable 就是 LangChain 的"USB-C 标准"


7.4.2 Runnable 是什么?——统一执行协议

Runnable 是LangChain 所有可执行组件的统一抽象接口,它不仅仅是一个基类,更是一套协议(Protocol)。任何实现了这个协议的对象,都承诺提供以下五组核心方法:

能力方法说明典型场景
同步调用invoke单个输入 → 单个输出实时交互、测试
异步调用ainvoke异步单次调用FastAPI 等高并发服务
批处理batch批量输入 → 批量输出(自动线程池并发)批量文档处理
流式stream输出在生成时逐块返回聊天界面"打字机"效果
组合pipe/ ``通过 LCEL 串联多个 Runnable

关键认识:LangChain 中几乎所有核心组件本质上都是 Runnable 实例

# 以下都是 Runnable——调用方式完全相同prompt=ChatPromptTemplate.from_template("讲个关于{topic}的笑话")model=ChatOpenAI(model="gpt-4o-mini")parser=StrOutputParser()chain=prompt|model|parser# 链本身也是 Runnableprompt.invoke({"topic":"程序员"})# → PromptValuemodel.invoke(messages)# → AIMessageparser.invoke(ai_message)# → strchain.invoke({"topic":"程序员"})# → str(最终结果)

7.4.3 为什么这样设计

1. 统一接口

Prompt、Model、Parser、Retriever 无论内部多复杂,对外一律只认.invoke()。昨天用 GPT,今天换 DeepSeek,明天换本地模型——调用代码零改动。这就是 7.4.2 中"一个 .invoke() 走天下"的底层逻辑。

2.一次定义,四种执行模式

chain=prompt|model|parser# 只定义一次chain.invoke(x)# 单次执行chain.batch([x1,x2])# 批量执行(自动线程池并发)chain.stream(x)# 逐 token 流式awaitchain.ainvoke(x)# 异步

如果组件没实现流式,框架自动把invoke结果包成迭代器 yield 出来。组件可以按需升级,上层代码零感知

例如,一个 LLM 可能只实现了.invoke()(一次性返回完整结果),但调用方使用.stream()时,LangChain 会自动将:

# 底层实现(伪代码)defstream(self,input):result=self.invoke(input)# 调用同步方法yieldresult# 包装成单步迭代器返回

当该 LLM 后来原生实现了流式接口后,只需把真实实现挂到_stream方法上,调用方代码完全不用改——这就是"零感知"的含义:接口统一,上下游解耦。


理解 Runnable 后,下面两件事会变得很自然:

  • 学一个新组件时:不需要重新学它的调用方式——只要是 Runnable,invoke / batch / stream就是肌肉记忆
  • 调试时:可以专注在"组合逻辑对不对"而非"这个组件的调用语法是什么"

这些设计思想在下一节(7.5 多种定义链的方式)中马上就会用到。

7.5 多种定义链的方式

除了|管道操作符,LangChain 还提供了另外两种定义链的方式:

fromlangchain_core.runnablesimportRunnableSequence# 方式一:管道操作符(最推荐,最直观)chain=model|parser# 方式二:RunnableSequencechain=RunnableSequence(first=model,last=parser)# 方式三:.pipe() 方法(参考 Linux 管道设计)chain=model.pipe(parser)

三种方式效果完全相同。方式一最简洁直观,推荐日常使用。.pipe()方法的设计参考了 Linux 系统的管道(pipe)机制,LCEL 借此实现了优雅的组件编排。


8. 完整代码示例

fromlangchain_core.messagesimportHumanMessage,SystemMessagefromlangchain_core.output_parsersimportStrOutputParserfromlangchain_openaiimportChatOpenAI# 1. 定义大模型(默认从环境变量读取 OPENAI_API_KEY)model=ChatOpenAI(model="gpt-4o-mini")# 2. 定义消息列表messages=[SystemMessage(content="请帮我进行翻译,由英文翻译成中文!"),HumanMessage(content="my name is xiaoming")]# 3. 定义输出解析器parser=StrOutputParser()# 4. 定义链并执行chain=model|parser result=chain.invoke(messages)print(result)# 输出: 我叫小明

总结

通过本节的快速上手编码,我们完成了:

  1. 接入大模型——使用ChatOpenAI定义 GPT 模型,通过 API Key 远程调用
  2. 构造消息——使用SystemMessageHumanMessage构造符合 LangChain 规范的消息列表
  3. 调用模型——使用.invoke()方法获取模型响应,理解AIMessage的结构
  4. 输出解析——使用StrOutputParser提取纯文本结果
  5. 链式执行——使用 LCEL 的|操作符将组件串联,一次调用即可得到最终结果
  6. Runnable 接口——理解 LangChain 所有组件的标准化接口,掌握invoke/batch/stream等核心方法
  7. ChatOpenAI 参数调优——掌握 temperature、max_tokens、Token 概念、超时重试及第三方兼容接入

接下来将深入学习聊天模型的高级定义方式(init_chat_model工厂函数、本地部署)以及模型工具调用能力。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/10 5:03:08

2026年6个不撞款的中西文字体下载网站推荐

2026年6个不撞款的中西文字体下载网站推荐设计师、运营和品牌团队在做物料时,都会遇到字体下载的问题。这个步骤看起来不大,但它会影响后面的很多工作。字体能不能快速预览,字体能不能商用,授权记录能不能查清楚,都会影…

作者头像 李华
网站建设 2026/7/10 4:59:34

基于Claude 3.5 Sonnet构建AI编程智能体:从模型到Agent的工程实践

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Qwen 随心用,限时 5 折。 👉 点击领海量免费额度 如果你最近关注AI编程助手,可能会发现一个现象:很多开发者开始讨论一个叫“Claude Code”的工具,但…

作者头像 李华
网站建设 2026/7/10 4:57:17

AI芯片自研趋势与智能驾驶技术解析:2026科技动态深度观察

今天我们来关注2026年7月8日的重要科技动态,重点关注AI芯片、智能驾驶和新能源汽车三大领域的最新进展。DeepSeek自研AI芯片的消息引发行业震动,华为对乾崑智驾数据展示机制的回应澄清了技术误解,小米增程车的上市节奏曝光则预示着新能源汽车…

作者头像 李华
网站建设 2026/7/10 4:54:45

Fable 5 下线延期引端侧 AI 畅想,苹果高通等厂商布局,2028 年或迎新局面

从发布参数,到发布架构 Fable 5 原定 7 月 8 日下午下线,现延长到 12 号,之后订阅用户不能用套餐限额体验。这引发人们对该级别模型在本地设备运行的畅想。过去人们探讨前沿模型关注其强度、速度和可取代的工作,此次有人问能否跑在…

作者头像 李华
网站建设 2026/7/10 4:53:48

STM32F103RCT6 DAC双路输出:示波器X-Y模式显示10种DIY图像(附MATLAB脚本)

STM32F103RCT6 DAC双路输出:示波器X-Y模式创意图形全攻略1. 硬件架构设计与核心原理在嵌入式图形显示领域,利用STM32的DAC功能驱动示波器X-Y模式是一项兼具实用性和趣味性的技术。这套系统的核心在于通过数字模拟转换器(DAC)将数字…

作者头像 李华
网站建设 2026/7/10 4:49:55

医用自助终端专用扫码模块 XT206H1 嵌入式集成技术方案解析

医疗自助设备集成过程中,嵌入式扫码模组是实现身份核验、报告调取、医疗溯源数据采集的核心硬件,医院大厅强光、室内弱光、手机屏幕反光、微小医疗条码等复杂识别环境,对扫码模块成像、解码、硬件适配能力提出严苛要求。本文基于深圳市兴通物…

作者头像 李华