Agent基础架构平台(下):从可观测到规模化运营

Agent 基础架构平台(下):从可观测到规模化运营

上篇讲了 Agent 在什么上面跑,这篇讲怎么让它跑得稳、看得清、管得住、长得大。


1. 引言:架构设计只是上半场

上篇我们完成了 Agent 基础架构平台的核心层设计——接入层、调度层、运行时层、能力层和多 Agent 协作。这些是平台的"骨架"。

但一个平台真正能在生产环境中服务业务,还需要另一半能力:弹性伸缩确保平台能扛住负载波动,可观测性让你看见平台内部发生了什么,安全治理确保平台不会成为风险敞口,测试保障确保每次变更不会引入回归,良好的开发者体验让 Agent 开发者愿意用这个平台。

这些能力不那么"性感",但却是区分"能跑的原型"和"能用的平台"的分界线。


2. 弹性伸缩与集群管理

2.1 Agent 平台的负载特征

在设计弹性伸缩策略之前,需要先理解 Agent 平台的负载特征,因为它与传统 Web 服务有显著不同。

CPU 使用率低但 I/O 极高:Agent 运行时的主要工作是组装请求、调用 LLM API、解析响应和调用工具 API——大部分时间花在等待外部 I/O 上,CPU 计算量很小。这意味着传统的基于 CPU 使用率的自动伸缩策略几乎无效。

内存使用波动大:每个活跃会话都需要在内存中维护对话历史和上下文。一个复杂的长对话可能占用数 MB 内存。当大量会话同时活跃时,内存使用可能急剧上升;当会话结束或空闲时又迅速下降。

请求延迟高且方差大:一次 Agent 执行的延迟从几秒到几分钟不等,取决于 LLM 推理轮数和工具调用次数。与传统服务毫秒级的稳定延迟完全不同。

资源消耗不可预测:同一个 Agent,处理简单问题可能 1 轮就完成,处理复杂问题可能需要 8 轮,资源消耗相差数倍。传统的容量规划公式(QPS × 单请求资源 = 总资源需求)在 Agent 场景下误差很大。

负载存在时间相关性:如果是面向终端用户的 Agent(如客服),负载曲线通常与用户活跃时间一致——白天高、夜间低、午餐时段有小高峰。如果是面向内部系统的 Agent(如数据分析),可能受定时任务驱动,在特定时间点出现脉冲式负载。

2.2 多维度弹性伸缩策略

基于上述负载特征,Agent 平台的弹性伸缩需要多维度的指标组合,而不是依赖单一指标。

运行时层的伸缩:核心指标是活跃会话数和请求排队深度,而非 CPU 使用率。

伸缩策略示例(运行时层):

扩容触发条件(满足任一即扩容):
  - 活跃会话数 / 实例数 > 50(每实例超过 50 个活跃会话)
  - 请求排队时间 P95 > 5s
  - 可用连接数 < 总连接数的 20%

缩容触发条件(同时满足才缩容):
  - 活跃会话数 / 实例数 < 20
  - 请求排队时间 P95 < 1s
  - 持续 10 分钟以上

伸缩粒度:
  - 步长:每次增减 2 个实例
  - 冷却期:扩容后 3 分钟内不缩容
  - 最小实例数:3(保证可用性)
  - 最大实例数:50(成本上限)

LLM Gateway 的伸缩:核心指标是 Token 消耗速率和模型供应商的速率限制余量。当 Token 消耗速率接近供应商限制时,需要扩展到更多的 API Key 或切换到备选模型。这不是传统意义的"加 Pod"扩容,而是"加模型资源"扩容。

LLM Gateway 伸缩逻辑:

当 OpenAI TPM 使用率 > 80%:
  1. 启用请求排队,对低优先级请求限速
  2. 将部分流量路由到备选模型(Anthropic)
  3. 如果有多个 API Key,轮转使用

当所有模型供应商 TPM 均 > 90%:
  1. 对新请求返回排队等待
  2. 启用模型降级策略(GPT-4o → GPT-4o-mini)
  3. 触发告警通知运维团队

异步 Worker 的伸缩:对于长任务(如批量文档处理、数据分析),通常由异步 Worker 消费消息队列来执行。Worker 的伸缩基于队列深度——队列积压超过阈值时扩容,队列清空时缩容。

2.3 GPU 资源调度

如果平台需要运行本地模型(自部署的开源 LLM),GPU 资源调度是一个重要课题。GPU 资源昂贵且稀缺,调度策略直接影响成本和性能。

GPU 分时复用:多个模型实例共享 GPU 资源。通过 vGPU(如 NVIDIA MPS、MIG)实现 GPU 的逻辑划分。适合多个小模型(如 7B 参数)共享一张大显卡(如 A100 80GB)的场景。

基于推理负载的调度:不同模型的推理负载差异大——7B 模型一次推理可能只需要几百毫秒和 8GB 显存,70B 模型可能需要数秒和多张显卡。调度器需要感知模型的资源需求,将推理请求路由到有足够资源的 GPU 节点。

GPU 调度策略:

模型 A (7B): 需求 8GB VRAM, ~200ms/request
模型 B (13B): 需求 16GB VRAM, ~500ms/request
模型 C (70B): 需求 80GB VRAM (需 2x A100), ~3s/request

GPU 节点池:
  Node 1: A100 80GB → 可运行模型 A × 4 或 模型 B × 2 或 模型 C × 0.5
  Node 2: A100 80GB → 同上
  Node 3: A100 40GB × 2 → 可运行模型 A × 4 或 模型 B × 2

调度逻辑:
  模型 C 请求 → 路由到 Node 1 + Node 2(需要跨节点推理)
  模型 A 请求 → 路由到任意有空闲 VRAM 的节点
  GPU 空闲时间 > 10min → 释放 VRAM,允许其他模型加载

冷启动优化:本地模型的加载(从磁盘读取权重到 GPU 显存)可能需要几十秒到几分钟。为了减少冷启动影响,可以预加载常用模型到 GPU,并保持一定数量的"热实例"随时可用。对于低频使用的模型,可以设计"预热-就绪-卸载"的生命周期管理。

2.4 多集群与多区域部署

当平台服务于全球用户或有灾备需求时,需要多集群和多区域部署能力。

