Docs · App Dev Guide

大模型应用开发

从 Prompt 工程到 AI Agent,一站式覆盖大模型应用开发全链路 —— 让你能在 1 周内跑出生产级 MVP。

Agent · 评估与部署

Agent 比传统软件更难测试:它有随机性、有状态、会调用外部工具、可能陷入循环。没有系统化的评估和部署策略,Agent 很难从 demo 走到生产环境。

为什么 Agent 评估特别难

传统软件测试Agent 测试
输入 → 输出 确定同样输入,LLM 可能给出不同策略
单元测试覆盖逻辑分支Agent 的「分支」是 LLM 自由生成的
失败时堆栈清晰Agent 可能默默用了错误策略但没报错
无外部依赖易 mockAgent 依赖真实工具、API、数据库

评估维度

1. 任务完成度(Task Success)

最直观的指标:Agent 是否完成了用户请求?

def evaluate_success(prediction: str, reference: str) -> bool:
          """用 LLM 判断预测结果是否满足参考标准"""
          prompt = f"""
      用户请求:{reference}
      Agent 输出:{prediction}
      
      请判断 Agent 是否完成了用户请求。只回答"是""否""""
          return "是" in llm.generate(prompt)

更精细的指标

  • 完全成功:所有子任务完成,结果正确
  • 部分成功:完成了主要任务,有 minor 遗漏
  • 失败:任务未完成或结果错误

2. 工具调用正确性

Agent 调了哪些工具、参数对不对、顺序是否合理?

# 期望的工具调用序列
      expected_calls = [
          {"name": "search", "args": {"query": "国产大模型 2025"}},
          {"name": "compare", "args": {"models": ["DeepSeek", "Qwen", "Yi"]}}
      ]
      
      # 实际调用序列
      actual_calls = trace["tool_calls"]
      
      # 评估:名字和关键参数是否匹配
      def match_score(expected, actual):
          if expected["name"] != actual["name"]:
              return 0.0
          # 关键参数匹配度
          keys = set(expected["args"].keys())
          matched = sum(1 for k in keys if actual["args"].get(k) == expected["args"][k])
          return matched / len(keys)

3. 效率指标

指标说明目标
步数完成任务用了多少轮 thought-action越少越好
Token 消耗总输入+输出 token 数控制成本
延迟端到端响应时间用户可接受
工具调用次数外部 API 调用次数越少越省

4. 安全性与边界

  • 权限越界:Agent 是否调用了不该调的工具?
  • 信息泄露:是否把敏感数据传给了外部 API?
  • 幻觉输出:最终结果是否包含编造的信息?
  • 无限循环:是否设置了 max_steps 并生效?

评估数据集构建

1. 人工标注案例

{
        "input": "帮我查一下北京明天的天气,然后发邮件提醒我带伞",
        "expected_steps": [
          {"tool": "weather", "args": {"city": "北京", "date": "明天"}},
          {"tool": "send_email", "args": {"subject": "天气提醒", "body": "..."}}
        ],
        "success_criteria": "获取了北京明天天气并发送了提醒邮件"
      }

2. 对抗测试(Adversarial Cases)

专门设计让 Agent 出错的输入:

  • 模糊指令:"帮我处理一下那个文档"
  • 矛盾需求:"用最快的速度做最详细的分析"
  • 边界条件:空输入、超长输入、特殊字符
  • 恶意注入: prompt 中夹带「忽略之前指令」类的攻击

3. A/B 对比测试

同一批测试集,跑两个版本的 Agent,对比指标:

# 跑测试集
      results_v1 = [agent_v1.run(case["input"]) for case in test_set]
      results_v2 = [agent_v2.run(case["input"]) for case in test_set]
      
      # 对比
      print(f"V1 成功率: {success_rate(results_v1):.1%}")
      print(f"V2 成功率: {success_rate(results_v2):.1%}")
      print(f"V1 平均步数: {avg_steps(results_v1):.1f}")
      print(f"V2 平均步数: {avg_steps(results_v2):.1f}")

部署策略

1. 渐进式发布

不要一次性全量替换旧系统:

Phase 1: Shadow Mode(影子模式)
         → Agent 并行运行,结果只记录不生效,对比旧系统
         
      Phase 2: Canary(灰度)
         → 5% 流量走 Agent,监控错误率和用户反馈
         
      Phase 3: Rollout(全量)
         → 逐步切到 100%,保留快速回滚能力

2. 关键设计:人机协同(Human-in-the-Loop)

生产环境不要完全自动,关键操作给人确认:

async def execute_with_guardrails(action, tools):
          if action["risk_level"] == "high":
              # 高敏感操作:发审批通知
              approval = await request_human_approval(action)
              if not approval:
                  return {"status": "rejected", "reason": "未通过人工审核"}
      
          return await tools.execute(action)

3. 监控与告警

监控项告警阈值响应
错误率> 5%自动降级到旧系统
平均步数> 15排查是否陷入循环
P99 延迟> 30s检查工具超时配置
Token 成本超日预算限流或切换 cheaper 模型
工具失败率> 10%检查外部 API 状态

4. 版本管理与回滚

Agent 的 prompt、工具配置、模型参数都是「代码」,要版本化:

# prompt-v1.yaml
      system_prompt: "你是一个谨慎的助手..."
      max_steps: 10
      model: gpt-4o
      
      # 切换版本只需改配置,无需重新部署代码

从评估到上线的完整流程

开发 Agent → 本地单元测试 → 构建评估数据集
         ↓
      跑自动化评估 → 指标达标?
         ↓ 否 → 调 prompt / 加工具 / 改策略 → 重新评估
         ↓ 是
      Shadow Mode 验证 → 灰度发布 → 全量上线
         ↓
      持续监控 + 定期回归测试
🚀

Agent 上线不是终点,而是起点。上线后的真实用户反馈才是最好的评估数据——持续收集、迭代优化。