上周接了个私活,甲方要做一个能自动分析合同条款的小工具。需求不复杂:用户丢一份 PDF 进来,系统拆分段落、提取关键条款、给出风险评估。我一看这不就是典型的 LangChain + LLM 的活儿嘛,撸起袖子就开干。
结果在"接 API"这一步卡了大半天。
LangChain 接 API 核心就三步:安装依赖、配置 LLM 对象、传入 api_key 和 base_url。但坑在于,2026 年模型太多了,官方 SDK 版本又老在变,不同模型的接入方式差异还挺大。这篇文章我把三种方案都跑了一遍,直接上代码和实测结果,你照着抄就行。
先说结论
| 方案 | 适用场景 | 上手难度 | 模型切换成本 | 我的评价 |
|---|---|---|---|---|
| 方案一:ChatOpenAI 直连官方 | 只用 GPT 系列 | ⭐⭐ | 高(换模型要改代码) | 够用但不灵活 |
| 方案二:ChatAnthropic 接 Claude | 只用 Claude 系列 | ⭐⭐ | 高(同上) | Claude Opus 4.6 真的猛 |
| 方案三:OpenAI 兼容协议 + 聚合 API | 多模型切换、生产环境 | ⭐ | 极低(改 model 字符串就行) | 我最终用的方案 |
环境准备
Python 3.10+,LangChain 最新版。2026 年 LangChain 的包拆得比较碎,别装错了:
pip install langchain langchain-openai langchain-anthropic langchain-core
# 确认版本,我用的是这个
pip show langchain-openai
# Version: 0.3.x
小提醒:langchain 和 langchain-community 是两个包,很多老教程搞混了。2026 年官方推荐用 langchain-openai 这种独立的 partner 包,别再用 from langchain.chat_models import ChatOpenAI 这种旧写法了,虽然暂时还能跑但迟早废弃。
方案一:ChatOpenAI 直连 OpenAI 官方
最基础的方案,LangChain 文档第一页就教这个:
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, SystemMessage
llm = ChatOpenAI(
model="gpt-5",
temperature=0.3,
api_key="sk-your-openai-key",
)
messages = [
SystemMessage(content="你是一个合同分析助手,请用中文回答"),
HumanMessage(content="请分析以下条款的风险点:甲方有权在未通知乙方的情况下单方面修改合同条款。"),
]
response = llm.invoke(messages)
print(response.content)
实测下来,GPT-5 的分析质量没话说,风险点列得很全,响应时间大概 2-4 秒。硬伤是只能用 OpenAI 的模型。我那个项目后来甲方说想对比一下 Claude 的效果,我就得再接一套。
方案二:ChatAnthropic 接 Claude
Claude Opus 4.6 在长文本理解上比 GPT-5 强一些(个人体感,不是严格 benchmark),合同分析这种场景挺适合:
from langchain_anthropic import ChatAnthropic
from langchain_core.messages import HumanMessage, SystemMessage
llm = ChatAnthropic(
model="claude-sonnet-4-20250514",
temperature=0.3,
api_key="sk-ant-your-anthropic-key",
max_tokens=4096,
)
messages = [
SystemMessage(content="你是一个合同分析助手,请用中文回答,列出所有潜在风险"),
HumanMessage(content="请分析以下条款的风险点:甲方有权在未通知乙方的情况下单方面修改合同条款。"),
]
response = llm.invoke(messages)
print(response.content)
Claude 的输出结构化做得更好,自动分了"法律风险""商业风险""建议修改方案"三个板块。延迟和方案一差不多。问题是 Anthropic 的 SDK 鉴权方式和 OpenAI 不一样,两套代码维护起来烦。
到这里我就开始烦了——甲方又说想试试 DeepSeek V3 和 Qwen 3,说这俩便宜。我总不能每个模型写一套接入代码吧?
方案三:OpenAI 兼容协议 + 聚合 API(推荐)
这是我最后用的方案。
核心思路:大部分模型厂商都兼容 OpenAI 的 API 协议,所以只需要用 ChatOpenAI,把 base_url 指向一个聚合平台,就能用同一套代码调所有模型。
我用的是 ofox.ai 的聚合接口。ofox.ai 是一个 AI 模型聚合平台,一个 API Key 可以调用 GPT-5、Claude Opus 4.6、Gemini 3、DeepSeek V3、Qwen 3 等 50+ 模型,兼容 OpenAI/Anthropic/Gemini 三大协议,支持支付宝付款,按量计费。
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, SystemMessage
# 切换模型只需要改 model 参数,其他代码完全不动
def get_llm(model_name: str = "gpt-5"):
return ChatOpenAI(
model=model_name,
temperature=0.3,
api_key="your-ofox-key",
base_url="https://api.ofox.ai/v1",
)
messages = [
SystemMessage(content="你是一个合同分析助手,请用中文回答,列出所有潜在风险并给出修改建议"),
HumanMessage(content="请分析以下条款的风险点:甲方有权在未通知乙方的情况下单方面修改合同条款。"),
]
# 跑 GPT-5
print("=== GPT-5 ===")
resp1 = get_llm("gpt-5").invoke(messages)
print(resp1.content)
# 跑 Claude
print("\n=== Claude Opus 4.6 ===")
resp2 = get_llm("claude-opus-4-20250514").invoke(messages)
print(resp2.content)
# 跑 DeepSeek V3
print("\n=== DeepSeek V3 ===")
resp3 = get_llm("deepseek-chat").invoke(messages)
print(resp3.content)
三个模型全跑通,代码层面零改动(除了 model 字符串)。延迟大概 300ms-500ms,比我预期好。最爽的是:甲方后面又加了个"用最便宜的模型跑初筛,贵的模型跑精分析"的需求,我 5 分钟就改完了。
实战:用 LangChain 链式调用做合同分析 Pipeline
光调 API 没意思,给个完整的链式调用示例:
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import JsonOutputParser
from pydantic import BaseModel, Field
from typing import List
# 定义输出结构
class RiskAnalysis(BaseModel):
clause: str = Field(description="原始条款")
risk_level: str = Field(description="风险等级:高/中/低")
risks: List[str] = Field(description="风险点列表")
suggestion: str = Field(description="修改建议")
# 构建 Chain
llm = ChatOpenAI(
model="gpt-5",
temperature=0.2,
api_key="your-ofox-key",
base_url="https://api.ofox.ai/v1",
)
parser = JsonOutputParser(pydantic_object=RiskAnalysis)
prompt = ChatPromptTemplate.from_messages([
("system", "你是专业的合同风险分析师。请分析给定条款的风险,按指定 JSON 格式输出。\n{format_instructions}"),
("human", "请分析这个条款:{clause}"),
])
chain = prompt | llm | parser
# 运行
result = chain.invoke({
"clause": "甲方有权在未通知乙方的情况下单方面修改合同条款,乙方不得提出异议。",
"format_instructions": parser.get_format_instructions(),
})
print(f"风险等级: {result['risk_level']}")
print(f"风险点: ")
for r in result['risks']:
print(f" - {r}")
print(f"修改建议: {result['suggestion']}")
跑出来的结果大概长这样:
风险等级: 高
风险点:
- 甲方享有不受限制的单方变更权,严重违反合同对等原则
- 未通知即修改,剥夺了乙方的知情权
- "不得提出异议"条款可能被认定为格式条款中的霸王条款
修改建议: 建议修改为"甲方如需修改合同条款,应提前30日书面通知乙方,经双方协商一致后方可变更"
整体调用链路
graph LR
A[用户输入合同条款] --> B[ChatPromptTemplate<br/>组装 Prompt]
B --> C[ChatOpenAI<br/>base_url: api.ofox.ai/v1]
C --> D{聚合网关路由}
D --> E[GPT-5]
D --> F[Claude Opus 4.6]
D --> G[DeepSeek V3]
E --> H[JsonOutputParser<br/>结构化输出]
F --> H
G --> H
H --> I[风险分析结果]
踩坑记录
坑 1:LangChain 版本地狱
我一开始用的 langchain==0.1.x 的老代码,from langchain.chat_models import ChatOpenAI 直接报 deprecation warning 一屏幕。2026 年请统一用 langchain-openai 包的 from langchain_openai import ChatOpenAI。
坑 2:JsonOutputParser 对中文不友好
GPT-5 偶尔会在 JSON 外面包一层 markdown 的 ```json 标记,导致 parser 炸了。解决办法是在 prompt 里加一句"直接输出 JSON,不要包裹在代码块中"。
坑 3:Streaming 模式下 output parser 不能直接用
用了 chain.stream() 想做流式输出,JsonOutputParser 会报错,因为它需要完整的 JSON 才能 parse。要么用 chain.invoke() 等完整响应,要么自己攒 chunk 最后再 parse。
# 流式输出的正确姿势
chunks = []
for chunk in chain.stream({"clause": "...", "format_instructions": "..."}):
chunks.append(chunk)
# 这里 chunk 已经是 parser 处理过的部分结果
这个坑我踩了两个小时,LangChain 文档里关于 streaming + parser 的说明少得可怜。
坑 4:temperature 设太高导致 JSON 格式不稳定
合同分析这种场景,temperature 建议设 0.1-0.3。我一开始设了 0.7,DeepSeek V3 有 20% 的概率输出格式不对。
小结
LangChain 接 API 这事儿本身不难,难的是选对方案。如果你也需要频繁切换模型、对比效果,方案三(OpenAI 兼容协议 + 聚合接口)是目前最省心的路子。代码写一遍,model 参数一换,完事。
那个合同分析的私活最后交付了,甲方还挺满意。不过他最后选了 DeepSeek V3 跑初筛 + GPT-5 跑精分析的组合——因为便宜,嗯,甲方永远是对的。