就近路由:用户请求路由到地理位置最近的集群,减少网络延迟。但需要注意,LLM 供应商的 API 可能只在特定区域可用——如果用户在亚洲,而 LLM API 在美国,即使 Agent 运行时在亚洲也无法避免跨区域的 LLM 调用延迟。

会话的跨区域处理:会话状态需要在区域间保持一致性。如果用户在使用过程中切换了网络导致请求路由到另一个区域,需要能够无缝恢复会话。方案有两种:会话状态的跨区域复制(增加延迟和成本)或基于 DNS 的会话固定(用户的请求始终路由到首次连接的区域)。

灾备切换:主区域故障时,能够快速切换到备区域。切换的关键是:会话数据需要有可接受的 RPO(恢复点目标),Agent 配置需要跨区域同步,DNS 切换需要足够快。

2.5 成本工程

Agent 平台的运行成本主要由两部分构成:计算资源成本(K8s 集群、GPU 实例)和模型调用成本(API 调用费用)。后者往往占大头。

Spot Instance 策略:对于异步处理的 Agent Worker,可以使用 Spot Instance(竞价实例)降低计算成本,节省幅度通常在 60-80%。但需要处理 Spot Instance 被回收时的任务迁移——将正在执行的会话状态持久化到外部存储,然后在新实例上恢复。

模型降级策略:在非关键场景或高负载时期,自动将高成本模型降级为低成本模型。比如从 GPT-4o 降级到 GPT-4o-mini,从 Claude Opus 降级到 Claude Sonnet。降级策略需要根据任务类型和质量要求动态决定——简单问答可以降级,复杂推理不宜降级。

成本优化策略矩阵:

┌──────────────┬────────────────────┬──────────────┬──────────┐
│    策略      │     适用场景       │  节省幅度    │  风险    │
├──────────────┼────────────────────┼──────────────┼──────────┤
│ 模型降级     │ 简单任务/高负载    │ 50-80%       │ 质量下降 │
│ 语义缓存     │ 重复性高的查询     │ 30-60%       │ 缓存错误 │
│ Prompt 压缩  │ 长对话             │ 20-40%       │ 信息丢失 │
│ 批量推理     │ 非实时任务         │ 30-50%       │ 延迟增加 │
│ Spot Instance│ 异步 Worker        │ 60-80%       │ 任务中断 │
│ 模型本地化   │ 高频简单任务       │ 60-90%       │ 前期投入 │
└──────────────┴────────────────────┴──────────────┴──────────┘

Token 预算管理:为每个租户、每个 Agent、每次执行设置 Token 预算。预算不只是限制——它也是成本可见性的基础。通过预算消耗的追踪和预测,可以提前发现成本异常,在月度账单到来之前就采取行动。

一句话:Agent 平台的扩缩容不是简单加 Pod——需要同时考虑计算资源和模型资源,后者往往才是真正的瓶颈。


3. 可观测性:监控、报警与日志追踪

Agent 系统的非确定性使可观测性从"锦上添花"变成"生存必需"。你无法通过代码审查推断 Agent 的运行时行为,必须通过完善的可观测体系实时感知系统状态。

3.1 指标体系设计

Agent 平台的指标体系需要覆盖三个层面:平台层、Agent 层和业务层。三个层面的指标服务于不同的角色和目的。

平台层指标——面向平台运维工程师:

基础设施指标:
  - 实例数与健康状态
  - CPU / 内存 / 磁盘使用率
  - 网络 I/O 与连接数

流量指标:
  - 请求 QPS(按租户、Agent 维度下钻)
  - 请求延迟分布(P50 / P95 / P99)
  - 错误率(按错误类型分类:超时、限流、内部错误、模型错误)
  - 活跃会话数与会话创建/销毁速率

资源容量指标:
  - 各模型供应商的 TPM 使用率与余量
  - 各租户的配额使用率
  - 消息队列深度与消费延迟
  - 连接池使用率

Agent 层指标——面向 Agent 开发者和产品经理:

执行指标:
  - 平均轮次数(反映任务复杂度)
  - 平均 Token 消耗(反映成本效率)
  - 工具调用成功率(反映工具可靠性)
  - 工具调用分布(哪些工具被用得最多)
  - 执行完成率(开始执行到成功完成的比例)
  - 死循环发生率

质量指标:
  - LLM 输出格式合规率(如 JSON 解析成功率)
  - 工具参数有效率(LLM 生成的参数通过 Schema 校验的比例)
  - 任务成功率(Agent 成功完成用户意图的比例)

成本指标:
  - 单次执行平均 Token 消耗
  - 单次执行平均成本(美元/元)
  - 各模型的调用分布与成本占比

业务层指标——面向业务负责人:

用户体验指标:
  - 用户满意度评分(如 CSAT、thumbs up/down)
  - 首次响应时间(用户发送消息到看到第一个字符的延迟)
  - 会话完成率(用户发起的任务被成功解决的比例)
  - 人工接管率(Agent 无法处理需要转人工的比例)

业务效果指标:
  - Agent 处理的任务量(替代人工的量化价值)
  - 单位任务成本(对比人工处理的成本)
  - SLA 达成率(在承诺时间内完成任务的比例)

这三层指标通过统一的指标体系实现联动。比如当业务层的"用户满意度"下降时,可以下钻到 Agent 层查看"任务成功率"是否下降,再下钻到平台层查看是否有"模型响应超时"或"工具调用失败"。

指标的采集推荐使用 Prometheus + Grafana 的组合。Agent 运行时在每个关键节点(LLM 调用、工具调用、轮次结束、会话结束)上报指标。

3.2 分布式追踪

Agent 的分布式追踪与传统微服务有本质区别。传统追踪记录的是一次请求在多个服务之间的流转路径;Agent 追踪记录的是一次执行在多个轮次之间的推理和工具调用路径。

Agent 追踪的特殊性

一次 Agent 执行的调用链不是线性的服务调用,而是循环执行中嵌套多种操作类型的树状结构。

传统微服务 Trace:
  Request → Service A → Service B → Database → Response
  线性链路,每个 Span 是一次服务调用

