🏭 构建 Agent 实践指南 — 生产级特性

缓存 · Failover · 多平台 · 监控 · 部署 — 从 20 个 Agent 项目源码提炼的生产方法论

📑 目录

  1. 什么是「生产级」Agent?
  2. 缓存策略:从请求到 Prompt 的多层缓存
  3. Failover 与重试:让 Agent 永不宕机
  4. 多平台部署:一次构建,处处运行
  5. 可观测性:监控、追踪与调试
  6. 配置管理与热更新
  7. 凭证与密钥管理
  8. 速率限制与成本控制
  9. 部署架构:从本地到云原生
  10. 跨项目生产级成熟度评估
  11. 实战清单:为你的 Agent 加持生产级特性

1. 什么是「生产级」Agent?

大多数 Agent 项目在 demo 阶段看起来很惊艳,但一上生产就崩。原因很简单——demo 只关心 happy path,生产必须处理所有 unhappy path

Demo vs 生产级 Agent 的差异

维度Demo Agent生产级 Agent
LLM 调用单 provider,挂了就挂了多 provider failover + credential 轮换
提示词硬编码字符串分层组装 + 缓存 boundary + 热更新
上下文无限增长直到 token 溢出压缩/摘要策略 + 固定窗口
错误处理try-catch 打日志重试 + 降级 + 熔断 + 告警
部署python main.pyDocker + 编排 + 健康检查
平台CLI 或 Web UI14-30+ 消息平台适配
监控print()Prometheus + Sentry + OTel + Langfuse
密钥.env 文件Credential Pool + 速率追踪 + 轮换
配置代码里改常量运行时热更新 + 环境分层
成本不在意Token 计量 + 预算控制 + 缓存省钱
核心洞察:在 20 个项目中,只有 OpenClawHermes 是真正的生产级部署——它们有真实用户在 14-30+ 平台上 7×24 运行。其他项目大多是开发者工具或研究框架,离生产还差一层。

2. 缓存策略:从请求到 Prompt 的多层缓存

缓存是生产环境最直接的成本优化手段。一次 LLM 调用可能花费 $0.01-0.10,如果你的系统提示词有 3 万 token,每次请求都在重复发送同样的前缀——这是巨大的浪费。

2.1 四层缓存架构

┌─────────────────────────────────────────────────────────────────────┐ │ Agent 缓存四层架构 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ Layer 1: LLM Provider Prefix Cache (外部) │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ Anthropic / OpenAI / Google 的原生 prompt cache │ │ │ │ 规则: 相同前缀 → 跳过计算 → 延迟 ↓ 成本 ↓ 50% │ │ │ │ 要求: 前 N 个 token 必须跨 turn 完全一致 │ │ │ └───────────────────────────────────────────────────────────┘ │ │ ↓ 关键 │ │ Layer 2: Cache Boundary (应用层) │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ 把系统提示词分为 STABLE PREFIX / VOLATILE SUFFIX │ │ │ │ Stable: 身份 + 工具定义 + 技能 → 跨 turn 不变 │ │ │ │ Volatile: 记忆 + 运行时状态 → 每 turn 重建 │ │ │ │ → 确保 Layer 1 的 prefix cache 命中 │ │ │ └───────────────────────────────────────────────────────────┘ │ │ ↓ │ │ Layer 3: LRU 组装缓存 (应用层) │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ Stable prefix 的构建结果缓存 (LRU 上限 64 条) │ │ │ │ 避免 每个 turn 重新 组装 ~36K 字符 的系统提示词 │ │ │ │ → CPU 时间 ↓ + 组装延迟 ↓ │ │ │ └───────────────────────────────────────────────────────────┘ │ │ ↓ │ │ Layer 4: 工具结果缓存 (应用层) │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ 相同工具 + 相同参数 → 返回缓存结果 │ │ │ │ 例: CrewAI 的 CacheHandler, SWE-agent 的历史结果 │ │ │ │ → API 调用 ↓ + 延迟 ↓ │ │ │ └───────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────┘

2.2 Cache Boundary — OpenClaw 的天才设计

OpenClaw

这是 20 个项目中最精妙的缓存设计。核心思路:让 LLM provider 的 prefix cache 尽可能命中

实现细节

System Prompt 组装 (~36,206 字符 + ~32,694 字符工具定义) ┌─────────────────────────────────────────────┐ │ STABLE PREFIX (缓存热区,跨 turn 不变) │ │ │ │ 1. Identity (SOUL.md / AGENTS.md) │ │ 2. Tool Definitions (~32K 字符) │ │ 3. Skills (SKILL.md 内容) │ │ 4. Tool Guidance (per-model) │ │ 5. User Profile (USER.md) │ │ 6. Platform Context (Telegram/Discord/...) │ │ 7. System Constraints (安全边界) │ │ 8. Provider Overlay (GPT-5 等) │ ├─────────────────────────────────────────────┤ │ ← CACHE BOUNDARY → │ │ (system-prompt-cache-boundary.ts) │ │ SHA256 hash 验证 prefix 稳定性 │ ├─────────────────────────────────────────────┤ │ VOLATILE SUFFIX (每 turn 重建) │ │ │ │ 9. Memory State (MEMORY.md 内容) │ │ 10. Runtime Context (时间/设备/频道) │ │ 11. Conversation History (摘要/压缩) │ │ 12. Pending Approvals │ │ 13. Sub-Agent Status │ └─────────────────────────────────────────────┘

