【LangChain1.0】第十四阶段:Agent最佳设计模式与生产实践

第十四阶段: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架构遵循以下设计原则:

  1. 单一职责 - 一个Agent专注解决一类问题
  2. 工具齐全 - 通过工具扩展能力,而非复杂逻辑
  3. 状态清晰 - 最小化状态管理复杂度
  4. 易于测试 - 输入输出明确,可测试性强

三种核心模式

模式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 可观测性建设

三大支柱

  1. Metrics (指标) - 定量监控
  2. Logs (日志) - 事件记录
  3. 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笔记项目组
版本 : v1.0.0
最后更新: 2025-11-20

相关推荐
晚霞的不甘2 小时前
Flutter for OpenHarmony:迈向专业:购物APP的架构演进与未来蓝图
其他·flutter·架构·fiddler·前端框架·harmonyos
2301_790300962 小时前
C++中的观察者模式实战
开发语言·c++·算法
霖霖总总2 小时前
[小技巧49]深入 MySQL JOIN 算法:从执行计划到性能优化
mysql·算法·性能优化
阳艳讲ai2 小时前
九尾狐AI智能矩阵:重构企业获客新引擎
大数据·人工智能
Liue612312312 小时前
窗帘检测与识别_YOLOv26模型详解与应用_1
人工智能·yolo·目标跟踪
啊巴矲2 小时前
小白从零开始勇闯人工智能:计算机视觉初级篇(OpenCV进阶操作(下))
人工智能·opencv·计算机视觉
玄同7652 小时前
SQLAlchemy 会话管理终极指南:close、commit、refresh、rollback 的正确打开方式
数据库·人工智能·python·sql·postgresql·自然语言处理·知识图谱
万岳科技系统开发2 小时前
配送外卖系统源码整体架构解析:从下单到配送的技术实现
架构
萤丰信息2 小时前
四大核心技术领航,智慧园区重构产业生态新范式
java·大数据·人工智能·智慧城市·智慧园区