GLM 接入 LangChain 实战:从基础调用到 Agent 生产避坑
面向开发者,系统讲解 GLM 接入 LangChain:环境依赖、ChatOpenAI 配置、提示模板、流式输出、Agent 工具调用、异常处理与生产避坑。

GLM 接入 LangChain,真正需要解决的问题并不只是让模型返回一段文本。当应用开始涉及提示模板、对话历史、流式输出、外部工具和多步骤任务时,开发者还需要考虑接口兼容性、参数传递、依赖版本以及异常处理。
智谱官方提供了 LangChain 集成指南。当前文档使用 langchain_openai 中的 ChatOpenAI 连接 GLM,并通过智谱的 OpenAI 兼容接口完成请求。官方示例使用的模型标识为 glm-5.3。这条路径的价值在于,开发者可以复用 LangChain 的提示模板、链式调用和 Agent 组件,不必为每个模型单独编写一套基础调用逻辑。
不过,接口兼容不等于所有功能完全一致。GLM 的部分扩展参数、推理模式和工具调用行为,仍需要结合具体接口文档进行验证。
本文以官方文档为基础,从环境准备开始,逐步完成基础调用、提示模板、对话历史、流式输出和 Agent 配置,并讨论生产环境中容易忽略的兼容性与成本问题。
一、GLM 与 LangChain 是如何配合的?
LangChain 是用于构建大模型应用的开发框架。它提供提示模板、模型接口、工具封装、链式调用和智能体等组件,帮助开发者组织完整的应用流程。
GLM 则负责具体的模型推理。应用将用户输入发送给模型,再根据模型返回的内容继续处理。
两者可以理解为不同层次的组件:
- GLM:负责理解输入、生成回答,并在支持的场景中提出工具调用请求。
- LangChain:负责组织提示词、调用模型、管理工具和串联应用步骤。
- 业务代码:负责执行实际操作,例如查询数据库、访问外部 API、校验权限和保存结果。
例如,开发一个企业知识问答系统时,可以先通过 LangChain 组织用户问题和检索到的资料,再调用 GLM 生成回答。如果需要查询实时数据,还可以让模型调用业务工具,由应用执行查询并将结果返回给模型。
这种分层方式有利于维护和扩展。当需要更换模型时,通常只需调整模型初始化和相关参数;提示模板、业务逻辑及工具定义则可以在兼容范围内继续复用。
需要注意,LangChain 不会自动赋予模型所有工具能力。模型是否支持特定功能,仍取决于具体模型、接口以及对应的适配实现。
二、环境准备:先检查 Python 与依赖版本
智谱当前的 LangChain 集成文档列出了以下环境要求:
- Python 版本为 3.8 或更高。
- langchain_community 版本高于 0.0.32。
官方还特别提醒,应确保 langchain_community 满足版本要求,以获得相应的兼容性和功能支持。
这一点容易被忽略。Python 项目经常存在多个虚拟环境,开发者可能已经安装了 LangChain,却仍然在运行时遇到导入错误或组件不兼容的问题。
建议先检查当前环境:
python --version
python -m pip show langchain
python -m pip show langchain-openai
python -m pip show langchain-community这里使用 python -m pip,可以减少安装命令与运行脚本使用不同 Python 解释器的情况。
接下来,按照智谱官方集成页面安装相关依赖:
python -m pip install -U langchain langchain-openai langchainhub httpx_sse官方页面目前仍列出了 langchainhub 和 httpx_sse。前者用于示例中的提示模板获取,后者属于 SSE 相关依赖。不过,具体项目是否需要全部依赖,应结合实际使用的组件和版本判断。
还需要注意,官方示例使用了部分较早的 LangChain 接口。LangChain 的 API 持续演进,安装最新版本后,不能假设所有旧示例都无需调整。正式开发时,应先确认所安装版本对应的 API 文档,再运行示例。
三、获取 GLM API Key,并配置 Base URL
完成依赖安装后,需要准备智谱 API Key。
可以访问智谱开放平台,登录账户并在 API Keys 管理页面创建密钥。创建后应妥善保存,不要将真实密钥直接提交到公开代码仓库。
1. 配置环境变量
Linux 或 macOS 终端可以使用以下命令:
export ZAI_API_KEY="YOUR_API_KEY"将 YOUR_API_KEY 替换为自己的密钥。
Windows PowerShell 可以使用:
$env:ZAI_API_KEY="YOUR_API_KEY"然后在 Python 中读取:
import os
api_key = os.getenv("ZAI_API_KEY")
if not api_key:
raise RuntimeError("请先配置 ZAI_API_KEY")这样可以避免在代码中直接写入密钥。需要注意,环境变量通常只对当前进程及其继承的子进程有效,重启终端或更换运行环境后,可能需要重新配置。
2. Base URL 应该怎么写?
智谱官方 LangChain 示例使用的基础地址是:https://open.bigmodel.cn/api/paas/v4/
在 ChatOpenAI 初始化时,需要同时配置模型名称、API Key 和 Base URL。
import os
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="glm-5.3",
api_key=os.getenv("ZAI_API_KEY"),
base_url="https://open.bigmodel.cn/api/paas/v4/",
temperature=0.6,
)这里使用了 api_key 和 base_url 这两个较新的参数名称。智谱官方集成页面目前也展示了 openai_api_key 和 openai_api_base 的写法;在当前 langchain-openai 中,它们对应兼容的参数别名。
对于新项目,建议优先使用当前版本文档推荐的参数名称。若要严格复现智谱官方示例,也可以使用:
llm = ChatOpenAI(
model="glm-5.3",
openai_api_key=os.getenv("ZAI_API_KEY"),
openai_api_base="https://open.bigmodel.cn/api/paas/v4/",
temperature=0.6,
)两种写法的核心配置一致。
需要特别注意: base_url 必须与 API Key 所属平台和接口类型匹配。智谱普通模型 API 与编程专用端点并不是同一个地址,不能随意混用。
此外,模型 ID 也应以当前账户可用的模型列表为准。官方示例中的 glm-5.3 是文档所使用的模型标识,不意味着所有账户、接口或套餐都必然具有相同的访问权限。
四、首次调用:先让最简单的对话跑通
在加入复杂的 Agent 逻辑之前,建议先测试基础调用。
from langchain_openai import ChatOpenAI
import os
llm = ChatOpenAI(
model="glm-5.3",
api_key=os.getenv("ZAI_API_KEY"),
base_url="https://open.bigmodel.cn/api/paas/v4/",
temperature=0.6,
)
response = llm.invoke(
"请用三句话解释什么是 API 网关。"
)
print(response.content)这段代码完成了四件事:初始化模型客户端、提交用户输入、接收模型响应,以及读取文本内容。
如果调用成功,说明基础配置至少可以正常工作。
如果出现异常,可以按以下顺序检查:
- 确认环境变量是否读取成功。
- 确认 Base URL 是否正确。
- 检查模型名称是否有效。
- 查看账户权限、可用额度和接口返回的错误信息。
- 检查 langchain-openai 版本及其参数兼容性。
不要在出现错误后一次性修改所有参数。先确认认证与网络请求正常,再逐步加入其他功能,更容易定位问题。
五、使用提示模板:让模型配置与业务逻辑分离
在真实应用中,用户输入通常需要配合固定的角色说明和任务要求。
例如,一个技术问答系统可能需要始终要求模型以开发者能够理解的方式解释概念。与其每次手动拼接整段提示词,不如将固定要求与动态内容分开。
LangChain 可以通过 ChatPromptTemplate 实现这一点。
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_messages([
(
"system",
"你是一名技术顾问。请使用清晰、准确的语言回答问题。"
),
(
"human",
"请解释 {topic},并列出两个实际应用场景。"
),
])
chain = prompt | llm
response = chain.invoke({
"topic": "大模型 API 接入"
})
print(response.content)这里使用管道符将提示模板和模型组合成一条处理链。
调用时只需要传入 topic,LangChain 就会将变量填入模板,再把生成后的消息发送给模型。
这种方式有三个实际好处。
第一,固定提示词不需要在每个业务函数中重复编写。
第二,模型配置和提示内容彼此独立,便于更换模型或调整业务要求。
第三,测试更加方便。开发者可以使用同一套提示模板,比较不同模型的回答质量,而不必反复手动整理请求内容。
对于需要大量重复调用的应用,还可以保持固定提示前缀的一致性,并观察服务端上下文缓存是否生效。不过,提示词相同并不保证一定命中缓存,具体还取决于服务端的缓存规则和请求条件。
六、流式输出:让回答逐步返回
默认调用通常是在模型完成响应后,程序再读取完整结果。对于交互式应用,这可能让用户感觉等待时间较长。
流式输出则允许客户端逐步接收生成内容,适合聊天界面、实时助手等场景。
智谱官方 OpenAI 兼容接口提供了 SSE 流式响应示例。对于 LangChain,官方集成页面展示了通过 streaming=True 和回调处理增量输出的方式。
可以使用 LangChain 的流式接口:
for chunk in llm.stream("请介绍 LangChain 的主要用途。"):
if chunk.content:
print(chunk.content, end="", flush=True)
print()这段代码使用 LangChain 的模型流式调用接口逐步读取输出。
需要区分的是,流式输出改善的是响应呈现方式,并不保证模型整体生成速度一定更快。模型的推理时间、网络延迟、输出长度和服务端负载仍然会影响实际体验。
如果应用需要将增量内容推送到网页,还需要将这些内容转发给前端,并正确处理连接关闭、请求取消和异常中断等情况。
七、从 LangChain 到 Agent:让模型调用外部工具
当应用不再满足于回答问题,而是需要查询实时信息或执行多步骤任务时,就可以考虑使用 Agent。
Agent 的核心不是简单地让模型多说几轮,而是让模型根据任务决定下一步需要什么信息、是否调用工具,以及如何利用工具返回的结果继续处理。
例如,用户提出:
“查询某个城市的天气,再根据结果给出出行建议。”
模型本身并不能凭空获得可靠的实时天气数据。开发者需要提供天气查询工具,工具负责调用真实的天气服务,再把结果交还给模型。
1. 定义一个工具
LangChain 提供 @tool 装饰器,可以将普通 Python 函数封装为工具。
from langchain_core.tools import tool
@tool
def get_weather(city: str) -> str:
"""查询指定城市的天气信息。"""
# 这里应接入真实天气 API
return f"{city}:示例天气数据,请替换为真实接口结果。"这个示例只展示工具的定义方式,返回内容是占位数据,并不代表真实天气。
在生产环境中,应当将函数体替换为实际的天气 API 请求,并处理参数验证、超时、异常和数据来源。
工具的名称、描述和参数类型会影响模型对工具用途的理解。因此,建议使用明确的函数名和说明,并限制模型可以调用的操作范围。
2. 使用工具构建 Agent
智谱官方 LangChain 集成页面目前展示了基于 create_react_agent 和 AgentExecutor 的示例,并使用 Tavily 搜索作为外部工具。
其核心结构如下:
from langchain.agents import AgentExecutor, create_react_agent
from langchain import hub
from langchain_community.tools.tavily_search import TavilySearchResults
tools = [
TavilySearchResults(max_results=2)
]
prompt = hub.pull("hwchase17/react")
agent = create_react_agent(
llm,
tools,
prompt,
)
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True,
max_iterations=3,
)
result = agent_executor.invoke({
"input": "查找 LangChain 的官方文档,并总结它的主要用途。"
})
print(result["output"])运行前,需要安装相应的 Tavily 工具依赖,并配置 Tavily 自己的 API Key。它与智谱的 API Key 是不同的凭证。
还要注意,以上代码对应智谱当前集成页面所展示的 Agent 接口。LangChain 不同版本的 Agent API 可能存在变化,执行前应检查当前安装版本的文档。如果使用的版本不再支持相应导入方式,就需要迁移到该版本推荐的 Agent 构建接口,而不能直接假设旧示例仍然可用。
3. Agent 不应该无限执行
官方自定义工具示例中使用了 max_iterations 参数限制执行轮数。这是值得保留的工程措施。
因此,生产环境中的 Agent 不应完全依赖默认执行行为。至少需要设置执行轮数、总耗时和工具权限,避免模型反复调用工具,或者在无法完成任务时持续消耗资源。
可以在现有代码基础上增加执行限制:
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True,
max_iterations=3,
max_execution_time=60,
handle_parsing_errors=True,
return_intermediate_steps=True,
)这里的 max_iterations=3 将 Agent 的执行轮数限制为 3,max_execution_time=60 则为执行过程设置时间上限。handle_parsing_errors=True 用于处理部分 Agent 输出解析错误,让执行器有机会将错误反馈给模型并继续处理。
需要注意,这些参数的具体行为可能随 LangChain 版本变化。时间限制也不应被当成所有底层网络请求都能立即中断的保证,实际效果需要结合当前版本和工具实现进行验证。
生产环境中,哪些异常需要单独处理?
Agent 的错误不只有模型请求失败。根据错误来源,可以分成几类。
表格
| 异常类型 | 常见原因 | 建议处理方式 |
|---|---|---|
| 认证错误 | API Key 无效或权限不足 | 检查密钥、账户权限与模型访问范围 |
| 速率限制 | 请求频率或用量超过限制 | 采用指数退避,避免连续重试 |
| 网络超时 | 网络波动或服务响应延迟 | 设置合理超时,确认任务状态后再决定是否重试 |
| 参数错误 | 模型名称、请求参数或工具输入不符合要求 | 修正参数,不要对同一错误盲目重试 |
| 工具执行失败 | 外部 API 不可用、返回格式异常 | 捕获工具异常,记录失败原因,必要时返回可理解的错误信息 |
| Agent 解析失败 | 模型输出不符合预期格式 | 设置解析错误处理,并限制重新尝试次数 |
异常处理示例
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def run_agent(question: str) -> str:
try:
result = agent_executor.invoke({
"input": question
})
return result["output"]
except TimeoutError:
logger.warning("Agent 执行超时")
return "当前任务处理超时,请稍后重试。"
except Exception:
logger.exception("Agent 执行失败")
return "任务暂时无法完成,请检查配置或稍后重试。"
answer = run_agent(
"查找 LangChain 官方文档,并总结主要用途。"
)
print(answer)这段代码用于展示基础的异常处理结构。不同 SDK 和工具可能抛出不同类型的异常,因此实际项目还应根据使用的 HTTP 客户端、模型适配器和工具接口,分别处理认证错误、限流错误和网络异常。
另外,不要对整个 Agent 任务进行无条件重试。假设 Agent 已经成功创建了一条记录,但在返回结果时发生网络超时,重新执行整个任务可能导致重复写入。对于涉及订单、支付、消息发送或数据修改的工具,应优先设计幂等机制,并在重试前检查任务状态。
八、从示例走向生产:GLM 接入 LangChain 的几个建议
完成基础调用、提示模板和 Agent 后,建议按照以下顺序推进项目:
先验证单轮对话,确认模型名称、Base URL 和 API Key 正常。
再加入提示模板,检查变量替换和消息结构。
引入对话历史,控制历史长度,避免不必要的输入持续累积。
加入工具调用,验证参数、返回结果和失败处理。
最后增加执行轮数、超时、日志和成本监控,再考虑部署到生产环境。
如果应用需要在多个模型之间切换,还应将模型初始化与业务逻辑分离。这样可以在兼容范围内调整模型配置,而不必重写整个应用。
对于需要统一管理多个模型接口的团队,也可以评估 KoalaAPI 这类 API 中转站方案,重点核对目标模型是否可用、接口参数是否兼容、计费规则是否清晰,以及异常处理和数据安全机制是否满足项目要求。不能仅凭平台提供统一入口,就默认所有模型的专有功能都能完整透传。
结语
GLM 接入 LangChain 的关键,不是简单地将一个模型名称填入 ChatOpenAI,而是理解模型接口、框架组件和业务执行环境之间的关系。
对于基础问答,模型初始化与提示模板通常已经足够;对于需要查询数据或调用外部服务的任务,则需要进一步设计工具和 Agent;而当应用进入生产环境后,权限控制、异常处理、执行限制和成本管理同样不可缺少。
先跑通最小调用,再逐层增加功能,是降低集成复杂度最有效的方法之一。每增加一层,都应验证它的输入、输出和失败行为。这样既便于排查问题,也能为后续模型升级和接口切换保留空间。

