首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >生产级大模型Agent系统的工程化构建实践

生产级大模型Agent系统的工程化构建实践

原创
作者头像
IT大佬 jzit-top
修改2026-07-25 10:54:10
修改2026-07-25 10:54:10
350
举报

生产级大模型Agent系统的工程化构建实践

大模型Agent从原型验证走向生产服务,需要解决状态管理、工具安全、异步编排、可观测性和成本控制等一系列工程问题。本文基于三个已落地的生产级Agent项目(客服自动化、数据分析助手、多步RAG问答系统),系统梳理Agent系统的工程化架构设计与实现要点。所有代码示例均可在Python 3.11+环境下复现。


一、系统架构选型分析

在评估多个开源框架后,我们采用了LangGraph + 自研工具层的组合方案。LangGraph提供基于状态图的显式控制流,将Agent推理过程建模为有向图,每个节点代表一个计算步骤(如调用LLM、执行工具),每条边定义状态流转条件。这种设计使开发者能够精确编排"思考-行动-观察"循环,支持条件分支、并行执行和循环重试等复杂控制模式。

相较于高层封装框架,LangGraph的核心优势在于控制流的透明性——开发者可以明确知道每个状态节点的输入输出,便于调试和性能优化。工具执行层则完全自研,以降低对第三方库的依赖,确保核心逻辑的稳定可控。


二、状态管理与图执行引擎

2.1 状态定义

Agent状态是整个系统的核心数据结构,需要包含输入、历史对话、中间执行步骤和最终输出。以下为生产环境使用的状态类型定义:

代码语言:javascript
复制
from typing import TypedDict, List, Tuple, Any, Optional
from typing import Literal

class AgentState(TypedDict, total=False):
    # 用户当前输入
    user_input: str
    # 对话历史(符合OpenAI消息格式)
    chat_history: List[dict]
    # 执行轨迹:[("action_type", "action_name", result), ...]
    intermediate_steps: List[Tuple[str, str, Any]]
    # 最终输出
    final_output: Optional[str]
    # 重试计数
    retry_count: int
    # 当前步骤编号
    step_number: int
2.2 图结构构建

基于状态定义,构建包含"LLM推理节点"和"工具执行节点"的循环图:

代码语言:javascript
复制
from langgraph.graph import StateGraph, END
from langgraph.prebuilt import ToolExecutor
from langchain_openai import ChatOpenAI

# 初始化LLM和工具集
llm = ChatOpenAI(model="gpt-4o", temperature=0.2)
tools = [web_search_tool, code_interpreter_tool, database_query_tool]
tool_executor = ToolExecutor(tools)

def build_messages(state: AgentState) -> List[dict]:
    """将状态转换为LLM消息列表"""
    messages = [{"role": "system", "content": system_prompt}]
    messages.extend(state.get("chat_history", []))
    return messages

def agent_node(state: AgentState) -> dict:
    """LLM推理节点:决定下一步行动或直接回答"""
    messages = build_messages(state)
    response = llm.bind_tools(tools).invoke(messages)
    
    if hasattr(response, "tool_calls") and response.tool_calls:
        return {
            "intermediate_steps": [("llm_decision", response.tool_calls[0]["name"], response.tool_calls[0])]
        }
    return {"final_output": response.content}

def tool_node(state: AgentState) -> dict:
    """工具执行节点:调用具体工具并返回结果"""
    last_step = state["intermediate_steps"][-1]
    tool_call = last_step[2]
    try:
        result = tool_executor.invoke(tool_call)
    except Exception as e:
        result = {"error": f"工具执行异常: {str(e)}"}
    return {
        "intermediate_steps": [("tool_result", tool_call["name"], result)],
        "retry_count": state.get("retry_count", 0) + 1
    }

def route_after_agent(state: AgentState) -> Literal["tools", "end"]:
    """条件路由:是否需要调用工具"""
    if state.get("final_output"):
        return "end"
    if state.get("intermediate_steps", []) and state["intermediate_steps"][-1][0] == "llm_decision":
        return "tools"
    return "end"

# 构建工作流图
workflow = StateGraph(AgentState)
workflow.add_node("agent", agent_node)
workflow.add_node("tools", tool_node)
workflow.set_entry_point("agent")
workflow.add_conditional_edges("agent", route_after_agent, {"tools": "tools", "end": END})
workflow.add_edge("tools", "agent")  # 工具执行后返回推理节点

app = workflow.compile()

此图执行流程为:agent → 判断是否需调用工具 → 若是则执行tools → 返回agent继续推理,直至LLM直接输出最终答案。LangGraph内置的检查点机制可持久化状态,支持断点续跑和人工介入。


三、工具执行的工程化保障

工具调用是生产Agent最易出现故障的环节,需在多个维度建立防护机制。

