第十四阶段:Agent最佳设计模式与生产实践
版本 : LangChain 1.0.7+ | LangGraph 1.0.3+
定位 : Agent系统从设计到生产的完整实践指南
更新: 2025-11-20
概述
本笔记系统总结了大模型Agent开发与部署的核心实践,涵盖架构设计、性能优化、可靠性保障、监控运维等生产环节。所有内容基于真实项目经验,提供可运行的完整代码示例。
与《LangChain笔记》的关系
建议学习路径:
《LangChain笔记》第一~三阶段 (基础) → 本实践笔记 (生产)
本笔记深化《LangChain1.0》第七阶段(高级应用)和第八阶段(生产实践)的内容,补充实战细节。
学习目标
掌握核心技能:
- 设计可扩展的Agent架构
- 优化响应速度和成本
- 构建可靠的错误处理机制
- 建立完善的监控体系
达成生产标准:
- 响应时间 < 1s (P95)
- 系统可用性 > 99.9%
- 错误恢复自动化
- 全链路可观测
目录
[第一部分: 架构设计模式](#第一部分: 架构设计模式)
- [1.1 单Agent架构设计](#1.1 单Agent架构设计)
- [1.2 状态管理最佳实践](#1.2 状态管理最佳实践)
- [1.3 工具系统设计](#1.3 工具系统设计)
[第二部分: 性能优化实战](#第二部分: 性能优化实战)
- [2.1 响应速度优化](#2.1 响应速度优化)
- [2.2 成本优化策略](#2.2 成本优化策略)
- [2.3 并发与异步处理](#2.3 并发与异步处理)
[第三部分: 可靠性保障](#第三部分: 可靠性保障)
- [3.1 错误处理与重试](#3.1 错误处理与重试)
- [3.2 降级与熔断](#3.2 降级与熔断)
- [3.3 测试策略](#3.3 测试策略)
[第四部分: 监控运维](#第四部分: 监控运维)
- [4.1 可观测性建设](#4.1 可观测性建设)
- [4.2 关键指标监控](#4.2 关键指标监控)
[第五部分: 案例研究](#第五部分: 案例研究)
- [5.1 智能客服Agent优化实战](#5.1 智能客服Agent优化实战)
第一部分:架构设计模式
1.1 单Agent架构设计
核心原则
单Agent架构遵循以下设计原则:
- 单一职责 - 一个Agent专注解决一类问题
- 工具齐全 - 通过工具扩展能力,而非复杂逻辑
- 状态清晰 - 最小化状态管理复杂度
- 易于测试 - 输入输出明确,可测试性强
三种核心模式
模式1: ReAct Agent (推荐 ⭐⭐⭐⭐⭐)
适用场景: 90%的Agent应用场景
架构图:
用户输入
↓
[Agent State]
↓
LLM推理 → 决策 → 工具调用 → 工具执行 → 更新状态
↑ ↓
└────────────── 循环 (直到任务完成) ──────┘
↓
最终响应
完整实现:
python
"""
ReAct Agent 完整实现示例
演示三种状态管理模式: 无状态、内存、持久化
"""
from __future__ import annotations
import asyncio
import os
from collections import defaultdict
from typing import Dict, List
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
from langgraph.prebuilt import create_react_agent
# ============================================================================
# 工具定义
# ============================================================================
@tool
async def search_web(query: str) -> str:
"""搜索网络信息
Args:
query: 搜索关键词
Returns:
搜索结果摘要
"""
# 实际应用中,这里会调用真实的搜索API (如Tavily、SerpAPI)
await asyncio.sleep(0.5) # 模拟网络延迟
return f"搜索结果: 关于'{query}'的最新信息包括..."
@tool
async def calculate(expression: str) -> str:
"""计算数学表达式
Args:
expression: 数学表达式,如 "2 + 2" 或 "10 * 5"
Returns:
计算结果
"""
try:
result = eval(expression)
return f"计算结果: {expression} = {result}"
except Exception as e:
return f"计算错误: {str(e)}"
@tool
async def get_weather(city: str) -> str:
"""获取指定城市的天气信息
Args:
city: 城市名称,如 "北京" 或 "上海"
Returns:
天气信息
"""
# 实际应用中,这里会调用天气API
await asyncio.sleep(0.3)
return f"{city}的天气: 晴天, 温度25°C, 湿度60%"
def get_tools():
"""获取工具列表"""
return [search_web, calculate, get_weather]
def get_model() -> ChatOpenAI:
"""获取LLM模型"""
api_key = os.getenv("OPENAI_API_KEY")
if not api_key:
raise ValueError("请设置 OPENAI_API_KEY 环境变量")
return ChatOpenAI(
model="gpt-4o-mini", # 使用mini版本节省成本
temperature=0
)
# ============================================================================
# 模式1: 无状态Agent
# ============================================================================
class StatelessAgent:
"""无状态Agent - 每次调用独立
优点:
- 简单、可靠
- 易于扩展
- 无状态泄漏风险
缺点:
- 不支持多轮对话
- 每次都重新初始化
"""
def __init__(self):
self.model = get_model()
self.tools = get_tools()
self.agent = create_react_agent(
model=self.model,
tools=self.tools,
state_modifier="你是一个智能助手,可以搜索信息、计算和查询天气。"
)
async def chat(self, user_input: str) -> str:
"""处理用户输入"""
result = await self.agent.ainvoke({
"messages": [("user", user_input)]
})
return result["messages"][-1].content
# ============================================================================
# 模式2: 内存状态Agent
# ============================================================================
class InMemoryAgent:
"""内存状态Agent - 支持多轮对话
优点:
- 实现简单
- 支持多轮对话上下文
缺点:
- 进程重启丢失状态
- 无法水平扩展
- 内存占用持续增长
"""
def __init__(self):
self.model = get_model()
self.tools = get_tools()
self.agent = create_react_agent(
model=self.model,
tools=self.tools,
state_modifier="你是一个智能助手,可以搜索信息、计算和查询天气。"
)
# 每个用户的对话历史 (存储在内存中)
self.conversations: Dict[str, List] = defaultdict(list)
async def chat(self, user_id: str, user_input: str) -> str:
"""处理用户输入 (支持多轮对话)"""
# 获取该用户的历史消息
messages = self.conversations[user_id]
messages.append(("user", user_input))
# 调用Agent
result = await self.agent.ainvoke({"messages": messages})
# 更新历史消息
self.conversations[user_id] = result["messages"]
return result["messages"][-1].content
def clear_history(self, user_id: str):
"""清空用户的对话历史"""
self.conversations[user_id] = []
# ============================================================================
# 模式3: 持久化Agent (生产推荐 ⭐⭐⭐⭐⭐)
# ============================================================================
class PersistentAgent:
"""持久化Agent - 生产级方案
优点:
- 进程重启不丢失状态
- 支持水平扩展
- 可查询历史记录
缺点:
- 需要数据库依赖
- 增加延迟 (通常 < 10ms)
"""
def __init__(self, checkpoint_uri: str = None):
self.model = get_model()
self.tools = get_tools()
# 持久化存储
checkpointer = None
if checkpoint_uri:
try:
from langgraph.checkpoint.postgres import PostgresSaver
checkpointer = PostgresSaver.from_conn_string(checkpoint_uri)
print(f"✓ 使用PostgreSQL持久化: {checkpoint_uri}")
except ImportError:
print("⚠ PostgreSQL依赖未安装,降级到内存模式")
except Exception as e:
print(f"⚠ PostgreSQL连接失败: {e},降级到内存模式")
if checkpointer is None:
# 降级到SQLite(仅用于演示)
try:
from langgraph.checkpoint.sqlite import SqliteSaver
checkpointer = SqliteSaver.from_conn_string(":memory:")
print(f"✓ 使用SQLite内存模式 (仅演示)")
except ImportError:
print("⚠ 无可用checkpointer,使用无状态模式")
self.agent = create_react_agent(
model=self.model,
tools=self.tools,
checkpointer=checkpointer,
state_modifier="你是一个智能助手,可以搜索信息、计算和查询天气。"
)
async def chat(self, thread_id: str, user_input: str) -> str:
"""处理用户输入 (自动持久化)
Args:
thread_id: 会话ID,用于区分不同会话
user_input: 用户输入
"""
config = {"configurable": {"thread_id": thread_id}}
# 调用Agent - 自动加载历史状态
result = await self.agent.ainvoke(
{"messages": [("user", user_input)]},
config=config
)
# 状态自动持久化
return result["messages"][-1].content
使用示例:
python
async def demo_stateless():
"""演示无状态模式"""
agent = StatelessAgent()
# 第一次调用
response1 = await agent.chat("北京天气怎么样?")
print(f"助手: {response1}")
# 第二次调用 - 无法记住上一轮对话
response2 = await agent.chat("那上海呢?") # Agent无法理解"那上海呢"
print(f"助手: {response2}")
async def demo_in_memory():
"""演示内存状态模式"""
agent = InMemoryAgent()
user_id = "user_123"
# 第一轮对话
response1 = await agent.chat(user_id, "北京天气怎么样?")
print(f"助手: {response1}")
# 第二轮对话 - 可以理解上下文
response2 = await agent.chat(user_id, "那上海呢?") # ✓ 能够理解
print(f"助手: {response2}")
async def demo_persistent():
"""演示持久化模式"""
# 尝试使用PostgreSQL,失败则降级
postgres_uri = os.getenv("POSTGRES_URI")
agent = PersistentAgent(checkpoint_uri=postgres_uri)
thread_id = "conversation_456"
# 第一轮对话
response1 = await agent.chat(thread_id, "搜索LangChain最新版本")
print(f"助手: {response1}")
# 第二轮对话 (即使进程重启,通过相同thread_id也能恢复)
response2 = await agent.chat(thread_id, "它有哪些新特性?")
print(f"助手: {response2}")
性能对比:
| 模式 | 首次调用 | 后续调用 | 状态持久化 | 水平扩展 | 推荐场景 |
|---|---|---|---|---|---|
| 无状态 | ~500ms | ~500ms | ❌ | ✅ | 单次查询 |
| 内存 | ~500ms | ~520ms | ❌ | ❌ | 开发测试 |
| 持久化 | ~510ms | ~530ms | ✅ | ✅ | 生产环境 |
1.2 状态管理最佳实践
状态设计原则
1. 最小化原则 - 只保存必要的状态
python
# ❌ 不好 - 保存过多冗余信息
state = {
"all_messages": [...], # 完整历史
"user_profile": {...}, # 用户信息
"search_cache": {...}, # 搜索缓存
"debug_info": {...} # 调试信息
}
# ✅ 好 - 只保存核心状态
state = {
"messages": messages[-10:], # 只保留最近10轮
}
2. 状态隔离 - 不同用户/会话的状态完全隔离
python
# 使用thread_id隔离
config = {"configurable": {"thread_id": f"user_{user_id}"}}
3. 状态清理 - 定期清理过期状态
python
from datetime import datetime, timedelta
async def cleanup_old_sessions(checkpointer, days=30):
"""清理30天前的会话"""
cutoff = datetime.now() - timedelta(days=days)
# 实现清理逻辑
pass
持久化方案对比
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| SQLite | 简单,无额外依赖 | 不支持并发写 | 单机开发 |
| PostgreSQL | 成熟,支持高并发 | 需要运维 | 生产推荐 |
| Redis | 快速,支持TTL | 内存开销大 | 短期会话 |
PostgreSQL持久化完整示例:
python
from langgraph.checkpoint.postgres import PostgresSaver
# 初始化
checkpointer = PostgresSaver.from_conn_string(
"postgresql://user:password@localhost:5432/langchain"
)
# 创建Agent
agent = create_react_agent(
model=model,
tools=tools,
checkpointer=checkpointer
)
# 使用
config = {"configurable": {"thread_id": "user_123"}}
result = await agent.ainvoke(input_data, config=config)
# 查询历史
state = await checkpointer.aget(config)
1.3 工具系统设计
工具设计原则
1. 单一职责
python
# ❌ 不好 - 一个工具做太多事
@tool
def universal_tool(action: str, data: dict) -> str:
if action == "search":
return search(data)
elif action == "calculate":
return calculate(data)
...
# ✅ 好 - 每个工具职责明确
@tool
def search(query: str) -> str:
"""搜索网络信息"""
pass
@tool
def calculate(expression: str) -> str:
"""计算数学表达式"""
pass
2. 清晰的文档字符串
python
@tool
def query_database(sql: str, limit: int = 100) -> str:
"""查询数据库
Args:
sql: SQL查询语句 (只支持SELECT)
limit: 返回结果数量限制,默认100条
Returns:
JSON格式的查询结果
示例:
query_database("SELECT * FROM users WHERE age > 18", limit=10)
"""
pass
3. 错误处理
python
@tool
async def api_call(endpoint: str) -> str:
"""调用外部API"""
try:
async with httpx.AsyncClient(timeout=10.0) as client:
response = await client.get(endpoint)
response.raise_for_status()
return response.text
except httpx.TimeoutException:
return "错误: API调用超时"
except httpx.HTTPError as e:
return f"错误: API调用失败 - {str(e)}"
工具数量控制
推荐方案: 根据场景动态加载工具
python
def select_tools_by_context(user_input: str) -> list:
"""根据用户输入选择相关工具"""
# 关键词检测
if any(kw in user_input for kw in ["天气", "温度", "下雨"]):
return [get_weather]
elif any(kw in user_input for kw in ["计算", "加", "减", "乘", "除"]):
return [calculate]
elif any(kw in user_input for kw in ["搜索", "查找", "了解"]):
return [search_web]
else:
# 默认提供基础工具
return [search_web, calculate]
# 动态创建Agent
relevant_tools = select_tools_by_context(user_input)
agent = create_react_agent(model, tools=relevant_tools)
工具数量建议:
- ✅ 推荐: 3-7个工具 (最优)
- ⚠️ 可接受: 8-15个工具
- ❌ 避免: >20个工具 (LLM容易选错)
第二部分:性能优化实战
2.1 响应速度优化
性能基准
响应时间分级:
响应时间 用户感知 评级
< 100ms 即时响应 ⭐⭐⭐⭐⭐ 卓越
< 500ms 流畅体验 ⭐⭐⭐⭐ 优秀
< 1s 可接受 ⭐⭐⭐ 良好
1-3s 开始感觉慢 ⭐⭐ 需优化
3-5s 明显延迟 ⭐ 差
> 5s 用户流失风险 ❌ 紧急
Agent响应时间组成 (以GPT-4o为例):
总响应时间 = LLM首Token (40%) + LLM生成 (15%) + 工具执行 (35%) + 网络+系统 (10%)
优化策略1: 流式输出 (必做 ⭐⭐⭐⭐⭐)
收益: 首字延迟从5s降至0.2s,降低96%
完整实现:
python
"""
流式输出完整示例
对比流式 vs 非流式的性能差异
"""
import time
import asyncio
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
from langgraph.prebuilt import create_react_agent
@tool
async def search(query: str) -> str:
"""搜索信息"""
await asyncio.sleep(1) # 模拟搜索延迟
return f"搜索结果: {query}"
model = ChatOpenAI(model="gpt-4o-mini", temperature=0)
agent = create_react_agent(model=model, tools=[search])
# ============================================================================
# 非流式调用 - 用户等待所有内容生成完成
# ============================================================================
async def non_streaming_example(query: str):
"""非流式调用"""
print("【非流式调用】")
start = time.time()
result = await agent.ainvoke({"messages": [("user", query)]})
total_time = time.time() - start
print(f"总耗时: {total_time:.2f}s")
print(f"最终响应: {result['messages'][-1].content}\n")
# ============================================================================
# 流式调用 - 用户立即开始看到内容
# ============================================================================
async def streaming_example(query: str):
"""流式调用"""
print("【流式调用】")
start = time.time()
first_chunk_time = None
async for event in agent.astream_events(
{"messages": [("user", query)]},
version="v2"
):
kind = event["event"]
# 流式返回LLM生成的内容
if kind == "on_chat_model_stream":
content = event["data"]["chunk"].content
if content:
if first_chunk_time is None:
first_chunk_time = time.time()
print(f"首字延迟: {first_chunk_time - start:.2f}s\n")
print(content, end="", flush=True)
# 显示工具调用
elif kind == "on_tool_start":
print(f"\n[🔧 调用工具: {event['name']}]", flush=True)
elif kind == "on_tool_end":
print(f"[✓ 工具完成]", flush=True)
total_time = time.time() - start
print(f"\n\n总耗时: {total_time:.2f}s\n")
# ============================================================================
# FastAPI集成示例
# ============================================================================
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
app = FastAPI()
@app.post("/chat/stream")
async def chat_stream(query: str):
"""流式聊天端点"""
async def generate():
async for event in agent.astream_events(
{"messages": [("user", query)]},
version="v2"
):
if event["event"] == "on_chat_model_stream":
content = event["data"]["chunk"].content
if content:
yield f"data: {content}\n\n"
return StreamingResponse(
generate(),
media_type="text/event-stream"
)
性能对比:
python
query = "搜索2024年GDP数据并分析"
# 非流式: 用户等待5秒后一次性看到结果
await non_streaming_example(query)
# 输出: 总耗时: 5.23s
# 流式: 用户200ms后就开始看到内容
await streaming_example(query)
# 输出: 首字延迟: 0.21s, 总耗时: 5.18s
优化策略2: 并行工具调用 (收益 ⭐⭐⭐⭐)
收益: 等待时间降低50-70%
原理: 现代LLM (GPT-4o, Claude 3.5) 会自动识别可并行的工具调用
python
@tool
async def search_web(query: str) -> str:
"""搜索网络 (耗时: 1s)"""
await asyncio.sleep(1)
return f"搜索结果: {query}"
@tool
async def query_database(sql: str) -> str:
"""查询数据库 (耗时: 1s)"""
await asyncio.sleep(1)
return f"查询结果: {sql}"
@tool
async def call_api(endpoint: str) -> str:
"""调用API (耗时: 1s)"""
await asyncio.sleep(1)
return f"API响应: {endpoint}"
# Agent会自动并行调用
agent = create_react_agent(
model=ChatOpenAI(model="gpt-4o"),
tools=[search_web, query_database, call_api]
)
# 单个请求触发3个工具调用
result = await agent.ainvoke({
"messages": [("user", "搜索天气,查询用户数,调用支付API")]
})
# ❌ 串行执行: 3s (1s + 1s + 1s)
# ✅ 并行执行: ~1s (max(1s, 1s, 1s))
控制并发数:
python
from langchain_core.runnables import RunnableConfig
# 限制最大并发数 (避免过载)
config = RunnableConfig(max_concurrency=5)
result = await agent.ainvoke(input_data, config=config)
优化策略3: 模型路由 (收益 ⭐⭐⭐⭐)
收益: 成本降低50-70%,速度提升40-60%
原理: 简单任务用快速模型,复杂任务用强大模型
python
from langchain_openai import ChatOpenAI
from langchain_anthropic import ChatAnthropic
# 模型性能对比 (实测数据)
MODELS = {
"fast": ChatOpenAI(model="gpt-4o-mini"), # ~200ms, $0.15/1M tokens
"balanced": ChatOpenAI(model="gpt-4o"), # ~500ms, $2.5/1M tokens
"powerful": ChatAnthropic(model="claude-sonnet-4"), # ~800ms, $3/1M tokens
}
def select_model(user_input: str) -> ChatOpenAI:
"""根据查询复杂度选择模型"""
# 简单规则
if len(user_input) < 50 and "?" in user_input:
return MODELS["fast"] # 简单问答
# 关键词检测
complex_keywords = ["分析", "总结", "评估", "对比", "推理"]
if any(kw in user_input for kw in complex_keywords):
return MODELS["powerful"] # 复杂分析
return MODELS["balanced"] # 默认
# 使用动态模型
async def smart_agent(user_input: str):
model = select_model(user_input)
agent = create_react_agent(model, tools)
return await agent.ainvoke({"messages": [("user", user_input)]})
基于LLM的路由 (高级):
python
from pydantic import BaseModel
class RouteDecision(BaseModel):
"""路由决策"""
model: str # "fast" | "balanced" | "powerful"
reason: str
# 用快速模型做路由决策
router_model = ChatOpenAI(model="gpt-4o-mini")
router = router_model.with_structured_output(RouteDecision)
async def llm_based_routing(user_input: str):
# 用快速模型分析任务复杂度
decision = await router.ainvoke(
f"分析以下任务的复杂度,选择合适的模型:\n{user_input}"
)
# 用选定的模型执行任务
model = MODELS[decision.model]
agent = create_react_agent(model, tools)
return await agent.ainvoke({"messages": [("user", user_input)]})
优化策略4: 智能缓存 (收益 ⭐⭐⭐)
收益: 相同查询响应时间 < 10ms
精确缓存
python
from langchain_community.cache import RedisCache
import redis
# Redis缓存
redis_client = redis.Redis(
host='localhost',
port=6379,
decode_responses=True
)
cache = RedisCache(redis_client)
model = ChatOpenAI(model="gpt-4o", cache=cache)
# 首次查询: 500ms
result1 = await model.ainvoke("什么是LangChain?")
# 第二次相同查询: <10ms (缓存命中)
result2 = await model.ainvoke("什么是LangChain?")
语义缓存
python
from langchain_community.cache import RedisSemanticCache
from langchain_openai import OpenAIEmbeddings
# 语义缓存 - 相似问题也命中
embeddings = OpenAIEmbeddings()
semantic_cache = RedisSemanticCache(
redis_url="redis://localhost:6379",
embedding=embeddings,
similarity_threshold=0.9 # 相似度阈值
)
model = ChatOpenAI(model="gpt-4o", cache=semantic_cache)
# 首次查询
await model.ainvoke("什么是LangChain?")
# 语义相似的查询也命中缓存
await model.ainvoke("LangChain是什么?") # ✓ 缓存命中
await model.ainvoke("介绍一下LangChain") # ✓ 缓存命中
await model.ainvoke("LangChain的作用") # ✓ 缓存命中
2.2 成本优化策略
Token使用优化
策略1: Prompt压缩
python
# ❌ 不好 - Prompt冗长
prompt = """
你是一个专业的AI助手。
你需要帮助用户解决各种问题。
你应该提供准确、详细的回答。
你需要保持礼貌和专业。
... (更多冗余描述)
用户问题: {question}
"""
# ✅ 好 - Prompt简洁
prompt = """专业AI助手,提供准确回答。
问题: {question}"""
策略2: 上下文窗口控制
python
# 只保留最近N轮对话
MAX_HISTORY = 10
messages = conversation_history[-MAX_HISTORY:]
result = await agent.ainvoke({"messages": messages})
策略3: 使用便宜的Embedding模型
python
# 对比
expensive_embed = OpenAIEmbeddings(model="text-embedding-3-large") # $0.13/1M tokens
cheap_embed = OpenAIEmbeddings(model="text-embedding-3-small") # $0.02/1M tokens
# 对于大多数场景,small模型足够
vectorstore = Chroma(embedding_function=cheap_embed)
2.3 并发与异步处理
异步调用 (必做)
python
# ❌ 不好 - 同步调用
def process_requests(queries):
results = []
for query in queries:
result = agent.invoke({"messages": [("user", query)]})
results.append(result)
return results # 串行处理,100个查询需要100s
# ✅ 好 - 异步批处理
async def process_requests_async(queries):
tasks = [
agent.ainvoke({"messages": [("user", query)]})
for query in queries
]
results = await asyncio.gather(*tasks)
return results # 并发处理,100个查询约10s (取决于max_concurrency)
批处理优化
python
from langchain_core.runnables import RunnableConfig
# 批量处理
inputs = [{"messages": [("user", f"问题{i}")]} for i in range(100)]
# 控制并发
config = RunnableConfig(max_concurrency=10)
results = await model.abatch(inputs, config=config)
# 性能对比:
# 串行: 100次 × 1s = 100s
# 并发(10): 100次 ÷ 10 = 10s
第三部分:可靠性保障
3.1 错误处理与重试
错误分类
python
# 可恢复错误 - 重试有意义
class RecoverableError(Exception):
"""可恢复错误"""
pass
# 网络超时
class NetworkTimeoutError(RecoverableError):
pass
# 速率限制
class RateLimitError(RecoverableError):
pass
# 不可恢复错误 - 立即失败
class UnrecoverableError(Exception):
"""不可恢复错误"""
pass
# 认证失败
class AuthError(UnrecoverableError):
pass
# 配额耗尽
class QuotaExceededError(UnrecoverableError):
pass
重试策略
策略1: 简单重试
python
from tenacity import retry, stop_after_attempt, wait_fixed
@retry(
stop=stop_after_attempt(3), # 最多3次
wait=wait_fixed(2) # 每次等待2秒
)
async def simple_retry_call(user_input: str):
"""简单重试策略"""
return await agent.ainvoke({"messages": [("user", user_input)]})
策略2: 指数退避 (推荐 ⭐⭐⭐⭐⭐)
python
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(
stop=stop_after_attempt(5),
wait=wait_exponential(multiplier=1, min=2, max=60)
# 重试间隔: 2s, 4s, 8s, 16s, 32s
)
async def exponential_backoff_call(user_input: str):
"""指数退避重试"""
return await agent.ainvoke({"messages": [("user", user_input)]})
策略3: 智能重试 (生产推荐 ⭐⭐⭐⭐⭐)
python
from tenacity import (
retry,
stop_after_attempt,
wait_exponential,
retry_if_exception_type
)
import httpx
from openai import RateLimitError, APITimeoutError
@retry(
# 只对特定错误重试
retry=retry_if_exception_type((APITimeoutError, httpx.TimeoutException)),
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=1, max=10)
)
async def smart_retry_call(user_input: str):
"""智能重试 - 只重试可恢复错误"""
try:
return await agent.ainvoke({"messages": [("user", user_input)]})
except RateLimitError as e:
# 速率限制 - 等待更长时间
wait_time = parse_retry_after_header(e)
await asyncio.sleep(wait_time)
raise # 继续重试
except ValueError as e:
# 输入错误 - 不重试
raise ValueError(f"输入验证失败: {e}") from None
策略4: 断路器模式 (防雪崩 ⭐⭐⭐⭐)
python
from enum import Enum
import time
class CircuitState(Enum):
CLOSED = "closed" # 正常
OPEN = "open" # 断路
HALF_OPEN = "half_open" # 半开(测试)
class CircuitBreaker:
"""断路器 - 防止持续调用失败服务"""
def __init__(
self,
failure_threshold: int = 5,
timeout: int = 60,
expected_exception: type = Exception
):
self.failure_threshold = failure_threshold
self.timeout = timeout
self.expected_exception = expected_exception
self.failure_count = 0
self.last_failure_time = None
self.state = CircuitState.CLOSED
async def call(self, func, *args, **kwargs):
"""执行调用,带断路器保护"""
if self.state == CircuitState.OPEN:
# 检查是否可以尝试恢复
if time.time() - self.last_failure_time > self.timeout:
self.state = CircuitState.HALF_OPEN
print("[断路器] 进入半开状态,尝试恢复")
else:
raise Exception("断路器开启,服务不可用")
try:
result = await func(*args, **kwargs)
# 成功 - 重置计数
if self.state == CircuitState.HALF_OPEN:
self.state = CircuitState.CLOSED
print("[断路器] 恢复正常")
self.failure_count = 0
return result
except self.expected_exception as e:
self.failure_count += 1
self.last_failure_time = time.time()
if self.failure_count >= self.failure_threshold:
self.state = CircuitState.OPEN
print(f"[断路器] 触发断路 (失败{self.failure_count}次)")
raise
# 使用
breaker = CircuitBreaker(failure_threshold=3, timeout=30)
async def protected_agent_call(user_input: str):
return await breaker.call(
agent.ainvoke,
{"messages": [("user", user_input)]}
)
3.2 降级与熔断
降级策略
降级1: 工具降级
python
@tool
async def search_with_fallback(query: str) -> str:
"""搜索(带降级)"""
try:
# 主工具: 高质量API
return await premium_search_api(query)
except Exception as e:
print(f"[降级] 主搜索失败: {e}")
try:
# 降级1: 免费API
return await free_search_api(query)
except Exception as e2:
print(f"[降级] 备用搜索失败: {e2}")
# 降级2: 返回缓存
return get_cached_result(query)
降级2: 模型降级
python
class ModelFallback:
"""模型降级"""
def __init__(self):
self.models = [
ChatOpenAI(model="gpt-4o"), # 主模型
ChatOpenAI(model="gpt-4o-mini"), # 降级1
ChatAnthropic(model="claude-sonnet-4"), # 降级2
]
async def invoke_with_fallback(self, messages):
"""带降级的模型调用"""
for i, model in enumerate(self.models):
try:
return await model.ainvoke(messages)
except Exception as e:
print(f"[降级] 模型{i}失败: {e}")
if i == len(self.models) - 1:
raise # 所有模型都失败
raise Exception("所有模型均不可用")
降级3: 功能降级
python
async def agent_with_degradation(user_input: str):
"""带功能降级的Agent"""
try:
# 完整功能: 多工具ReAct Agent
agent = create_react_agent(model, tools=all_tools)
return await agent.ainvoke({"messages": [("user", user_input)]})
except Exception as e:
print(f"[降级] 完整Agent失败: {e}")
try:
# 降级1: 只用核心工具
agent = create_react_agent(model, tools=core_tools)
return await agent.ainvoke({"messages": [("user", user_input)]})
except Exception as e2:
print(f"[降级] 简化Agent失败: {e2}")
# 降级2: 纯LLM,无工具
return await model.ainvoke(user_input)
3.3 测试策略
单元测试
python
import pytest
from unittest.mock import AsyncMock
@pytest.mark.asyncio
async def test_agent_with_search():
"""测试Agent能正确调用搜索工具"""
# Mock工具
mock_search = AsyncMock(return_value="Mock搜索结果")
# 创建Agent
agent = create_react_agent(model, tools=[mock_search])
# 执行
result = await agent.ainvoke({
"messages": [("user", "搜索Python教程")]
})
# 验证
assert mock_search.called
assert "Mock搜索结果" in str(result)
@pytest.mark.asyncio
async def test_retry_on_timeout():
"""测试超时重试"""
mock_agent = AsyncMock()
mock_agent.ainvoke.side_effect = [
asyncio.TimeoutError(), # 第1次失败
asyncio.TimeoutError(), # 第2次失败
{"result": "success"} # 第3次成功
]
@retry(stop=stop_after_attempt(3))
async def call_with_retry():
return await mock_agent.ainvoke({})
result = await call_with_retry()
assert result == {"result": "success"}
assert mock_agent.ainvoke.call_count == 3
第四部分:监控运维
4.1 可观测性建设
三大支柱
- Metrics (指标) - 定量监控
- Logs (日志) - 事件记录
- Traces (追踪) - 链路还原
结构化日志
python
import logging
import json
from datetime import datetime
class StructuredLogger:
"""结构化日志"""
def __init__(self):
self.logger = logging.getLogger("agent")
def log_request(
self,
user_input: str,
response: str,
latency: float,
success: bool,
context: dict = None
):
log_entry = {
"timestamp": datetime.utcnow().isoformat(),
"event": "agent_request",
"input": user_input,
"output": response,
"latency_ms": latency * 1000,
"success": success,
"context": context or {}
}
self.logger.info(json.dumps(log_entry))
# 使用
logger = StructuredLogger()
start = time.time()
try:
result = await agent.ainvoke({"messages": [("user", query)]})
latency = time.time() - start
logger.log_request(
user_input=query,
response=result["messages"][-1].content,
latency=latency,
success=True,
context={"model": "gpt-4o", "tools_used": ["search"]}
)
except Exception as e:
latency = time.time() - start
logger.log_request(
user_input=query,
response=str(e),
latency=latency,
success=False,
context={"error_type": type(e).__name__}
)
LangSmith集成
python
from langsmith import traceable
@traceable(name="agent_call")
async def traced_agent_call(user_input: str):
"""自动追踪到LangSmith"""
return await agent.ainvoke({"messages": [("user", user_input)]})
# LangSmith会自动记录:
# - 总延迟
# - LLM调用次数和时间
# - 工具调用次数和时间
# - Token消耗
# - 完整的调用链路
4.2 关键指标监控
核心指标
python
from prometheus_client import Counter, Histogram, Gauge
# 请求计数
request_count = Counter(
'agent_requests_total',
'Total agent requests',
['status', 'model']
)
# 延迟分布
request_latency = Histogram(
'agent_request_latency_seconds',
'Agent request latency',
['model']
)
# Token消耗
token_usage = Counter(
'agent_tokens_total',
'Total tokens used',
['model', 'type'] # type: prompt/completion
)
# 当前并发
concurrent_requests = Gauge(
'agent_concurrent_requests',
'Current concurrent requests'
)
# 使用
@request_latency.labels(model="gpt-4o").time()
async def monitored_agent_call(user_input: str):
concurrent_requests.inc()
try:
result = await agent.ainvoke({"messages": [("user", user_input)]})
request_count.labels(status="success", model="gpt-4o").inc()
# 记录Token使用
token_usage.labels(model="gpt-4o", type="prompt").inc(result['usage']['prompt_tokens'])
token_usage.labels(model="gpt-4o", type="completion").inc(result['usage']['completion_tokens'])
return result
except Exception as e:
request_count.labels(status="error", model="gpt-4o").inc()
raise
finally:
concurrent_requests.dec()
第五部分:案例研究
5.1 智能客服Agent优化实战
场景描述
某电商平台智能客服系统,日均10万次对话。
优化前状态
性能指标:
- 平均响应时间: 5.2s
- P95延迟: 8.5s
- P99延迟: 12.3s
用户体验:
- 用户满意度: 62%
- 超时率: 15%
- 转人工率: 35%
成本:
- 月度LLM成本: $5,000
- 服务器成本: $1,200
优化策略
优化1: 启用流式输出
python
# 前: 非流式,用户等待5s
# 后: 流式,首字延迟0.3s
async def stream_chat():
async for event in agent.astream_events(input, version="v2"):
if event["event"] == "on_chat_model_stream":
yield event["data"]["chunk"].content
效果: 首字延迟 ↓94% (5.2s → 0.3s)
优化2: Redis缓存常见问题
python
cache = RedisCache(redis.Redis(...))
model = ChatOpenAI(model="gpt-4o", cache=cache)
# 命中率: 35%
# 缓存响应时间: <50ms
效果: 35%请求响应时间 ↓99%
优化3: 简单问题路由到gpt-4o-mini
python
def route_model(query):
if is_simple_qa(query): # FAQ类问题
return "gpt-4o-mini" # $0.15/1M vs $2.5/1M
return "gpt-4o"
效果: 成本 ↓55%
优化4: 并行调用知识库和订单系统
python
# 前: 串行 - 知识库1s + 订单系统1s = 2s
# 后: 并行 - max(1s, 1s) = 1s
效果: 工具调用时间 ↓50%
优化后状态
性能指标:
- 首字延迟: 0.3s (↓94%)
- 平均完整响应: 1.8s (↓65%)
- P95延迟: 3.2s (↓62%)
- P99延迟: 5.1s (↓59%)
用户体验:
- 用户满意度: 89% (↑27%)
- 超时率: 2% (↓13%)
- 转人工率: 18% (↓17%)
成本:
- 月度LLM成本: $2,250 (↓55%)
- 服务器成本: $980 (↓18%)
投入产出比
优化投入:
- 开发时间: 2周
- 基础设施: Redis ($100/月)
收益:
- 成本节省: $2,870/月
- 用户满意度提升: 27%
- ROI: ~28倍/年
最佳实践速查表
✅ 必做清单 (高优先级)
架构设计:
- 使用
create_react_agent而非手动循环 - 生产环境用PostgreSQL持久化checkpointer
- 工具函数有清晰的docstring和参数说明
- 控制工具数量 (3-7个最优)
性能优化:
- 启用流式输出 (收益⭐⭐⭐⭐⭐, 成本低)
- 配置Redis缓存 (收益⭐⭐⭐⭐, 成本低)
- 使用异步调用ainvoke/astream (收益⭐⭐⭐⭐, 成本低)
- 添加性能监控
可靠性:
- 所有外部调用添加超时控制 (30s)
- 实现指数退避重试 (至少3次)
- 区分可恢复/不可恢复错误
- 关键路径添加降级方案
监控:
- 集成LangSmith追踪
- 记录关键指标 (延迟、成本、错误率)
- 设置错误率告警 (>5%)
- 定期审查错误日志
⭐ 推荐清单 (中优先级)
- 实现模型路由降低成本
- 断路器保护下游服务
- 语义缓存提升命中率
- 编写核心场景测试用例
- 集成Sentry错误追踪
🚀 高级清单 (可选)
- 边缘部署降低全球延迟
- 预测性预加载
- 自动化错误分类与恢复
- 构建评估基准
- A/B测试系统
学习路径建议
路径1: 快速提升 (1-2周)
适合: 已有Agent项目,需要快速优化
第二部分 (性能优化) → 第三部分 (可靠性) → 第四部分 (监控)
路径2: 系统学习 (4-6周)
适合: 从零构建生产级Agent
第一部分 (架构) → 第二部分 (性能) → 第三部分 (可靠性)
→ 第四部分 (监控) → 第五部分 (案例)
路径3: 专项深入 (按需)
适合: 针对特定问题
根据实际问题选择对应章节深入研究
环境准备
依赖安装
bash
# 核心依赖
pip install langchain>=1.0.7
pip install langgraph>=1.0.3
pip install langsmith>=0.2.0
# LLM Providers
pip install langchain-openai>=1.0.3
pip install langchain-anthropic
# 数据存储
pip install langchain-chroma
pip install redis
pip install psycopg2-binary
# 监控与测试
pip install prometheus-client
pip install pytest pytest-asyncio
pip install tenacity # 重试库
pip install sentry-sdk # 错误追踪
环境变量
bash
# .env文件
OPENAI_API_KEY=sk-...
LANGCHAIN_API_KEY=ls__...
LANGCHAIN_TRACING_V2=true
LANGCHAIN_PROJECT=agent-production
# PostgreSQL (可选)
POSTGRES_URI=postgresql://user:pass@localhost:5432/langchain
# Redis (可选)
REDIS_HOST=localhost
REDIS_PORT=6379
参考资源
官方文档
相关笔记
- LangChain笔记 - 基础教程
- 大模型设计思想 - 设计理念
社区资源
维护 : LangChain笔记项目组
版本 : v1.0.0
最后更新: 2025-11-20