关键代码src/agents/system-prompt-cache-boundary.ts (~50 行)——用 SHA256 哈希验证 stable prefix 没有被意外修改,确保 provider 的 prefix cache 始终命中。

设计启示:不要把所有东西都塞进系统提示词然后期望缓存自动工作。你必须主动设计分割点——哪些跨 turn 不变(stable),哪些每 turn 变化(volatile)。这个分割点就是你的 Cache Boundary。

2.3 Hermes 的缓存复用策略

Hermes

Hermes 的 Background Review Fork 是另一个巧妙的缓存利用场景:

Review Fork 继承父 Agent 的缓存

主 Agent 对话 Background Review Fork ┌────────────────┐ ┌────────────────────┐ │ User → LLM │ │ fork 继承: │ │ LLM → Tool │ ──fork──→ │ - runtime │ │ Tool → Result │ │ - provider │ │ ... │ │ - cached prompt │ ← 直接命中 │ │ │ - credentials │ prefix cache │ System Prompt │ │ - cache │ (~26% 成本 ↓) │ = ~36K stable │ │ │ │ + volatile │ │ 白名单: 只能调用 │ │ │ │ memory + skill │ └────────────────┘ └────────────────────┘

效果:实测约 26% 的成本降低。Review fork 不需要重新构建系统提示词,直接复用父 agent 已缓存的版本。

2.4 其他项目的缓存策略

项目缓存策略实现方式效果
OpenClawCache Boundary + LRUstable/volatile 分割 + SHA256 验证 + LRU 64 条Provider prefix cache 命中率最大化
Hermes继承父缓存Review fork 继承 cached prompt~26% 成本降低
CrewAICacheHandler工具结果缓存,相同输入返回缓存减少重复 API 调用
SWE-agent命令历史缓存相同 shell 命令返回历史输出减少容器执行次数
AutoGPTLLM 响应缓存Redis 事件总线 + LLM 结果缓存降低重复推理成本
LangGraphCheckpointState snapshot 持久化,可回溯失败恢复,非典型缓存
常见反模式:把整个对话历史作为系统提示词的一部分发送,导致每 turn 的 prefix 都不同,provider 的 prefix cache 完全失效。正确做法是对话历史放在 user/assistant message 中,系统提示词保持稳定。

3. Failover 与重试:让 Agent 永不宕机

LLM API 是生产环境中最不可靠的依赖——它会限流、超时、返回 500、偶尔整个服务宕机。你的 Agent 必须优雅地处理所有这些情况。

3.1 多层 Failover 架构

┌─────────────────────────────────────────────────────────────────────┐ │ LLM 调用 Failover 五层防线 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ Layer 1: 指数退避重试 (Retry) │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ 处理: 瞬态错误 (429 RateLimit, 503, ConnectionError) │ │ │ │ 策略: exponential backoff + jitter │ │ │ │ 参数: max_retries=5, multiplier=8.0 (OpenHands) │ │ │ │ 退避: 1s → 8s → 64s → ... (加上随机 jitter 防惊群) │ │ │ └───────────────────────────────────────────────────────────┘ │ │ ↓ 重试耗尽 │ │ Layer 2: Provider 降级 (Fallback) │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ 处理: 单 provider 持续不可用 │ │ │ │ 策略: 自动切换到备用 provider │ │ │ │ 例: OpenAI 挂 → Anthropic → Google → DeepSeek │ │ │ │ OpenClaw: 40+ provider, Hermes: multi-provider │ │ │ └───────────────────────────────────────────────────────────┘ │ │ ↓ 全部不可用 │ │ Layer 3: 模型降级 (Model Downgrade) │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ 处理: 高端模型不可用 │ │ │ │ 策略: 降级到更小/更稳定的模型 │ │ │ │ 例: Claude Opus → Claude Sonnet → Claude Haiku │ │ │ │ OpenHands: 可配置 fallback 策略 (ALL / STOP) │ │ │ └───────────────────────────────────────────────────────────┘ │ │ ↓ 仍然失败 │ │ Layer 4: Credential 轮换 (Key Rotation) │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ 处理: 单 API key 限流 │ │ │ │ 策略: 自动切换到下一个 credential │ │ │ │ Hermes: Credential Pool + 速率追踪 │ │ │ │ OpenClaw: credential rotation 作为 failover 的一环 │ │ │ └───────────────────────────────────────────────────────────┘ │ │ ↓ 仍然失败 │ │ Layer 5: 优雅降级 (Graceful Degradation) │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ 处理: 所有 LLM 调用失败 │ │ │ │ 策略: 返回缓存的/默认响应,告知用户稍后重试 │ │ │ │ Agent Zero: 使用本地模型的最后手段 │ │ │ └───────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────┘

