
AI Agent 的演示很迷人:一次 Prompt,它自动调用工具、规划步骤、给出答案。但一旦把 Agent 部署到真实业务中,面对高并发、长时任务、API 抖动、模型幻觉等“地狱模式”,90% 的原型都会崩溃。工程化,就是给 Agent 装上工业级的骨骼——让它在不确定性中保持稳定、可观测、可扩展。今天,我们用少量代码揭示 Agent 工程化的五大核心支柱。
Agent 调用外部工具(API、数据库、代码执行器)时,任何一次超时或异常都可能导致整条推理链断裂。工程化的第一步就是包裹每一处外部交互:
import time
import logging
from functools import wraps
def robust_tool_call(max_retries=3, backoff=2):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for attempt in range(max_retries):
try:
return func(*args, **kwargs)
except Exception as e:
logging.warning(f"工具调用失败 (尝试 {attempt+1}/{max_retries}): {e}")
if attempt == max_retries - 1:
raise
time.sleep(backoff ** attempt) # 指数退避
return None
return wrapper
return decorator
@robust_tool_call(max_retries=3)
def call_weather_api(city):
# 模拟可能超时或返回错误的 API
import requests
resp = requests.get(f"https://api.weather.com/{city}", timeout=5)
resp.raise_for_status()
return resp.json()工程意义:重试 + 退避 + 日志,将偶发故障对 Agent 决策的影响降至最低。同时,要定义工具返回的统一数据模型(如 ToolResult(status, data, error)),让大模型能解析成功/失败状态。
对话式 Agent 的短期记忆通常只存于内存,一旦服务重启,所有上下文灰飞烟灭。工程化需要将消息历史、计划栈、工具执行记录持久化,并支持从断点恢复。
import json
import redis
class AgentStateStore:
def __init__(self, redis_client, ttl=3600):
self.redis = redis_client
self.ttl = ttl
def save_session(self, session_id, messages, plan_stack, tool_results):
payload = {
"messages": messages,
"plan_stack": plan_stack,
"tool_results": tool_results
}
self.redis.setex(f"agent:session:{session_id}", self.ttl, json.dumps(payload))
def load_session(self, session_id):
data = self.redis.get(f"agent:session:{session_id}")
if data:
return json.loads(data)
return None
def clear_session(self, session_id):
self.redis.delete(f"agent:session:{session_id}")工程精髓:长时任务(如“帮我分析去年全年销售数据”)可能运行数分钟,期间 Agent 需要反复调用 SQL 和 Python 计算引擎。持久化能让任务在服务扩缩容或重启后无缝继续,同时为审计和调试提供完整轨迹。
Agent 的行为是非确定性的,故障排查极其困难。工程化要求结构化日志 + 链路追踪 + 指标埋点,让每一次“思考-行动”循环都可被回放。
import logging
import json
from datetime import datetime
class AgentTracer:
def __init__(self, log_file="agent_trace.log"):
self.logger = logging.getLogger("AgentTrace")
handler = logging.FileHandler(log_file)
handler.setFormatter(logging.Formatter('%(message)s'))
self.logger.addHandler(handler)
self.logger.setLevel(logging.INFO)
def log_step(self, session_id, step_num, thought, action, action_input, observation, duration_ms):
record = {
"timestamp": datetime.utcnow().isoformat(),
"session_id": session_id,
"step": step_num,
"thought": thought,
"action": action,
"input": action_input,
"observation": observation,
"duration_ms": duration_ms
}
self.logger.info(json.dumps(record))
# 可扩展:同时推送到 Elasticsearch / Datadog实战价值:当 Agent 给用户错误答案时,你可以重放所有步骤,精确找到是推理错误、工具返回脏数据,还是模型幻觉。配合 session_id 跨服务追踪,是 SRE 的救命稻草。
Agent 可能陷入死循环(反复调用同一工具而不收敛),或单步耗时过长。工程化必须引入最大步数限制和全局超时,并支持“紧急退出”将控制权交还给用户。
import asyncio
import signal
class AgentOrchestrator:
def __init__(self, max_steps=10, global_timeout=120):
self.max_steps = max_steps
self.global_timeout = global_timeout
async def run_with_timeout(self, session_id, initial_prompt):
# 使用 asyncio 实现超时中断
try:
result = await asyncio.wait_for(
self._run_loop(session_id, initial_prompt),
timeout=self.global_timeout
)
return result
except asyncio.TimeoutError:
# 记录告警,返回友好错误,并保存当前状态供人工接管
logging.error(f"Session {session_id} 全局超时")
return {"status": "timeout", "partial_result": self._capture_state(session_id)}
async def _run_loop(self, session_id, prompt):
for step in range(self.max_steps):
# 决策 → 工具调用 → 观察 → 再次决策
# 若检测到重复动作达到阈值,主动跳出
if self._detect_loop(session_id):
raise RuntimeError("检测到循环执行,已停止")
# ... 执行一步
return {"status": "max_steps_reached"}工程要点:生产环境还需结合熔断器,当某工具的错误率超过阈值时,Agent 自动跳过该工具并告知用户“该服务暂时不可用”。
Agent 的输出无法用简单的断言判断好坏,但工程化必须建立评估体系。可以构建一组典型任务集(Golden Set),每次变更 Prompt 或工具后,自动运行所有用例,并计算成功率、平均步数、Token 消耗等指标。
# 模拟评估框架
test_cases = [
{"input": "查询北京天气", "expected_tools": ["query_weather"], "output_contains": ["晴", "温度"]},
{"input": "计算 123*456", "expected_tools": ["calc"], "output_contains": ["56088"]},
]
def evaluate_agent(agent_func, test_cases):
results = []
for case in test_cases:
try:
output = agent_func(case["input"])
tools_used = output.get("tool_sequence", [])
tool_match = set(case["expected_tools"]).issubset(set(tools_used))
content_match = all(kw in output.get("final_answer", "") for kw in case["output_contains"])
results.append({"case": case["input"], "tool_match": tool_match, "content_match": content_match})
except Exception as e:
results.append({"case": case["input"], "error": str(e)})
# 计算通过率,记录 diff,若低于阈值则阻止上线
return results工程价值:将 Agent 的 Prompt 调优、工具升级视为“代码变更”,必须通过 CI 流水线的评估门禁,避免“改了 Prompt 导致已有功能衰退”。
从原型到生产,Agent 需要脱胎换骨的改造。今天我们看到的重试装饰器、状态存储、链路日志、超时控制、回归评估,并非华丽的新技术,而是传统分布式系统几十年积累的工程智慧在 AI 领域的复现。
记住:用户不会原谅“偶尔正确”的 Agent。只有将稳定性、可观测性和可控性编码进每一行工程代码,Agent 才能真正从实验室走进客服、金融、医疗等关键领域。动手为你的 Agent 加上这五块“骨骼”吧——那时,它不再是玩具,而是一台值得信赖的智能引擎。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。