LangChain开发注意事项
核心问题
1. Token成本控制
- 追踪Token使用:每次调用都会消耗Token,直接关联成本
- 长对话问题:消息历史堆积会快速消耗Token和超出上下文窗口
- 解决方案 :
- 使用
SummarizationMiddleware自动总结旧消息 - 使用
ClearToolUsesMiddleware清理旧工具输出 - 定期检查
usage_metadata字段追踪消耗
- 使用
python
# 监控Token使用
response = model.invoke("...")
print(response.usage_metadata)
# {'input_tokens': 8, 'output_tokens': 304, 'total_tokens': 312}
2. 消息历史管理
- 不是所有消息都必需保存:历史消息应该有策略地清理或总结
- 短期记忆vs长期记忆 :
- 短期(State):当前对话的消息
- 长期(Store):跨对话的用户信息
- 实践:在多轮对话前设置最大消息数限制
python
# 保留最近的N条消息
if len(messages) > 20:
messages = messages[-20:] # 只保留最近20条
3. 工具定义的关键性
- 工具描述决定调用:Agent通过读工具的docstring来决定是否调用
- 差的描述导致错误调用:Agent可能调用错误的工具或不调用工具
python
# ❌ 不好:描述模糊
@tool
def do_something(x: str) -> str:
"""做某事"""
pass
# ✅ 好:清晰说明何时使用
@tool
def search_user_database(name: str) -> str:
"""在用户数据库中搜索。用于查找特定用户信息时调用。"""
pass
常见错误
4. 消息格式问题
- 错误的消息类型 :混淆
HumanMessage,AIMessage,ToolMessage - 上下文窗口溢出 :
INVALID_CHAT_HISTORY错误 - 解决:确保消息格式一致,定期检查总长度
5. API认证和速率限制
MODEL_AUTHENTICATION:API密钥无效或未设置MODEL_RATE_LIMIT:超出速率限制,需要重试逻辑- 实践 :
- 使用环境变量管理API密钥
- 实现指数退避重试
python
# 使用重试中间件
from langchain.agents.middleware import RetryMiddleware
agent = create_agent(
model=llm,
tools=[...],
middleware=[RetryMiddleware(max_retries=3)]
)
6. 结构化输出问题
OUTPUT_PARSING_FAILURE:模型返回的数据不符合Schema- 解决 :使用
toolStrategy或providerStrategy自动重试
python
from langchain import toolStrategy
from pydantic import BaseModel
class ContactInfo(BaseModel):
name: str
email: str
agent = create_agent(
model=llm,
responseFormat=toolStrategy(ContactInfo) # 自动验证和重试
)
性能最佳实践
7. 上下文工程(Context Engineering)
- 动态选择工具:不要暴露所有工具,运行时选择相关工具
- 动态选择模型:复杂问题用强模型,简单问题用便宜模型
- 循序渐进:从静态Prompt开始,再加动态特性
python
# 动态选择工具
from langchain.agents.middleware import create_middleware
dynamic_tools_mw = create_middleware({
'wrapModelCall': lambda request, handler: (
handler(request.override(tools=select_relevant_tools(request.state)))
)
})
8. 中间件设计
- 中间件执行顺序很重要 :
beforehooks顺序执行,afterhooks逆序执行 - 保持中间件专注:每个中间件只做一件事
- 使用内置中间件:优先用官方提供的而不是自己写
python
# 好的中间件设计
@wrap_model_call
def logging_middleware(request, handler):
"""只负责日志"""
print(f"Model call: {len(request.messages)} messages")
return handler(request)
9. 流式处理的坑
- Token计数问题:某些provider(如OpenAI)流式模式需要opt-in获取Token
- 部分响应处理:流式响应需要处理不完整的消息
- 解决:检查provider文档中关于流式Token的说明
生产环境注意事项
10. 监控和告警
- 追踪性能指标:latency、error rate、token成本
- 监控限制:错误率、延迟峰值、成本异常
- 使用LangSmith:自动追踪所有调用
11. 错误处理
- 常见错误码 :
GRAPH_RECURSION_LIMIT:Agent陷入循环INVALID_TOOL_RESULTS:工具返回格式错误MODEL_NOT_FOUND:模型名称错误
python
# 实现健壮的错误处理
try:
response = agent.invoke(input)
except Exception as e:
if hasattr(e, 'lc_error_code'):
if e.lc_error_code == 'MODEL_RATE_LIMIT':
# 实现重试
pass
12. 成本优化
- 追踪每个模型的成本 :使用
UsageMetadataCallbackHandler - 使用缓存:某些provider(如Anthropic)支持prompt缓存
- 选择合适的模型:根据任务复杂度选cheap还是powerful
python
# 追踪多个模型的成本
with get_usage_metadata_callback() as cb:
model_1.invoke("...")
model_2.invoke("...")
print(cb.usage_metadata) # 聚合统计
总结
最常见的问题按优先级:
- Token成本失控 - 必须监控和限制
- 消息历史爆炸 - 实现自动总结或清理
- 工具描述不清 - 直接影响Agent表现
- API速率限制 - 需要重试和延迟策略
- 中间件执行顺序 - 影响功能和性能