3.2 OpenHands 的 RetryMixin — 最完善的重试实现

OpenHands

RetryMixin 实现

class LLM(BaseModel, RetryMixin, NonNativeToolCallingMixin):
    model: str = "claude-sonnet-4-20250514"
    api_key: str | SecretStr | None
    base_url: str | None
    num_retries: int = 5           # 最大重试次数
    retry_multiplier: float = 8.0  # 退避因子
    timeout: int = 300             # 单次请求超时 (秒)
    max_message_chars: int = 30_000
    max_output_tokens: int | None

# 只对这些瞬态错误重试:
LLM_RETRY_EXCEPTIONS = (
    APIConnectionError,     # 网络错误
    RateLimitError,         # 429 限流
    ServiceUnavailableError, # 503 服务不可用
)

# 不对以下错误重试:
# - AuthenticationError (401/403): key 有问题,重试没用
# - BadRequestError (400): 请求格式错误,重试没用
# - NotFoundError (404): 模型不存在,重试没用
关键设计:只对瞬态错误重试,对确定性错误不重试。这是很多人忽略的——对 400 错误重试 5 次只是浪费时间和 token。

3.3 LangGraph 的 RetryPolicy — 声明式重试

LangGraph

节点级重试策略

from langgraph.pregel import RetryPolicy

graph.add_node(
    "api_call",
    call_external_api,
    retry=RetryPolicy(
        max_attempts=3,          # 最大重试次数
        initial_interval=1.0,    # 初始间隔(秒)
        backoff_factor=2.0,      # 退避因子
        max_interval=10.0,       # 最大间隔上限
        jitter=True,             # 随机抖动防惊群
    )
)

# 命令式 failover: 执行时切换节点
graph.invoke(
    Command(goto="fallback_node"),  # 跳到备用节点
    config
)

LangGraph 的独特之处:重试策略是图节点的属性,不是全局配置。不同节点可以有不同的重试参数。

3.4 OpenClaw 的四维 Failover

OpenClaw

Provider Runtime 的 Failover 策略

用户请求 ↓ ┌─────────────────────────────────────────────┐ │ Provider Runtime (LLM 调用层) │ │ │ │ Step 1: 主 Provider + 主 Model │ │ ↓ 失败 │ │ Step 2: 同 Provider + 降级 Model │ │ ↓ 失败 │ │ Step 3: 备 Provider + 对等 Model │ │ ↓ 失败 │ │ Step 4: Credential 轮换 + 重试 │ │ ↓ 失败 │ │ Step 5: 最终降级 + 用户通知 │ │ │ │ 40+ Provider: │ │ OpenAI → Anthropic → Google → DeepSeek → │ │ Groq → Mistral → Ollama → LMStudio → ... │ └─────────────────────────────────────────────┘

3.5 Failover 对比表

项目重试Provider 降级模型降级Key 轮换优雅降级
OpenClaw✅ 40+
Hermes✅ multi✅ Pool⚠️
OpenHands✅ RetryMixin✅ fallback✅ ALL/STOP⚠️ 单 key⚠️
LangGraph✅ RetryPolicy⚠️ 手动⚠️ Command
AutoGPT✅ 6 providers⚠️⚠️⚠️
其他⚠️ 基础

4. 多平台部署:一次构建,处处运行

生产级 Agent 最大的挑战之一是消息平台适配——用户在 Telegram 上和你聊,在 Discord 上@你,在 WhatsApp 上发消息给你。你的 Agent 需要同时支持所有这些。

4.1 两种架构模式

编译时绑定 vs 运行时发现

维度OpenClaw 编译时绑定Hermes 运行时发现
架构Channel 编译进二进制Plugin 运行时加载
优点类型安全,零配置启动灵活扩展,用户可自定义
缺点添加平台需 rebuild依赖解析复杂
平台数14 channels30+ platforms
语言TypeScriptPython
典型场景SaaS 产品,平台固定开源框架,用户自定义

4.2 OpenClaw 的 14 Channel 架构

OpenClaw

Channel 分类

类别平台特点
即时通讯Telegram, Discord, WhatsApp, Signal, Slack, iMessage, Matrix, IRC双向消息,富文本,reaction
中国企业飞书, 企业微信, QQ, LINE国内合规,审批流
社交/其他Nostr, WeChat, Google Chat特殊协议适配

统一消息模型:所有平台的消息被抽象为统一的 Message 对象,Agent 只需要处理一种格式,Channel 插件负责翻译。

4.3 Hermes 的 30+ Platform Gateway

Hermes

Gateway 平台矩阵