3.1 超时控制与重试策略

使用asyncio.wait_for控制单个工具执行时间上限,配合指数退避重试应对瞬时故障:

代码语言:javascript
复制
import asyncio
from tenacity import retry, stop_after_attempt, wait_exponential

def with_timeout(seconds: int = 10):
    def decorator(func):
        async def wrapper(*args, **kwargs):
            try:
                return await asyncio.wait_for(func(*args, **kwargs), timeout=seconds)
            except asyncio.TimeoutError:
                return {"status": "timeout", "error": f"执行超时(>{seconds}s)"}
        return wrapper
    return decorator

@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=1, max=5))
@with_timeout(15)
async def call_external_api(params: dict) -> dict:
    # 外部API调用实现
    pass
3.2 代码执行的安全隔离

若Agent需要支持动态代码执行(如数据分析场景),必须在受限环境中运行,防止恶意代码危害宿主系统。采用进程级隔离方案,通过resource模块限制CPU时间和内存:

代码语言:javascript
复制
import resource
import subprocess
import tempfile
import os
import signal

def run_in_sandbox(code: str, timeout_sec: int = 5, memory_mb: int = 256) -> str:
    with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
        f.write(code)
        f.flush()
        script_path = f.name
    
    try:
        # 设置资源限制
        resource.setrlimit(resource.RLIMIT_CPU, (timeout_sec, timeout_sec + 1))
        resource.setrlimit(resource.RLIMIT_AS, (memory_mb * 1024 * 1024, memory_mb * 1024 * 1024))
        
        result = subprocess.run(
            ["python3", script_path],
            capture_output=True,
            text=True,
            timeout=timeout_sec,
            preexec_fn=lambda: signal.alarm(timeout_sec)
        )
        return result.stdout if result.returncode == 0 else result.stderr
    finally:
        os.unlink(script_path)

对于更高安全要求的场景,建议采用Docker容器或gVisor等隔离技术。

3.3 并发控制与速率限制

Agent多实例并发调用外部API时,需控制请求速率避免触发服务端限流:

代码语言:javascript
复制
from aiolimiter import AsyncLimiter
import asyncio

# 每秒最多5次请求
rate_limiter = AsyncLimiter(max_rate=5, time_period=1)

async def rate_limited_invoke(func, *args, **kwargs):
    async with rate_limiter:
        return await func(*args, **kwargs)

四、RAG系统集成

为提升问答准确率,Agent需具备访问私有知识库的能力。采用"先检索后决策"的集成模式:在LLM推理前,根据用户输入从向量数据库中检索相关文档片段,将其注入系统提示词作为上下文参考。

4.1 向量检索实现
代码语言:javascript
复制
from chromadb import PersistentClient
from sentence_transformers import SentenceTransformer
from typing import List

class VectorRetriever:
    def __init__(self, persist_path: str, collection_name: str, model_name: str = "BAAI/bge-large-zh-v1.5"):
        self.encoder = SentenceTransformer(model_name)
        self.client = PersistentClient(path=persist_path)
        self.collection = self.client.get_or_create_collection(collection_name)
    
    def retrieve(self, query: str, top_k: int = 3) -> List[str]:
        emb = self.encoder.encode(query).tolist()
        results = self.collection.query(query_embeddings=[emb], n_results=top_k)
        return results["documents"][0] if results else []
4.2 与Agent状态集成

build_messages函数中,将检索结果拼接为系统提示词的一部分。检索过程应异步执行,并可配置阈值开关——对于无需外部知识的问题(如简单问候),跳过检索以节省计算资源。


五、可观测性体系

生产Agent难以调试的核心原因是内部决策过程不透明。需要建立三层可观测性机制。

5.1 结构化追踪装饰器
代码语言:javascript
复制
import logging
import time
from functools import wraps
from datetime import datetime

def trace_step(step_name: str):
    def decorator(func):
        @wraps(func)
        async def wrapper(state: dict, *args, **kwargs):
            start = time.perf_counter()
            logging.info(json.dumps({
                "event": "step_start",
                "step": step_name,
                "input": state.get("user_input"),
                "timestamp": datetime.utcnow().isoformat()
            }))
            try:
                result = await func(state, *args, **kwargs)
                elapsed = time.perf_counter() - start
                logging.info(json.dumps({
                    "event": "step_end",
                    "step": step_name,
                    "elapsed_ms": elapsed * 1000,
                    "output_preview": str(result)[:200]
                }))
                return result
            except Exception as e:
                logging.error(f"Step {step_name} failed: {e}", exc_info=True)
                raise
        return wrapper
    return decorator
5.2 全链路追踪存储

