让生产轨迹驱动 Agent 提示词优化:理解 Amazon Bedrock AgentCore Reflector

2026-09-16 13 预计阅读时间: 1 分钟
来源: aws.amazon.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:13 分钟

Agent 上线之后,真正难的往往不是写出第一版 system prompt,而是持续回答三个问题:哪些失败来自提示词,哪些失败来自工具或业务数据,怎样改动才能在不破坏已有能力的前提下提升效果。

Amazon Bedrock AgentCore 的优化思路,是把生产环境中的 agent traces 转化为候选配置变更,再通过验证流程决定是否晋级。围绕这一流程,系统提示词优化器中的 Reflector engine 会分析执行记录,并分别支持 Single Agent Reflector 和 Sub-Agent Reflector 两类场景。

从“凭经验改 prompt”转向“用轨迹提出变更”

传统的 prompt 调优通常是人工查看几条失败样例,然后直接修改 system prompt。这种方式的问题很明显:

  • 样本数量少,容易把偶然失败当成普遍问题;
  • 修改原因没有结构化记录,难以复盘;
  • prompt、模型参数、工具配置和路由策略可能同时变化;
  • 改动上线前缺少可重复的回归验证。

Reflector engine 的核心价值不在于“自动生成一段更长的 prompt”,而在于建立一个相对完整的优化闭环:

  1. 收集生产 traces,包括用户请求、agent 中间步骤、工具调用、最终响应和结果信号;
  2. 识别成功与失败模式,寻找可解释的行为差异;
  3. 生成候选配置变更,例如 system prompt 的局部修改;
  4. 在保留的验证集上运行候选版本;
  5. 只有当候选版本满足预设指标和安全约束时,才考虑 promotion。

这里的“配置变更”不应狭义理解为 prompt 文本。实际工程中还可以把模型选择、工具描述、子 agent 指令、路由条件或推理预算纳入候选变更,但每次实验最好只改变一个主要变量。

Single Agent 与 Sub-Agent 的优化边界

Single Agent Reflector

Single Agent Reflector 面向一个主要 agent 的执行轨迹。它适合分析以下问题:

  • agent 是否正确理解了任务目标;
  • 是否遗漏了必须遵守的约束;
  • 工具调用前是否完成了必要的参数检查;
  • 最终回答是否覆盖了用户要求;
  • 同类任务中是否反复出现同一种错误。

这类优化的关键,是将一次完整执行拆成“目标—决策—工具调用—结果—最终响应”的链路。只看最终答案,往往无法判断问题究竟来自 prompt,还是来自某个工具返回了错误数据。

Sub-Agent Reflector

Sub-Agent Reflector 面向包含多个子 agent 或角色的系统。此时优化对象不只是某一段文本,还包括协作协议:

  • 主 agent 是否把任务正确分派给子 agent;
  • 子 agent 的职责边界是否清晰;
  • 子 agent 返回结果时是否使用稳定的格式;
  • 主 agent 是否正确整合了多个结果;
  • 重复调用、冲突结论或上下文丢失是否来自协作设计。

多 agent 系统的一个常见陷阱是,把所有失败都归因于某个子 agent 的“能力不足”。实际上,失败可能发生在任务拆分、消息格式、超时处理或结果合并环节。因此,Sub-Agent Reflector 需要观察跨 agent 的完整 trace,而不是只评价单个节点。

一个可改造的最小优化闭环

下面的 Python 示例是一个本地可运行的简化版本,用来演示“轨迹聚合—候选 prompt—验证—晋级”的基本结构。它不是 Amazon Bedrock AgentCore 的官方 SDK 调用,而是可以嵌入现有评测平台的示意实现。实际项目中,可以把 reflect() 替换成对模型或内部优化服务的调用,把 run_agent() 替换成真实 agent。

运行环境只需要 Python 3.10+,无需额外依赖:

from dataclasses import dataclass
from typing import Callable, List


@dataclass
class Trace:
    task: str
    expected: str
    actual: str
    success: bool
    error: str = ""


@dataclass
class Candidate:
    prompt: str
    reason: str


def reflect(traces: List[Trace], current_prompt: str) -> Candidate:
    """一个可替换为 LLM reflector 的规则版实现。"""
    failures = [t for t in traces if not t.success]
    missing_constraint = any("未引用来源" in t.error for t in failures)

    if missing_constraint:
        addition = (
            "\n回答包含事实性结论时,必须引用工具返回的来源;"
            "如果没有可靠来源,请明确说明不确定性。"
        )
        return Candidate(
            prompt=current_prompt + addition,
            reason="失败轨迹反复出现未引用来源的问题",
        )

    return Candidate(
        prompt=current_prompt,
        reason="当前样本没有发现稳定的 prompt 级失败模式",
    )


def evaluate(
    prompt: str,
    traces: List[Trace],
    run_agent: Callable[[str, str], str],
) -> float:
    """用固定验证集计算一个简单的精确匹配分数。"""
    passed = 0
    for trace in traces:
        actual = run_agent(prompt, trace.task)
        if actual.strip() == trace.expected.strip():
            passed += 1
    return passed / len(traces) if traces else 0.0