类别平台
即时通讯Telegram, WhatsApp, Signal, Discord, Slack, Matrix, Mattermost, iMessage (BlueBubbles)
中国企业飞书, 企业微信, 微信, 钉钉, QQ Bot, 腾讯元宝
邮件/短信Email, SMS
智能家居Home Assistant
API/WebhookAPI Server, Webhook
开发工具CLI (hermes), TUI (Ink/React), ACP (VS Code/Zed/JetBrains)

运行时发现机制:Hermes 在启动时扫描已安装的 plugin 包,自动注册可用的 Gateway。不需要修改代码,pip install hermes-telegram 就能添加 Telegram 支持。

4.4 平台适配的核心挑战

平台差异处理矩阵

挑战描述解决方案
消息长度限制Telegram 4096, Discord 2000, WhatsApp 65536自动分段 + "续" 标记
Markdown 支持Discord 部分支持, WhatsApp 不支持, Telegram 支持平台感知的格式降级
富媒体图片/文件/语音/视频 的发送方式各异统一 Media 接口 + 适配器模式
交互组件Discord buttons, Telegram inline keyboard抽象 Interaction 模型
ReactionEmoji 反应的 API 完全不同统一 react() 接口
速率限制每个平台有不同的 rate limitPer-channel rate limiter
消息格式回复/转发/引用的语义不同统一 ReplyModel
架构启示:多平台支持的关键不是"支持多少平台",而是"消息模型有多统一"。OpenClaw 和 Hermes 之所以能支持 14-30+ 平台,是因为它们在核心层做了充分的消息抽象。你只需要实现一个 Channel adapter 就能接入新平台。

5. 可观测性:监控、追踪与调试

Agent 在生产环境中最让人头疼的问题是:它为什么做了这个决定? 没有可观测性,你就是在黑箱运维。

5.1 可观测性三支柱在 Agent 中的映射

传统三支柱 → Agent 三支柱

传统Agent 场景关键数据
Metrics (指标)Token 使用量、工具调用频率、成功率tokens_per_turn, tool_call_count, error_rate
Traces (追踪)Agent 决策链、工具调用链、思考过程reasoning_trace, tool_chain, llm_io
Logs (日志)消息收发、配置变更、异常堆栈message_log, config_change, exception

5.2 AutoGPT — 最完善的生产监控

AutoGPT

AutoGPT 是唯一一个集成了完整生产监控栈的项目:

监控基础设施

工具用途实现
PrometheusMetricsexecution_manager_active_runs, pool_size, utilization_ratio
Sentry错误追踪异常自动上报,堆栈追踪
LangfuseLLM 可观测Prompt 版本管理,trace 追踪
RabbitMQ任务队列图执行任务的持久化队列
Redis事件总线跨进程事件广播
LaunchDarklyFeature Flags非本地环境的特性开关
Stripe计费按用量计费 / credits
# Prometheus metrics
active_runs_gauge = Gauge("execution_manager_active_runs", "Number of active graph runs")
pool_size_gauge = Gauge("execution_manager_pool_size", "Maximum number of graph workers")
utilization_gauge = Gauge("execution_manager_utilization_ratio", ...)

5.3 OpenClaw 的可观测性设计

OpenClaw

Trajectory 自监控

OpenClaw 有一套独特的自监控机制——Trajectory 导出

openclaw sessions export-trajectory events.jsonl 可视化 Dashboard

Trajectory 包含

这种设计让运维可以回放任何一次 Agent 决策的完整上下文——不仅是结果,还有"为什么"。

5.4 PydanticAI 的 OpenTelemetry 集成

PydanticAI

原生 OTel 支持

PydanticAI 是唯一原生集成 OpenTelemetry 的项目:

这是最"标准"的可观测性实现——不造轮子,直接用业界标准。

5.5 可观测性成熟度对比

项目MetricsTracesLLM 追踪错误追踪自监控
AutoGPT✅ Prometheus✅ Langfuse✅ Sentry⚠️
OpenClaw⚠️ 基础✅ Trajectory✅ API I/O⚠️✅ Dashboard
PydanticAI✅ OTel✅ OTel⚠️✅ OTel
OpenHands⚠️✅ Events⚠️⚠️✅ StuckDetector
其他⚠️ 日志
选择建议:如果你只需要基础的 LLM 可观测,用 PydanticAI + OTel 最省力。如果需要完整的 SaaS 监控,参考 AutoGPT 的 Prometheus + Sentry + Langfuse 组合。如果需要决策回放能力,参考 OpenClaw 的 Trajectory 导出。

6. 配置管理与热更新

生产环境中,你不能每次改配置都重启服务。Agent 的配置管理需要解决三个问题:分层、热更新、审计

6.1 OpenClaw 的配置热更新

OpenClaw

Gateway 配置系统

OpenClaw 使用 gateway 工具进行配置管理,支持热更新:

关键设计config.patch 优先热重载,只有当配置变更涉及核心架构(如端口、数据库连接)时才触发安全重启。这保证了大部分配置变更零停机。