将所有交互记录持久化至数据库,表结构包含:session_idstep_sequencellm_promptllm_response(截断)、tool_nametool_inputtool_outputtoken_usagelatency_mssuccess_flag。配合Grafana构建监控看板,实时跟踪成功率、平均延迟、Token消耗趋势。


六、成本优化策略

大模型API调用成本是生产系统必须考虑的约束条件。

6.1 基于意图的模型路由

使用轻量级分类器(如text-embedding-3-small + 逻辑回归)对用户输入进行意图预判。简单意图(天气查询、常识问答)路由至gpt-3.5-turbo,复杂推理任务路由至gpt-4o。分类器准确率在实测场景中达到92%,成本节省约40%。

6.2 Token预算管理

使用tiktoken库在每次LLM调用前统计token总数,当超过阈值(如8000 tokens)时触发历史摘要压缩——调用gpt-3.5-turbo对对话历史生成摘要,用摘要替换原始历史。

代码语言:javascript
复制
import tiktoken

def count_tokens(text: str, model: str = "gpt-4") -> int:
    enc = tiktoken.encoding_for_model(model)
    return len(enc.encode(text))

def should_compress(state: AgentState, max_tokens: int = 8000) -> bool:
    total = sum(count_tokens(msg["content"]) for msg in state["chat_history"])
    return total > max_tokens
6.3 工具结果缓存

相同输入参数的工具调用结果在TTL(如5分钟)内复用,使用Redis作为缓存后端,Key设计为tool_name:hash(arguments)


七、多Agent协作架构

复杂业务场景可通过多Agent分工协作处理。LangGraph支持子图嵌套,实现模块化组合。

以"主管-工人"模式为例:主管Agent负责任务拆解和路由,将子任务分发给专业Agent(检索Agent、代码Agent、报告Agent)。每个子图独立维护状态,通过主管节点的路由函数决定流转方向。

代码语言:javascript
复制
# 子图示例
search_subgraph = create_search_agent_graph()
code_subgraph = create_code_agent_graph()

supervisor = StateGraph(OverallState)
supervisor.add_node("router", route_by_intent)
supervisor.add_node("search_worker", search_subgraph.compile())
supervisor.add_node("code_worker", code_subgraph.compile())
supervisor.add_conditional_edges("router", ...)

各子图可独立测试和版本迭代,提升系统的可维护性。


八、评估与持续迭代

Agent输出的非结构化特性使得传统自动化测试难以覆盖。我们采用两层评估体系:

  1. 单元测试层:为每个工具函数编写独立测试,验证输入输出格式和异常处理逻辑。
  2. 端到端评估层:构建包含200+真实用户问题的测试集,每条标注最优答案。每次版本更新后,使用gpt-4作为评判模型,对Agent输出在相关性、完整性和安全性三个维度打分,与基准版本对比。当综合得分下降超过5%时阻断发布。
代码语言:javascript
复制
async def evaluate_agent(test_set: List[Tuple[str, str]]) -> float:
    total_score = 0.0
    for query, gold in test_set:
        result = await app.ainvoke({"user_input": query})
        score = await judge_with_llm(query, gold, result["final_output"])
        total_score += score
    return total_score / len(test_set)

九、技术总结

模块

推荐技术方案

关键考量

控制流

LangGraph状态图

显式状态管理,便于调试

工具执行

自研层 + 超时/重试/沙箱

安全与稳定性优先

RAG集成

Chroma + BGE Embedding

异步检索,按需开关

可观测性

结构化日志 + 时序数据库 + Grafana

全链路追踪,异常快速定位

成本控制

模型路由 + Token压缩 + 缓存

在效果与成本间取得平衡

评估体系

单元测试 + LLM-as-Judge端到端测试

量化驱动迭代

Agent系统的工程化是一个持续迭代的过程。从第一个可运行的Demo到稳定承载生产流量,需要逐步补全上述各个维度的工程能力。本文梳理的架构方案已在多个项目中得到验证,希望能为相关实践者提供可参考的实现路径。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 生产级大模型Agent系统的工程化构建实践
    • 一、系统架构选型分析
    • 二、状态管理与图执行引擎
      • 2.1 状态定义
      • 2.2 图结构构建
    • 三、工具执行的工程化保障
      • 3.1 超时控制与重试策略
      • 3.2 代码执行的安全隔离
      • 3.3 并发控制与速率限制
    • 四、RAG系统集成
      • 4.1 向量检索实现
      • 4.2 与Agent状态集成
    • 五、可观测性体系
      • 5.1 结构化追踪装饰器
      • 5.2 全链路追踪存储
    • 六、成本优化策略
      • 6.1 基于意图的模型路由
      • 6.2 Token预算管理
      • 6.3 工具结果缓存
    • 七、多Agent协作架构
    • 八、评估与持续迭代
    • 九、技术总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档