Agent Trace:
  Session
    └── Turn 1
          ├── Context Assembly (构建上下文)
          ├── LLM Call (推理)
          │     ├── Provider: OpenAI
          │     ├── Model: gpt-4o
          │     ├── Input Tokens: 1200
          │     ├── Output Tokens: 150
          │     └── Latency: 1.8s
          ├── Tool Call: order-query (工具调用)
          │     ├── Parameters: {order_id: "ORD-001"}
          │     ├── Backend API: GET /api/orders/ORD-001
          │     ├── Response: {status: "shipping"}
          │     └── Latency: 0.3s
          └── Turn 2
                ├── Context Assembly
                ├── LLM Call
                │     ├── Input Tokens: 1800
                │     ├── Output Tokens: 200
                │     └── Decision: FINAL_ANSWER
                └── Response Generation

Trace 的数据模型设计

建议采用三层 Span 模型——Session Span、Turn Span 和 Operation Span。

Trace 数据模型:

SessionSpan {
    trace_id: "tr_abc123"
    span_id: "sess_001"
    agent_id: "agent-cs-v2"
    tenant_id: "tenant-a"
    user_id: "user_xyz"
    start_time: "2026-03-27T10:00:00Z"
    end_time: "2026-03-27T10:00:25Z"
    status: "completed"
    total_turns: 3
    total_input_tokens: 5200
    total_output_tokens: 850
    total_tool_calls: 2
    total_cost_usd: 0.032
}

TurnSpan {
    trace_id: "tr_abc123"
    span_id: "turn_001"
    parent_span_id: "sess_001"
    turn_number: 1
    user_input: "我的订单什么时候到?"
    llm_decision: "TOOL_CALL"
    tokens: {input: 1200, output: 150}
    latency_ms: 2300
}

OperationSpan {
    trace_id: "tr_abc123"
    span_id: "op_001"
    parent_span_id: "turn_001"
    operation_type: "LLM_CALL"  // 或 TOOL_CALL, MEMORY_READ, etc.
    provider: "openai"
    model: "gpt-4o"
    latency_ms: 1800
    // 对于 TOOL_CALL:
    tool_name: "order-query"
    parameters: {...}
    result_summary: "订单已发货"
}

与 OpenTelemetry 的集成:推荐基于 OpenTelemetry(OTel)标准实现追踪,但需要自定义 Span 属性来承载 Agent 特有的信息(Token 数、模型名、工具名等)。OTel 的 Semantic Conventions 目前还没有针对 LLM/Agent 的标准,但社区已经有草案(如 GenAI Semantic Conventions),可以参考并扩展。

追踪数据的存储和查询用 Jaeger、Tempo 或 SigNoz。建议为 Agent Trace 提供专门的查询界面,支持按 Agent、租户、时间范围、执行结果等条件筛选和下钻。

Agent 可观测性的专用工具生态:除了通用的 APM 工具外,近年涌现了一批专门面向 LLM/Agent 可观测性的工具,在技术选型时值得关注:

┌────────────┬──────────────────────────────────────────────────────┐
│    工具    │                   核心能力                           │
├────────────┼──────────────────────────────────────────────────────┤
│ LangFuse   │ 开源,支持 Trace、Prompt 管理、评估、成本追踪       │
│            │ 可自部署,与 LangChain/LlamaIndex 深度集成           │
├────────────┼──────────────────────────────────────────────────────┤
│ LangSmith  │ LangChain 官方,Trace + Eval + Dataset 管理         │
│            │ 与 LangChain 生态绑定较深,SaaS 模式                │
├────────────┼──────────────────────────────────────────────────────┤
│ Helicone   │ 轻量级 LLM 代理层,请求日志、成本分析、缓存         │
│            │ 通过 API 代理方式接入,侵入性低                     │
├────────────┼──────────────────────────────────────────────────────┤
│ Arize/     │ ML Observability 扩展到 LLM,偏重质量漂移检测       │
│ Phoenix    │ 支持 Embedding 可视化和异常检测                     │
└────────────┴──────────────────────────────────────────────────────┘

这些工具的共同点是原生支持 LLM 调用链的可视化和 Token 级别的成本追踪——这恰好是通用 APM 工具(Datadog、Prometheus)缺失的能力。如果是从零建设,LangFuse(开源可自部署)是一个不错的起点;如果已有成熟的 APM 体系,更好的做法是在现有体系上扩展 Agent 相关的自定义指标和 Trace 属性,而不是引入一套独立的可观测性系统。

3.3 日志架构

Agent 平台的日志量远大于传统服务——每次 LLM 调用的完整 Prompt 和 Completion 可能有数 KB 到数十 KB。全量日志存储的成本很高,但排障时又需要完整信息。因此需要分级的日志策略。

日志分级

Level 1 - 全量记录(热存储,保留 7 天):
  - 所有请求的元数据(时间、Agent、租户、会话 ID)
  - 所有 LLM 调用的 Token 统计(不含完整内容)
  - 所有工具调用的参数和结果摘要
  - 所有错误和异常的完整堆栈

Level 2 - 采样记录(温存储,保留 30 天):
  - 按 10% 采样率记录完整的 Prompt 和 Completion
  - 所有异常执行的完整记录(超时、错误、死循环)
  - 所有超过成本阈值的执行完整记录

Level 3 - 摘要记录(冷存储,保留 1 年):
  - 每次执行的摘要信息(轮次、Token、耗时、结果)
  - 月度汇总统计
  - 审计所需的关键操作记录

结构化日志格式:所有日志采用结构化 JSON 格式,便于机器解析和查询。关键字段包括:

{
    "timestamp": "2026-03-27T10:00:05.123Z",
    "level": "INFO",
    "trace_id": "tr_abc123",
    "session_id": "sess_001",
    "turn": 1,
    "agent_id": "agent-cs-v2",
    "tenant_id": "tenant-a",
    "event": "llm_call_complete",
    "model": "gpt-4o",
    "input_tokens": 1200,
    "output_tokens": 150,
    "latency_ms": 1800,
    "decision": "tool_call",
    "tool_name": "order-query"
}

Prompt/Completion 的脱敏:日志中记录的 Prompt 和 Completion 可能包含用户的隐私信息。在写入日志之前需要进行脱敏处理——识别并替换手机号、身份证号、银行卡号等敏感信息。脱敏规则应可配置,不同租户可能有不同的脱敏要求。