6.2 AutoGPT 的 Feature Flags

AutoGPT

LaunchDarkly 集成

AutoGPT 在非本地环境使用 LaunchDarkly 的 Feature Flags:

这是 SaaS 化 Agent 平台的必备能力——你不能因为一个功能变更就让所有用户重启。

6.3 Hermes 的分层上下文文件

Hermes

SOUL.md + AGENTS.md + USER.md 三层配置

┌──────────────────────────────────────────────────┐ │ Layer 1: SOUL.md (身份层) │ │ - Agent 的核心人格、行为准则 │ │ - 很少变更,类似于 "宪法" │ │ - 修改需通知用户 (Hermes 的设计约定) │ ├──────────────────────────────────────────────────┤ │ Layer 2: AGENTS.md (行为层) │ │ - 工作流程、工具偏好、命名约定 │ │ - 随使用习惯逐步演化 │ │ - 可由 Agent 自己更新 │ ├──────────────────────────────────────────────────┤ │ Layer 3: USER.md (用户层) │ │ - 用户偏好、时区、项目上下文 │ │ - 频繁更新 │ │ - 由 Agent 在对话中学习并更新 │ └──────────────────────────────────────────────────┘
配置分层原则:变更频率低的放底层(身份),变更频率高的放顶层(状态)。底层变更需要审批和通知,顶层变更可以自动化。这与软件的配置分层(环境 → 服务 → 实例)是同一个思路。

7. 凭证与密钥管理

Agent 的一大特点是它需要访问大量外部服务——LLM API、搜索 API、消息平台、数据库……每个服务都需要凭证。如何安全管理这些凭证是生产环境的硬性要求。

7.1 Hermes 的 Credential Pool — 最佳实践

Hermes

Credential Pool + Rate Limit Guard

┌───────────────────────────────────────────────────────────────┐ │ Credential Pool │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ Key #1 │ │ Key #2 │ │ Key #3 │ ... │ Key #N │ │ │ │ OpenAI │ │ OpenAI │ │ Anthropic│ │ Google │ │ │ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ │ │ │ │ │ ┌────┴────────────┴────────────┴──────────────────┴────┐ │ │ │ Rate Limit Guard │ │ │ │ │ │ │ │ • 追踪每个 key 的 RPM / TPM / TPD │ │ │ │ • 当 key 接近限流 → 自动切换到下一个 │ │ │ │ • 当所有 key 都限流 → 等待 + 退避 │ │ │ │ • 支持 per-provider 和 per-key 的限流策略 │ │ │ └───────────────────────────────────────────────────────┘ │ │ │ │ 自动轮换策略: │ │ 1. Round-robin (均匀分配) │ │ 2. Least-recently-used (避免单 key 热点) │ │ 3. Capacity-based (选剩余额度最多的) │ └───────────────────────────────────────────────────────────────┘

7.2 OpenClaw 的 Credential Rotation

OpenClaw

OpenClaw 将 credential rotation 作为 failover 的一环:

主 key 请求 429 RateLimit 切换备用 key 继续请求 如果也限流 Provider 降级

与 Hermes 不同,OpenClaw 的 credential 管理更简单——它是 failover 链的一部分,而不是独立的 Pool。

7.3 密钥安全最佳实践

从 20 个项目提炼的密钥管理原则

原则做法反面教材
不硬编码环境变量 / Vault / Secrets Manager代码里写 api_key = "sk-..."
最小权限每个 key 只授予必要权限用 admin key 做 read-only 请求
多 key 分散Credential Pool 避免单点只用一个 key,限流就挂
速率感知Rate Limit Guard 追踪用量暴力重试直到 429
日志脱敏日志中自动 redact key把完整 API key 打到日志里
自动轮换定期或按需更换 key一个 key 用三年

8. 速率限制与成本控制

Agent 是 token 消耗大户。一个生产级 Agent 每天可能消耗数百万 token,成本控制不是可选项,而是必需品。

8.1 Token 成本模型

Agent 单轮对话的 Token 消耗构成

一次 Agent 调用的 Token 消耗分解: ┌─────────────────────────────────────────────────────┐ │ Input Tokens (大头,占 60-80%) │ │ │ │ ┌─────────────────────────────┐ │ │ │ System Prompt (~36K chars) │ ← 缓存可省 │ │ │ - 身份 + 工具 + 技能 │ │ │ │ - Stable Prefix (可缓存) │ ← Cache Boundary │ │ ├─────────────────────────────┤ │ │ │ Conversation History │ ← 压缩可省 │ │ │ - 完整历史 或 摘要 │ │ │ ├─────────────────────────────┤ │ │ │ Memory / Context Files │ ← 选择性注入可省 │ │ │ - MEMORY.md, daily notes │ │ │ └─────────────────────────────┘ │ ├─────────────────────────────────────────────────────┤ │ Output Tokens (小头,占 20-40%) │ │ │ │ ┌─────────────────────────────┐ │ │ │ Thinking / Reasoning │ ← 省不了,但可控制 │ │ ├─────────────────────────────┤ │ │ │ Text Response │ │ │ ├─────────────────────────────┤ │ │ │ Tool Calls (JSON) │ │ │ └─────────────────────────────┘ │ └─────────────────────────────────────────────────────┘ 省钱三剑客: 1. Cache Boundary → Input 缓存 → 省 50%+ input 成本 2. Context Compression → 历史压缩 → 省 30-60% input token 3. Model Routing → 简单任务用小模型 → 省 80%+ output 成本