def main() -> None:
    production_traces = [
        Trace("查找产品 A 的官方规格", "规格:支持 220V", "支持 220V", True),
        Trace(
            "查找产品 B 的官方规格",
            "规格:支持 110V",
            "支持 110V",
            False,
            error="未引用来源",
        ),
    ]
    validation_traces = [
        Trace("查找产品 A 的官方规格", "规格:支持 220V", "", False),
        Trace("查找产品 B 的官方规格", "规格:支持 110V", "", False),
    ]

    current_prompt = "你是一个严谨的产品信息助手。"
    candidate = reflect(production_traces, current_prompt)

    def fake_agent(prompt: str, task: str) -> str:
        # 示例替身:真实实现中这里应调用 agent,并记录完整 trace。
        if "来源" in prompt:
            return "规格:支持 220V" if "A" in task else "规格:支持 110V"
        return "无法确认"

    baseline = evaluate(current_prompt, validation_traces, fake_agent)
    proposed = evaluate(candidate.prompt, validation_traces, fake_agent)

    print("候选原因:", candidate.reason)
    print(f"基线分数:{baseline:.2%}")
    print(f"候选分数:{proposed:.2%}")

    # 生产环境还应加入最小提升幅度、成本、延迟和安全门槛。
    if proposed > baseline:
        print("结果:候选配置通过本地验证,可提交人工审核或灰度发布")
    else:
        print("结果:拒绝候选配置,保留当前版本")


if __name__ == "__main__":
    main()

这段代码有几个值得保留到生产系统的设计点:

  • 生产 traces 和验证 traces 分离,避免用发现问题的数据直接证明修复有效;
  • Reflector 输出变更原因,而不只是输出新 prompt;
  • 候选版本与基线版本使用同一验证集比较;
  • promotion 是一个显式决策,不是生成候选文本后的自动覆盖。

怎样设计可用的 trace 与验证流程

记录足够的上下文

至少应为每次执行保留以下字段:

{
  "trace_id": "trace-001",
  "task": "用户原始请求",
  "agent_version": "prompt-v12",
  "steps": [
    {"type": "model", "input": "...", "output": "..."},
    {"type": "tool", "name": "catalog_search", "arguments": {}, "result": "..."}
  ],
  "final_response": "...",
  "outcome": {"success": false, "reason": "未引用来源"},
  "latency_ms": 1840
}

需要特别注意隐私和数据治理。生产 trace 可能包含个人信息、内部文档或工具凭据,进入优化流程前应进行脱敏、访问控制和保留周期管理。优化器不应因为拿到了更多原始数据,就绕过现有的安全边界。

把“效果”拆成多个指标

只看任务成功率通常不够。一个候选 prompt 可能提升回答正确率,却让延迟、token 成本或拒答质量明显恶化。比较候选版本时,可以同时观察:

  • 任务成功率或业务准确率;
  • 工具调用正确率;
  • 引用和结构化输出合规率;
  • 延迟与 token 使用量;
  • 安全策略违规率;
  • 对已有能力的回归情况。

对于 Sub-Agent 系统,还应增加路由正确率、重复调用率、子 agent 结果可解析率和最终合并正确率等指标。

将基准测试和灰度发布分开

Reflector 的 benchmark 可以帮助比较 Single Agent Reflector 与 Sub-Agent Reflector 在不同任务结构下的表现,但 benchmark 结果不等于生产收益。真实上线前,建议采用三层验证:

  1. 离线回归:固定数据集,比较基线和候选版本;
  2. 对抗与边界测试:检查提示注入、缺失字段、工具异常和超长上下文;
  3. 小流量灰度:观察真实延迟、成本和用户反馈,再决定是否扩大流量。

如果验证集过于单一,优化器很容易针对数据集过拟合。验证集应覆盖高频任务、历史失败任务、长尾任务和明确的安全边界。

采用时的工程建议

可以把 AgentCore 的优化流程理解为一个受控的配置发布系统,而不是一个“自动改 prompt”按钮。落地时建议遵循下面的清单:

  • 为每个 agent、prompt 和工具协议建立可追踪版本号;
  • 生产 trace、训练或分析样本、验证集分别管理;
  • 要求每个候选变更附带失败模式、变更理由和预期影响;
  • 设置准确率、成本、延迟和安全性的 promotion 门槛;
  • 对 Sub-Agent 系统记录完整的跨 agent 调用链;
  • 对候选版本保留回滚路径和人工审核记录;
  • 将 prompt 优化与工具、检索数据质量问题分开诊断。

最重要的边界是:Reflector 能帮助团队从执行记录中发现模式、提出改动并验证改动,但它不能替代指标设计和系统治理。只有当 trace 足够完整、验证集足够可靠、promotion 规则足够明确时,生产轨迹才会真正变成可持续的 agent 改进信号。


相关推荐