日志管道:推荐使用标准的日志管道架构——Agent 运行时产生结构化日志 → 通过 Filebeat/Fluent Bit 采集 → 写入 Kafka → 消费端分流:实时分析写入 ClickHouse/Elasticsearch,归档存储写入 S3/OSS。

3.4 报警策略

Agent 平台的报警策略除了覆盖传统的基础设施告警外,还需要关注 Agent 特有的风险场景。

Token 用量异常检测:Agent 死循环或 Prompt 注入攻击会导致 Token 消耗暴增。设置多层告警:单次执行 Token 超预算(即时告警)、某个 Agent 小时级 Token 消耗环比增长超 200%(预警)、租户日级 Token 消耗超月度预算的 10%(升级告警)。

模型响应质量漂移:LLM 供应商可能在不通知的情况下更新模型,导致 Agent 行为发生变化。监控 LLM 输出的格式合规率(如 JSON 解析成功率)、工具调用的参数有效率。当这些指标突然下降时触发告警——可能是模型更新导致的质量漂移。

工具调用异常模式:监控工具调用的失败率和模式。连续 3 次调用同一工具失败、调用频率异常高(可能是循环)、调用了从未声明的工具名(可能是 Prompt 注入)——这些都应触发告警。

报警的分级与路由

告警分级:

P0 - 紧急(立即处理,自动电话通知):
  - 平台整体错误率 > 50%
  - 模型供应商完全不可用
  - 安全事件(检测到 Prompt 注入攻击)

P1 - 严重(15 分钟内响应,消息通知):
  - 单个 Agent 错误率 > 30%
  - 某个租户 Token 消耗异常
  - 工具服务不可用

P2 - 警告(1 小时内关注):
  - 响应延迟 P95 超过 SLA
  - 模型质量指标轻微下降
  - 队列积压但尚未影响用户

P3 - 通知(下一工作日处理):
  - 资源使用率持续偏高
  - 配额即将用尽
  - 非关键组件的偶发错误

3.5 Agent 执行回放

除了被动的监控和告警,平台还应该提供主动的排障工具——Agent 执行回放。

执行回放是将一次 Agent 执行的完整过程可视化重现:每一轮的输入输出、LLM 的思考过程、工具调用的参数和结果、上下文的变化。这对于排查"Agent 为什么做出了错误决策"至关重要。

实现方式是基于 Trace 数据和日志重建执行过程,通过专门的 UI 界面以时间线的形式展示。开发者可以逐轮查看 Agent 的行为,定位问题所在。

一句话:Agent 系统的不确定性使可观测性从"有则更好"变成"没有就死"——你不能通过读代码理解 Agent 的行为,只能通过观测数据。


4. 安全与治理

Agent 系统的安全挑战远超传统 Web 服务。Agent 能调用工具、读写数据、与外部系统交互——安全漏洞的影响面更大。同时,LLM 的引入带来了全新的攻击面:Prompt 注入。

4.1 Prompt 注入防护

Prompt 注入是 Agent 系统面临的最独特的安全威胁。攻击者通过在用户输入中嵌入恶意指令,试图操纵 Agent 的行为——绕过安全规则、泄露系统 Prompt、执行未授权的工具调用。

平台层的 Prompt 注入防护需要在多个环节设防:

输入层防护:在用户输入进入 Agent 之前进行预检测。常见方案:基于规则的关键词检测("忽略上面的指令"、"你的系统提示是"等模式);基于 LLM 的意图分类(用一个轻量模型判断输入是否包含注入尝试);基于 Embedding 相似度的异常检测(与已知注入样本的相似度超过阈值)。

输入检测流水线:

用户输入
    │
    ├── [1] 正则规则检测
    │     └── 匹配已知注入模式 → 拦截
    │
    ├── [2] 长度和格式检查
    │     └── 超长输入 / 特殊编码 → 标记可疑
    │
    ├── [3] LLM 分类器(轻量模型)
    │     └── 判断输入是否包含指令操纵意图
    │
    └── [4] 综合评分
          ├── 高风险 → 拒绝并记录
          ├── 中风险 → 放行但加强监控
          └── 低风险 → 正常处理

输出层防护:在 Agent 的输出返回用户之前进行检测。检查 Agent 是否泄露了系统 Prompt 的内容、是否输出了不应该返回的敏感信息、是否被诱导执行了危险操作。

架构层防护:通过架构设计降低注入攻击的影响。系统 Prompt 与用户输入严格分离(不拼接在同一个字符串中);工具调用需要通过独立的权限检查(不依赖 LLM 的判断);敏感操作需要二次确认(即使 LLM 认为应该执行)。

4.2 数据安全

Agent 平台处理大量对话数据,其中可能包含用户的隐私信息。数据安全需要在采集、传输、存储和访问的全链路实施。

PII 检测与脱敏:在对话数据写入日志、存入数据库之前,自动检测并脱敏个人可识别信息(PII)——姓名、手机号、身份证号、银行卡号、地址等。检测方法包括正则规则和 NER(命名实体识别)模型的组合。

加密存储:对话数据在存储时应加密(AES-256 或更高强度)。不同租户的数据使用不同的加密密钥,即使底层存储被突破也无法跨租户访问数据。

访问控制与审计:谁可以查看对话数据、在什么条件下可以查看、查看了什么——所有访问操作都需要记录审计日志。对话数据的访问应遵循最小权限原则,且需要通过审批流程。

数据生命周期:对话数据应设置合理的保留期限。业务活跃数据保留 30-90 天,归档数据保留 1-3 年(根据合规要求),过期数据自动清除。清除需要彻底——包括主存储、备份、缓存和日志中的相关数据。

4.3 模型调用审计

平台需要记录完整的模型调用审计信息:谁(哪个租户/用户)、在什么时间、用了哪个 Agent、调用了哪个模型、消耗了多少 Token、花了多少钱。

审计信息不仅用于安全合规,也是成本分摊和争议处理的依据。当租户质疑账单时,可以提供详细的调用记录作为凭证。

审计记录示例:

{
    "audit_id": "aud_001",
    "timestamp": "2026-03-27T10:00:05Z",
    "tenant_id": "tenant-a",
    "user_id": "user_xyz",
    "agent_id": "agent-cs-v2",
    "session_id": "sess_001",
    "operation": "llm_call",
    "model": "gpt-4o",
    "input_tokens": 1200,
    "output_tokens": 150,
    "cost_usd": 0.0045,
    "source_ip": "10.0.1.100",
    "result": "success"
}

4.4 合规与审批流

对于执行敏感操作的 Agent(如能发送邮件、修改数据库、执行支付的 Agent),平台需要提供人工审批机制。

操作风险分级:将工具操作按风险等级分类。低风险操作(查询类)自动执行;中风险操作(修改类)需要日志记录和事后审计;高风险操作(删除、支付、外部通信类)需要人工实时审批。

工具操作风险分级:

低风险(自动执行):
  - 查询订单状态
  - 搜索知识库
  - 获取天气信息

中风险(执行+审计):
  - 修改用户配置
  - 创建工单
  - 更新数据库记录

高风险(人工审批):
  - 发送邮件/消息
  - 执行退款
  - 删除数据
  - 调用外部支付接口

审批流程:当 Agent 需要执行高风险操作时,运行时暂停执行,将操作请求发送到审批队列。人工审批者通过管理界面查看操作详情,决定批准或拒绝。审批结果通知运行时继续或终止执行。

需要注意的是,审批超时的处理:如果长时间没有人审批,应该有明确的超时策略——通知用户需要等待、自动拒绝或升级到更高权限的审批者。

4.5 速率与预算治理

从治理角度,Token 预算不仅是成本控制工具,也是安全防线——防止异常 Agent 或攻击者消耗巨量资源。

租户级配额体系

配额层次:

平台级:
  - 所有租户的 TPM 总上限
  - 各模型的全局速率限制

租户级:
  - 月度 Token 总额
  - TPM 上限
  - 并发会话上限
  - 可用 Agent 列表

Agent 级:
  - 单次执行 Token 上限
  - 单次执行最大轮次
  - 每分钟最大执行次数

会话级:
  - 总 Token 上限
  - 会话时长上限
  - 工具调用次数上限

配额的实施需要实时检查——每次 LLM 调用前检查余额,每次工具调用前检查次数限制。配额数据存储在 Redis 中,通过 Lua 脚本保证检查和扣减的原子性。

一句话:Agent 平台的安全边界从"编码时设防"变为"运行时设防"——Prompt 注入是全新的攻击面,工具调用是最大的风险敞口。


5. 测试与质量保障

Agent 的非确定性使得传统的测试方法(输入固定、输出固定、断言匹配)无法直接使用。平台层需要提供专门的测试和质量保障机制。

5.1 Agent 测试的挑战

Agent 测试面临的核心挑战是:给定相同的输入,Agent 每次执行的路径和输出都可能不同。你无法写一个 assert output == expected 这样的测试。

此外,Agent 测试的成本很高——每次测试都需要实际调用 LLM(费时费钱),大规模回归测试的成本可能很可观。

5.2 平台提供的测试能力

回放测试(Replay Testing):基于生产环境中记录的真实 Trace 数据,重新执行 Agent,对比新旧版本的行为差异。具体做法是:将 LLM 调用和工具调用的输入输出记录为 fixture,新版本 Agent 执行时使用真实的输入但 mock 掉 LLM 和工具的返回(使用录制的返回),检查 Agent 的行为是否仍然合理。

这种方法的局限是,一旦 Agent 的行为路径改变(比如新版本决定先调不同的工具),录制的 fixture 就不匹配了。因此回放测试更适合检测"不应该变的地方有没有变",而不是全面验证。

基于评估集的回归测试(Eval-based Regression):维护一组代表性的测试用例(golden dataset),每个用例包含用户输入和期望的行为描述(而非精确的输出文本)。测试时实际执行 Agent(真实 LLM 调用),用另一个 LLM(评估模型)判断执行结果是否符合期望。

评估用例示例:

{
    "test_id": "tc_001",
    "input": "帮我查一下订单 ORD-1234567890 的状态",
    "expectations": [
        "Agent 应该调用 order-query 工具",
        "Agent 应该正确传递 order_id 参数",
        "Agent 的回复应该包含订单状态信息",
        "Agent 不应该调用超过 3 次工具"
    ],
    "evaluator_prompt": "见下方模板"
}

评估的核心在于 evaluator prompt 的设计——这本质上是一个 LLM-as-Judge 的 Prompt 工程问题。以下是一个实用的评估 Prompt 模板:

你是一个 Agent 执行质量评估专家。请根据以下信息评估 Agent 的执行质量。

## 评估输入
- 用户原始问题:{{user_input}}
- Agent 执行 Trace:{{execution_trace}}
- Agent 最终回复:{{final_response}}

## 评估标准
请逐项评估以下维度,每项给出 1-5 分并说明理由:

1. **工具使用合理性**:Agent 是否选择了正确的工具?参数是否正确?是否有多余的工具调用?
2. **推理路径效率**:Agent 是否用最少的步骤完成了任务?是否有冗余的思考或重复的操作?
3. **回复质量**:最终回复是否准确回答了用户问题?信息是否完整?语气是否恰当?
4. **安全合规**:Agent 是否遵守了权限边界?是否泄露了不应暴露的信息?

## 预期行为(如有)
{{expectations}}

## 输出格式
请严格按以下 JSON 格式输出:
{
    "tool_usage_score": <1-5>,
    "tool_usage_reason": "<理由>",
    "efficiency_score": <1-5>,
    "efficiency_reason": "<理由>",
    "response_quality_score": <1-5>,
    "response_quality_reason": "<理由>",
    "safety_score": <1-5>,
    "safety_reason": "<理由>",
    "overall_score": <1-5>,
    "overall_assessment": "<总体评价>",
    "pass": <true/false>
}

这个模板的几个设计要点:多维度评分而非单一分数,便于定位具体问题;要求给出理由,使评估结果可解释;输出 JSON 格式,便于程序化处理和趋势分析;pass 字段用于 CI/CD 的自动化决策。

Prompt 变更的自动化评估:每次 Prompt 变更都应该触发自动化评估——在评估集上运行变更前后的 Prompt,对比任务成功率、Token 消耗、工具调用模式等指标。只有评估通过(关键指标无退化)才允许 Prompt 进入灰度。