8.2 各项目的成本控制策略

项目策略机制估算节省
OpenClawPrompt 缓存Cache Boundary + LRU50%+ input 成本
HermesFork 缓存复用Review fork 继承 cached prompt~26% 总成本
OpenHands上下文压缩LLMSummarizingCondenser30-60% input token
AutoGPT计费系统Stripe + Credits商业变现
SWE-agent输出解析优化8 种解析器减少 retry减少无效 LLM 调用

8.3 模型路由——最被低估的成本优化

按任务复杂度路由到不同模型

# 概念实现:模型路由器
class ModelRouter:
    """根据任务复杂度选择最经济的模型"""

    def route(self, task: str, tools: list, history_len: int) -> str:
        # 简单问答 → 小模型
        if not tools and history_len < 5:
            return "gpt-4o-mini"     # $0.15/1M input

        # 需要工具调用 → 中等模型
        if len(tools) <= 3:
            return "claude-sonnet"    # $3/1M input

        # 复杂推理 + 多工具 → 旗舰模型
        if len(tools) > 5 or "debug" in task:
            return "claude-opus"      # $15/1M input

        # 默认中等
        return "claude-sonnet"

# 成本对比:
# 全部用 opus:  $15 × 每次请求 = 💸💸💸
# 路由策略:     80% sonnet + 15% mini + 5% opus = 省 70%+
成本优化优先级:Cache Boundary(投入产出比最高)→ 上下文压缩(效果显著)→ 模型路由(长期最大节省)→ 工具结果缓存(特定场景有效)。不要一上来就优化模型路由——先把缓存做好。

9. 部署架构:从本地到云原生

Agent 的部署架构决定了它的可靠性和可扩展性。从单进程到微服务,每种架构都有适用场景。

9.1 四种部署架构

部署架构演进

Level 1: 单进程 (开发/个人用) ┌──────────────────────────────────────────┐ │ python main.py │ │ ┌──────┐ ┌──────┐ ┌──────┐ │ │ │ Agent │ │ LLM │ │Tools │ │ │ └──────┘ └──────┘ └──────┘ │ │ 代表: Smolagents, PydanticAI │ └──────────────────────────────────────────┘ ↓ 需要更多平台/并发 Level 2: Gateway 模式 (小团队) ┌──────────────────────────────────────────┐ │ Gateway Process │ │ ┌────────┐ ┌────────┐ ┌────────┐ │ │ │Channel 1│ │Channel 2│ │Channel N│ │ │ └────┬────┘ └────┬────┘ └────┬────┘ │ │ └──────┬─────┘────────────┘ │ │ ↓ │ │ ┌──────────┐ │ │ │ Agent │ ← 单进程,事件循环 │ │ └──────────┘ │ │ 代表: OpenClaw, Hermes │ └──────────────────────────────────────────┘ ↓ 需要更高可用性 Level 3: 服务化 (中型团队) ┌──────────────────────────────────────────┐ │ API Gateway → Agent Service (×N) │ │ ┌──────────┐ ┌──────────┐ │ │ │ Agent #1 │ │ Agent #2 │ ... │ │ └─────┬────┘ └─────┬────┘ │ │ └──────┬───────┘ │ │ ┌────┴────┐ │ │ │ Redis │ ← 事件总线/状态 │ │ └─────────┘ │ │ 代表: AutoGPT (RabbitMQ + Redis) │ └──────────────────────────────────────────┘ ↓ 需要 SaaS 化 Level 4: 云原生 (企业) ┌──────────────────────────────────────────┐ │ Load Balancer │ │ ┌──────────┐ ┌──────────┐ │ │ │ K8s Pod 1 │ │ K8s Pod N │ │ │ │ Agent Svc │ │ Agent Svc │ │ │ └─────┬────┘ └─────┬────┘ │ │ ┌─────┴──────────────┴─────┐ │ │ │ Message Queue (SQS) │ │ │ ├──────────────────────────┤ │ │ │ State Store (DynamoDB) │ │ │ ├──────────────────────────┤ │ │ │ Observability Stack │ │ │ │ (Prometheus+Sentry+OTel)│ │ │ └──────────────────────────┘ │ │ 代表: AutoGPT Cloud │ └──────────────────────────────────────────┘

9.2 OpenClaw 的 Gateway 架构