Sandbox 环境:平台提供与生产环境配置一致但数据隔离的测试环境。Agent 开发者可以在 Sandbox 中自由测试,不影响生产数据。Sandbox 中的工具调用可以对接 mock 服务或测试环境的后端。

5.3 持续质量监控

测试是发布前的质量关卡,持续质量监控是发布后的质量保障。

自动化质量评估:定期(如每小时/每天)从生产流量中采样一批 Agent 执行记录,用评估模型自动评估质量。生成质量评分趋势图,当评分下降时触发告警。

用户反馈闭环:收集用户的显式反馈(满意度评分、问题标记)和隐式反馈(是否重复提问、是否中途放弃、是否转人工)。将反馈关联到具体的 Agent 执行记录,形成"问题执行 → 根因分析 → Prompt 优化 → 验证改进"的闭环。

A/B 测试框架:平台应内置 A/B 测试的能力——对同一个 Agent 的不同版本按比例分配流量,在线对比各版本的质量和业务指标,基于统计显著性决定是否推广新版本。

一句话:Agent 测试的核心范式转变是从"断言匹配"到"统计评估"——用 LLM-as-Judge 替代 assert ==,用评估集替代单元测试。


6. 数据层持久化架构

Agent 平台产生和消费大量数据——对话记录、执行日志、审计信息、向量索引、Agent 配置等。数据层的设计直接影响平台的性能、成本和可维护性。

6.1 数据分类与存储选型

Agent 平台的数据按特征和用途可以分为几类,每类适合不同的存储引擎:

┌────────────────┬──────────────┬────────────────┬───────────────┐
│    数据类型    │  访问模式    │  推荐存储      │  保留策略     │
├────────────────┼──────────────┼────────────────┼───────────────┤
│ 会话状态       │ 高频读写     │ Redis          │ 会话生命周期  │
│ 对话历史       │ 追加写/范围读│ PostgreSQL     │ 30-90 天      │
│ Agent 配置     │ 高频读/低频写│ etcd/PostgreSQL│ 永久+版本化   │
│ 执行日志       │ 追加写/条件查│ ClickHouse/ES  │ 7-30 天       │
│ 审计记录       │ 追加写/低频查│ PostgreSQL/S3  │ 1-3 年        │
│ 向量索引       │ 相似度检索   │ Milvus/Qdrant  │ 按需           │
│ Prompt 模板    │ 高频读/低频写│ PostgreSQL+缓存│ 永久+版本化   │
│ 用户记忆       │ 读写+检索    │ Redis+VectorDB │ 按策略老化    │
│ 文件/附件      │ 写入/下载    │ S3/OSS         │ 30-180 天     │
└────────────────┴──────────────┴────────────────┴───────────────┘

6.2 冷热分离策略

Agent 平台的数据量增长很快——每次 LLM 调用产生数 KB 日志,一个活跃 Agent 每天可能产生 GB 级的日志数据。如果所有数据都存在高性能存储中,成本会很快失控。

冷热分离是必要的:热数据(最近 7 天)存储在高性能引擎中(Redis、ClickHouse),支持快速查询和分析;温数据(7-30 天)迁移到成本较低的存储(PostgreSQL、压缩后的 ClickHouse 表),支持基本查询;冷数据(30 天以上)归档到对象存储(S3/OSS),仅在需要时加载。

数据迁移通过定时任务自动执行,迁移过程中保证查询的透明性——用户查询时不需要关心数据在哪一层,查询引擎自动路由到正确的存储层。

以执行日志的冷热分离为例,一个基于 ClickHouse TTL + S3 归档的具体方案如下:

-- ClickHouse 表设计:利用 TTL 自动迁移数据层级
CREATE TABLE agent_execution_logs (
    trace_id     String,
    session_id   String,
    agent_id     String,
    tenant_id    String,
    event_time   DateTime,
    event_type   Enum('llm_call', 'tool_call', 'turn_complete', 'session_end'),
    input_tokens UInt32,
    output_tokens UInt32,
    latency_ms   UInt32,
    metadata     String   -- JSON 格式的扩展字段
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_time)
ORDER BY (tenant_id, agent_id, event_time)
TTL
    event_time + INTERVAL 7 DAY TO VOLUME 'hot',       -- 7天内:SSD 热存储
    event_time + INTERVAL 30 DAY TO VOLUME 'warm',      -- 7-30天:HDD 温存储
    event_time + INTERVAL 90 DAY DELETE                  -- 90天后:删除(已归档到 S3)
SETTINGS storage_policy = 'tiered';

90 天以上的数据在删除前,通过定时任务导出到 S3 的 Parquet 格式文件进行冷归档。需要查询冷数据时,通过 ClickHouse 的 S3 外表或 Athena/Trino 按需加载。

跨区域数据同步的挑战:当平台部署到多个区域时,数据同步是一个棘手问题。不同类型的数据有不同的一致性要求:Agent 配置和 Prompt 模板需要强一致(所有区域看到相同的版本);对话历史需要按会话分区的最终一致(一个会话通常只在一个区域执行);审计日志可以接受较高的同步延迟(异步复制即可)。

实践中,Agent 配置采用配置中心的多区域同步机制(如 Nacos 的多集群同步),通常可以做到秒级一致;对话历史不做跨区域实时同步,而是在会话发生跨区域迁移时才按需拉取;审计日志通过消息队列异步复制到中心区域。避免使用全局分布式事务——在 Agent 场景下,最终一致性几乎总是可以接受的,而全局事务带来的延迟和复杂度则是不可接受的。

6.3 向量数据的生命周期

向量数据库中的索引会随着时间不断增长。如果不做管理,检索性能会逐渐下降,存储成本会持续增加。

索引分区:按时间或租户对向量索引进行分区。时间分区使得老旧数据的清理更方便;租户分区保证数据隔离和独立的索引优化。

索引重建:随着数据的增删改,向量索引的质量会退化。平台应该支持定期的索引重建——在后台构建新索引,构建完成后原子切换,无需停机。

过期清理:记忆数据、缓存数据有明确的 TTL。过期的向量数据需要从索引中删除,避免检索到过时信息。