OpenClaw

Event-Driven Gateway

┌───────────────────────────────────────────────────────┐ │ OpenClaw Gateway │ │ │ │ ┌─────────────┐ ┌──────────────┐ │ │ │ Channel │ │ Agent Core │ │ │ │ Adapters │───→│ (Event Loop) │ │ │ │ (14个) │←───│ │ │ │ └─────────────┘ └──────┬───────┘ │ │ │ │ │ ┌──────┴───────┐ │ │ │ Extensions │ │ │ │ (150+ 插件) │ │ │ └──────────────┘ │ │ │ │ 关键特性: │ │ • 单进程事件驱动,资源消耗低 │ │ • Channel adapter 异步 I/O │ │ • Sub-agent spawn/run/yield 异步生命周期 │ │ • Compaction 自动上下文压缩 │ │ • 热更新配置 (config.patch) │ └───────────────────────────────────────────────────────┘

9.3 OpenHands 的 Sandbox 架构

OpenHands

Docker Sandbox 隔离

OpenHands 的生产部署亮点是 Docker sandbox 隔离:

对话工厂模式LocalConversation (进程内) vs RemoteConversation (连接 agent server),根据工作区类型自动路由。

9.4 部署决策树

你的 Agent 需要怎么部署? 个人使用/开发调试 → Level 1: 单进程 (python main.py / npm start) → 简单,够用 需要多平台接入 (Telegram + Discord + ...) → Level 2: Gateway 模式 (OpenClaw / Hermes) → 单进程事件驱动,低资源 需要高可用/多租户 → Level 3: 服务化 (AutoGPT 模式) → 消息队列 + 多实例 + 共享状态 需要 SaaS 化/企业级 → Level 4: 云原生 (K8s + 全套监控) → 完整运维栈 注意: 不要过度架构!Level 2 已经能支撑数千用户。

10. 跨项目生产级成熟度评估

20 个项目的生产级特性评分

项目缓存Failover多平台可观测密钥管理成本控制部署综合
OpenClaw⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐生产级
Hermes⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐生产级
AutoGPT⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐准生产
OpenHands⭐⭐⭐⭐⭐⭐⭐⭐准生产
LangGraph⭐⭐⭐⭐⭐⭐准生产
PydanticAI⭐⭐⭐开发级
CrewAI⭐⭐开发级
SWE-agent⭐⭐⭐⭐开发级
其他 12 个开发级

⭐⭐⭐ = 业界最佳水平 | ⭐⭐ = 可用 | ⭐ = 基础/缺失

生产级
2 个
准生产
3 个
开发级
15 个
核心洞察:20 个项目中,只有 2 个是真正的生产级部署。大部分 Agent 框架还停留在"能跑起来"的阶段,缺少缓存、failover、密钥管理这些生产必需品。如果你的 Agent 要上生产,从 OpenClaw 和 Hermes 学习,而不是从研究框架。

11. 实战清单:为你的 Agent 加持生产级特性

根据 20 个项目的源码分析,以下是按优先级排序的生产级改造清单:

11.1 P0 — 不做就别上生产

🚨 必须实现

#特性参考项目实现要点
1LLM 重试 + 指数退避OpenHands RetryMixin只对瞬态错误重试 (429/503/ConnectionError),初始 1s,因子 2-8,加 jitter
2Provider 降级OpenClaw至少 2 个 provider,主挂切备。40+ provider 最佳,3 个够用
3Cache BoundaryOpenClaw系统提示词分 stable/volatile,确保 provider prefix cache 命中
4上下文压缩OpenHands Condenser对话超过 N 轮自动摘要,固定 token 窗口
5密钥不硬编码所有项目环境变量 / .env / Secrets Manager,绝对不要出现在代码里

11.2 P1 — 显著提升可靠性

⚡ 强烈建议

#特性参考项目实现要点
6Credential PoolHermes多 key 轮换 + 速率追踪,429 自动切下一个 key
7模型降级OpenHandsOpus 挂 → Sonnet → Haiku,用户可配置策略
8Stuck DetectionOpenHands检测循环/重复/无进展,自动 break 或换策略
9错误追踪AutoGPT Sentry异常自动上报,堆栈追踪,不靠用户反馈
10健康检查标准实践/health 端点,定期检查 LLM 连通性

11.3 P2 — 长期运营必备

📊 逐步添加

#特性参考项目实现要点
11Token 用量监控OpenClaw Trajectoryper-turn token 计量,成本可视化
12配置热更新OpenClaw运行时修改配置,不需要重启
13LLM 追踪AutoGPT Langfuse记录完整 prompt → response,可回放决策
14多平台适配OpenClaw / Hermes统一消息模型 + Channel adapter
15Feature FlagsAutoGPT灰度发布、A/B 测试、紧急 kill switch

11.4 快速实现代码参考

P0 #1: 重试 + 指数退避 (5 分钟实现)

import asyncio
import random
from typing import TypeVar, Callable