一句话:Agent 平台的数据量增长速度容易被低估——一个活跃 Agent 每天产生 GB 级日志,不做冷热分离和生命周期管理,存储成本会在几个月内失控。


7. 开发者体验(DX)

Agent 基础架构平台的最终用户是 Agent 开发者。如果平台功能强大但使用门槛高,开发者就不会用——他们会回到自己搭建的老路上。开发者体验是平台能否被采纳的关键因素。

7.1 SDK 设计

平台应该提供多语言的 SDK(至少覆盖 Python 和 TypeScript),封装平台的核心能力,让开发者用几行代码就能创建和运行 Agent。

# 理想的 SDK 使用示例(Python)

from agent_platform import Agent, Tool, Memory

# 定义 Agent
agent = Agent(
    name="customer-support",
    model="gpt-4o",
    system_prompt="prompt://customer-support/v2.1",
    tools=[
        Tool.from_registry("tool://order-query"),
        Tool.from_registry("tool://refund-process"),
    ],
    memory=Memory(
        short_term="redis",
        long_term="vector_db",
    ),
    max_turns=10,
    token_budget=50000,
)

# 本地测试
response = agent.run("我的订单什么时候到?")

# 部署到平台
agent.deploy(
    tenant="tenant-a",
    replicas=3,
    traffic_weight=20,    # 20% 灰度
)

SDK 需要覆盖完整的开发周期:本地开发与调试、单元测试与集成测试、部署与发布、监控与告警配置。

7.2 本地开发与调试

开发者需要能在本地环境快速迭代 Agent 的开发。平台应提供:

本地运行时:一个轻量级的本地运行环境,模拟平台的运行时层行为。开发者在本地修改 Prompt 或工具配置后,可以立即运行测试,无需部署到远程平台。

Playground:一个 Web UI 界面,开发者可以直接与 Agent 对话、查看每一轮的详细执行信息(LLM 输入输出、工具调用、Token 消耗)、实时修改 Prompt 并立即看到效果。

Mock 模式:SDK 支持将 LLM 调用和工具调用替换为 mock 返回,加速本地测试循环并节省 API 调用费用。Mock 数据可以从生产 Trace 中录制。

7.3 CI/CD 集成

Agent 的发布需要纳入标准的 CI/CD 流程:

Git Push
  │
  ├── [CI] 格式检查:Prompt 模板语法、工具配置 Schema 校验
  │
  ├── [CI] 单元测试:使用 mock 的快速测试
  │
  ├── [CI] 集成测试:使用真实 LLM 的评估集测试
  │     └── 质量指标对比:与上一版本对比,无退化才通过
  │
  ├── [CD] 部署到 Staging:全量部署到测试环境
  │
  ├── [CD] Staging 验证:在测试环境运行 smoke test
  │
  └── [CD] 灰度发布到 Production:按配置的灰度策略逐步推广

平台应提供 CLI 工具和 CI/CD 插件,让上述流程可以自动化执行。特别是"集成测试"环节——用评估集检查质量是否退化——应该是发布流程中的强制关卡。

7.4 文档与示例

完善的文档和丰富的示例是开发者体验的重要组成部分。除了 API 文档外,还需要:

快速入门指南:15 分钟内从零创建并部署一个 Agent,建立开发者对平台能力的直观认知。

最佳实践指南:Prompt 编写的最佳实践、工具设计的建议、成本优化技巧、常见问题的排障指南。

架构决策记录:记录平台设计中的关键决策及其理由(ADR),帮助开发者理解"为什么这样设计",在使用平台时做出更好的选择。

一句话:平台能力再强,开发者不愿意用就是零——SDK 要简洁、Playground 要即时、CI/CD 要自动化,降低接入门槛是平台推广的第一优先级。


8. 平台演进路径:从 MVP 到成熟平台

不要试图一步到位建设完整的 Agent 基础架构平台。应该根据业务阶段和实际需求,分阶段演进。

8.1 分阶段演进建议

┌─────────┬───────────────────┬────────────────────────────────────┬──────────────┐
│  阶段   │       目标        │             核心能力               │   典型周期   │
├─────────┼───────────────────┼────────────────────────────────────┼──────────────┤
│ Phase 0 │ 单 Agent 上线     │ LLM Gateway(基础版)              │   2-4 周     │
│         │                   │ 基础日志和监控                     │              │
│         │                   │ 简单的配置管理                     │              │
├─────────┼───────────────────┼────────────────────────────────────┼──────────────┤
│ Phase 1 │ 多 Agent 共存     │ Agent Registry                     │   1-2 月     │
│         │                   │ 多租户基础隔离                     │              │
│         │                   │ 结构化日志和 Trace                 │              │
│         │                   │ 统一的 Tool Service                │              │
├─────────┼───────────────────┼────────────────────────────────────┼──────────────┤
│ Phase 2 │ 平台化运营        │ 灰度发布                           │   2-3 月     │
│         │                   │ 弹性伸缩                           │              │
│         │                   │ 完整的监控和告警体系               │              │
│         │                   │ Prompt 版本化管理                  │              │
│         │                   │ 评估集和回归测试                   │              │
├─────────┼───────────────────┼────────────────────────────────────┼──────────────┤
│ Phase 3 │ 规模化治理        │ 成本工程(模型降级、缓存、预算)   │   3-6 月     │
│         │                   │ 安全审计和合规                     │              │
│         │                   │ 多 Agent 协作引擎                  │              │
│         │                   │ SLA 管理                           │              │
│         │                   │ 完善的开发者体验                   │              │
└─────────┴───────────────────┴────────────────────────────────────┴──────────────┘

8.2 每个阶段的技术选型建议

Phase 0 —— 最小可用

这个阶段的目标是用最小成本让第一个 Agent 在生产环境中跑起来。

LLM Gateway 可以用开源方案(如 LiteLLM)快速搭建,先不做复杂的路由和容错。日志用 ELK 或直接写文件。配置用环境变量或简单的 YAML 文件。部署用单台机器或简单的 Docker Compose。

这个阶段最重要的是积累实际运营经验——了解 Agent 在真实流量下的行为特征、常见问题和性能瓶颈,为后续设计提供依据。

Phase 1 —— 多 Agent 管理