T = TypeVar('T')

# 瞬态错误 — 可以重试
TRANSIENT_ERRORS = (ConnectionError, TimeoutError)

async def llm_call_with_retry(
    fn: Callable[..., T],
    max_retries: int = 5,
    base_delay: float = 1.0,
    backoff_factor: float = 2.0,
    max_delay: float = 60.0,
) -> T:
    """带指数退避 + jitter 的 LLM 调用重试"""
    for attempt in range(max_retries + 1):
        try:
            return await fn()
        except TRANSIENT_ERRORS as e:
            if attempt == max_retries:
                raise  # 重试耗尽,抛出

            # 指数退避 + 随机 jitter (防惊群)
            delay = min(base_delay * (backoff_factor ** attempt), max_delay)
            jitter = random.uniform(0, delay * 0.1)
            await asyncio.sleep(delay + jitter)
        except Exception:
            raise  # 非瞬态错误,不重试

P0 #3: Cache Boundary (15 分钟实现)

import hashlib

class PromptCacheBoundary:
    """系统提示词缓存分割点"""

    def __init__(self):
        self._stable_hash: str | None = None
        self._stable_content: str | None = None

    def build_system_prompt(
        self,
        stable_parts: dict,   # 跨 turn 不变的部分
        volatile_parts: dict,  # 每 turn 重建的部分
    ) -> str:
        # 组装 stable prefix
        stable = "\n".join(
            f"## {k}\n{v}" for k, v in stable_parts.items()
        )

        # 验证 stable 没有意外变化
        current_hash = hashlib.sha256(stable.encode()).hexdigest()
        if self._stable_hash and current_hash != self._stable_hash:
            # Stable 部分变了!prefix cache 会失效
            # 这可能是故意的(配置更新),记录一下
            import warnings
            warnings.warn("Stable prefix changed — cache boundary reset")

        self._stable_hash = current_hash
        self._stable_content = stable

        # 组装 volatile suffix
        volatile = "\n".join(
            f"## {k}\n{v}" for k, v in volatile_parts.items()
        )

        # 关键: stable 在前, volatile 在后
        # 这样 LLM provider 的 prefix cache 才能命中
        return f"{stable}\n\n{volatile}"

# 用法:
cache_boundary = PromptCacheBoundary()

# 每 turn:
system_prompt = cache_boundary.build_system_prompt(
    stable_parts={
        "identity": agent_identity,       # 不变
        "tools": tool_definitions,        # 不变
        "skills": skill_content,          # 不变
    },
    volatile_parts={
        "memory": current_memory,         # 每 turn 可能变
        "runtime": runtime_context,       # 每 turn 变
        "conversation_summary": summary,  # 每 turn 变
    },
)

P1 #6: Credential Pool (20 分钟实现)

import time
from dataclasses import dataclass, field

@dataclass
class Credential:
    key: str
    provider: str
    rpm_limit: int = 60        # requests per minute
    tpm_limit: int = 100_000   # tokens per minute
    last_used: float = 0
    request_count: int = 0
    token_count: int = 0

class CredentialPool:
    """多 key 凭证池 + 速率追踪"""

    def __init__(self):
        self._credentials: list[Credential] = []
        self._window = 60  # 速率追踪窗口 (秒)

    def add(self, key: str, provider: str, **limits):
        self._credentials.append(
            Credential(key=key, provider=provider, **limits)
        )

    def acquire(self, provider: str | None = None) -> Credential:
        """获取一个可用的 credential"""
        now = time.time()
        candidates = self._credentials

        if provider:
            candidates = [c for c in candidates
                          if c.provider == provider]

        # 筛选未限流的 credential
        available = []
        for c in candidates:
            # 清除过期窗口的计数
            if now - c.last_used > self._window:
                c.request_count = 0
                c.token_count = 0

            # 检查是否还有额度
            if (c.request_count < c.rpm_limit * 0.8 and
                c.token_count < c.tpm_limit * 0.8):
                available.append(c)

        if not available:
            raise RuntimeError("All credentials rate-limited")

        # 选最近最少使用的 (避免热点)
        selected = min(available, key=lambda c: c.last_used)
        selected.last_used = now
        selected.request_count += 1
        return selected

    def report_tokens(self, key: str, tokens: int):
        """上报 token 使用量"""
        for c in self._credentials:
            if c.key == key:
                c.token_count += tokens
                break

# 用法:
pool = CredentialPool()
pool.add("sk-key1", "openai", rpm_limit=60)
pool.add("sk-key2", "openai", rpm_limit=60)
pool.add("sk-ant-key3", "anthropic", rpm_limit=50)

cred = pool.acquire(provider="openai")
# → 自动选择使用最少的 key

🔗 相关阅读

本页内容基于 20 个 Agent 项目的源码分析,提炼生产级特性的设计模式和实现细节。
最后更新: 2026-05-17 | ← 返回 Agent 研究站