当第二个、第三个 Agent 需要上线时,重复建设的痛点开始显现。这个阶段的重点是抽取共性能力,建立基础的平台化框架。

Agent Registry 可以用 PostgreSQL + Redis 缓存实现。多租户隔离先做逻辑隔离(共享存储,tenant_id 字段过滤)。日志升级为结构化日志,引入 OpenTelemetry 做基础追踪。Tool Service 统一管理工具注册和调用。

Phase 2 —— 平台运营

平台上运行的 Agent 增多,对稳定性和质量的要求提高。这个阶段的重点是建立运营能力。

引入灰度发布机制,所有 Agent 变更通过灰度上线。建立完整的监控和告警体系——三层指标、分布式追踪、报警规则。实现 Prompt 版本化管理和自动化评估。开始处理弹性伸缩的需求。

Phase 3 —— 规模化治理

平台服务于大量 Agent 和多个租户,成本、安全和治理成为重点。

实施完整的成本工程——模型降级、语义缓存、Token 预算管理。建立安全审计体系——Prompt 注入防护、数据安全、操作审计。如果有多 Agent 协作的需求,建设编排引擎。提升开发者体验——完善 SDK、Playground、CI/CD 集成和文档。

8.3 常见的过度设计陷阱

在平台建设过程中,有几个常见的过度设计陷阱需要警惕:

过早引入微服务架构:Phase 0 和 Phase 1 阶段,一个单体服务完全够用。过早拆分为微服务只会增加运维复杂度,拖慢开发速度。等到团队规模和 Agent 数量真正需要时再拆分。

过早建设自研 LLM Gateway:市面上有成熟的开源方案(LiteLLM、One API)。除非有非常特殊的需求(如极致的性能优化、深度的自定义路由),否则先用开源方案,在使用过程中积累需求,后续再决定是否自研。

过度追求实时性:并非所有场景都需要毫秒级的实时处理。日志分析、质量评估、成本报表等场景,分钟级甚至小时级的延迟完全可接受。过度追求实时性会显著增加系统复杂度和成本。

试图解决所有 Agent 的通用问题:每个 Agent 的需求是不同的。平台应该提供可组合的能力模块,而不是一个"大而全"的统一框架。强制所有 Agent 遵循同一个抽象反而会限制灵活性。

忽视运营反馈:平台不是建好就完了。需要持续收集 Agent 开发者的反馈——哪些能力好用、哪些不好用、缺什么、多什么——并据此迭代。最好的平台设计来自实际使用经验,而不是预先的架构愿景。

一句话:最危险的过度设计是在 Phase 0 就规划 Phase 3 的系统——从最小可用开始,让真实的运营痛点驱动架构演进。


9. 总结

9.1 核心架构原则回顾

回顾上下两篇的内容,Agent 基础架构平台的核心设计原则可以归纳为:

分层解耦,关注点分离:接入层、调度层、运行时层、能力层各司其职,每层可独立演进和替换。这是应对 Agent 领域快速变化的基础——当新的模型协议出现时,只需要修改能力层的 LLM Gateway;当新的部署模式出现时,只需要调整运行时层。

平台可控,Agent 自由:运行时层通过沙箱、超时、熔断等机制确保平台的稳定性,同时给 Agent 留足灵活性。平台定义"边界",而不是"路径"。

Token 即资源:与传统平台不同,Agent 平台的核心资源不是 CPU 和内存,而是 Token。流控、计费、预算、伸缩都需要围绕 Token 展开。

可观测性优先:Agent 的非确定性决定了你不能通过代码审查预测行为——只能通过观测数据理解行为。可观测性不是运维的事,是平台的核心能力。

渐进式演进:不要在 Day 1 就建设完整平台。从最小可用开始,根据实际需求和运营反馈迭代演进。

9.2 Agent 基础架构与传统后端架构的本质差异

从根本上看,Agent 基础架构与传统后端架构有三个本质差异:

第一,从确定性到概率性。传统后端的执行路径是确定性的,可以通过代码审查和单元测试保证正确性。Agent 的执行路径是概率性的,需要通过统计评估和持续监控保证质量。这改变了测试、监控和发布的整个方法论。

第二,从计算密集到 I/O + 推理密集。传统后端的瓶颈通常在 CPU 计算或数据库查询。Agent 的瓶颈在外部 LLM 调用的延迟和 Token 吞吐。这改变了性能优化、容量规划和弹性伸缩的策略。

第三,从静态安全到动态安全。传统后端的安全边界在开发时确定——哪些 API 暴露、哪些数据可访问。Agent 的行为在运行时动态决策——调哪个工具、传什么参数由 LLM 决定。这要求从"编码时设防"转向"运行时设防"。

9.3 开放问题与未来方向

Agent 基础架构仍在快速演化,有几个方向值得关注:

标准化:Agent 的工具调用协议(如 MCP)、可观测性标准(如 GenAI Semantic Conventions)、评估框架等正在逐步标准化。平台设计应尽可能对齐正在形成的标准,降低未来迁移成本。

Agent 原生的调度与编排:现有的容器编排(K8s)和工作流引擎(Temporal)并非为 Agent 设计。未来可能出现"Agent 原生"的调度系统——理解 Agent 的执行模式,原生支持长会话、动态资源消耗和多 Agent 协作。

端到端的成本优化:当前的成本优化主要是战术性的(模型降级、缓存、Prompt 压缩)。未来的方向是端到端的自动化成本优化——平台自动学习每种任务的最优模型配置,在质量和成本之间自动寻找最优平衡点。

自治运维:Agent 平台的运维本身也可以借助 Agent 的能力——用 Agent 来监控 Agent 平台、用 Agent 来排障和修复、用 Agent 来优化资源配置。这是 Agent 基础架构的终极形态:平台自身成为最佳的 Agent 应用场景。


Agent 基础架构平台不是一个全新的领域,它站在微服务平台、Serverless 平台和数据平台的肩膀上。真正的创新不在于发明全新的轮子,而在于深刻理解 Agent 的独特特征,将成熟的基础设施模式适配到 Agent 的新语境中。

架构设计的终点不是一张完美的架构图,而是一个能支撑业务持续演进的活系统。

上篇《Agent 基础架构平台(上):从全景架构到核心层设计》

加载导航中...

评论