Workflow Evals with Mocked Tools

Nikola Balic (@nibzard)· emerging

问题

单元测试、代码检查器和类型检查器可验证单个组件,但无法对Agent工作流进行端到端测试。即便所有底层组件均无问题,也很容易编写出生效不佳的prompt。

你需要验证prompt与工具作为一个系统能否协同高效运转。

方案

实现工作流评估(模拟):使用模拟工具测试完整的Agent工作流

核心组件(借鉴Sierra方案):

1. 双工具实现

每个工具都提供「真实版」和「模拟版」两种实现

# 真实实现——调用真实API
def search_knowledge_base_true(query: str) -> str:
    return kb_api.search(query)

# 模拟实现——返回静态/测试数据
def search_knowledge_base_mock(query: str) -> str:
    return TEST_KB_RESULTS.get(query, DEFAULT_RESULT)

2. 模拟配置

每个评估需定义以下内容:

  • 初始Prompt:Agent接收的初始指令
  • 元数据:评估可用的场景context
  • 评估标准:成功/失败的判定规则
evals:
  - name: slack_reaction_jira_workflow
    initial_prompt: "给这条Slack消息里的JIRA工单添加一个笑脸反应"
    metadata:
      situation: "包含JIRA链接的Slack消息"
    expected_tools:
      - slack_get_message
      - jira_get_ticket
      - slack_add_reaction
    evaluation_criteria:
      objective:
        - tools_called: ["slack_get_message", "jira_get_ticket", "slack_add_reaction"]
        - tools_not_called: ["slack_send_message"]
      subjective:
        - agent_judge: "回复有用且准确"

3. 双重评估标准

客观标准:
  • 实际调用的工具列表
  • 未调用的工具列表
  • 对话中添加的标签/状态(若适用)
主观标准:
  • Agent作为判定者的评估(例如:“回复是否友好?”)
  • LLM对定性结果的评估

4. CI/CD集成

每次提交拉取请求(PR)时自动运行评估

# GitHub Actions 工作流
触发条件:pull_request
步骤:
  - 执行:python scripts/run_agent_evals.py
    # 将评估结果作为PR评论发布
# 评估执行流程
1. 加载评估配置
2. 将所有工具替换为模拟实现
3. 结合初始Prompt与元数据运行Agent
4. 跟踪Agent调用的工具
5. 对照客观标准(工具使用情况)完成评估
6. 启动Agent判定环节处理主观标准
7. 生成包含详情的通过/失败报告

如何使用

最佳适用场景

  • 工具存在副作用的Agent工作流(如API、数据库)
  • 需验证工作流的CI/CD流水线
  • Prompt工程与优化
  • Agent行为变更的回归测试

实现方案

1. 为工具创建模拟层

class MockToolRegistry:
    def __init__(self, mode: str = "mock"):
        self.mode = mode

    def get_tool(self, tool_name: str):
        if self.mode == "mock":
            return self.mocks[tool_name]
        return self.real_tools[tool_name]

    # 注册模拟实现
    mocks = {
        "slack_send_message": mock_slack_send_message,
        "jira_create_ticket": mock_jira_create_ticket,
        # ...
    }

2. 定义评估用例

evals = [
    {
        "name": "login_support_flow",
        "prompt": "用户无法登录,请提供帮助",
        "expected_tools": ["user_lookup", "password_reset"],
        "forbidden_tools": ["account_delete"],
        "subjective_criteria": "回复共情且有帮助"
    },
    # ... 更多评估用例
]

3. 运行并评估

def run_eval(eval_config):
    # 使用模拟工具运行Agent
    result = agent.run(
        prompt=eval_config["prompt"],
        tools=mock_registry
    )

    # 检查客观标准
    tools_called = result.tools_used
    passed = all(t in tools_called for t in eval_config["expected_tools"])
    passed &= all(t not in tools_called for t in eval_config["forbidden_tools"])

    # 检查主观标准
    if passed:
        judge_prompt = f"""
        请评估以下Agent回复:{result.response}
        评估标准:{eval_config['subjective_criteria']}
        是否通过?
        """
        passed = llm_evaluator(judge_prompt) == "PASS"

    return {"passed": passed, "details": result}

4. 与CI/CD集成

# .github/workflows/agent_evals.yml
name: Agent 评估
on: pull_request
jobs:
  evals:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - run: python scripts/run_evals.py --format github
      - uses: actions/github-script@v6
        with:
          script: |
            const results = require('./eval_results.json');
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: formatResults(results)
            });

处理非确定性问题: 文章指出,受非确定性影响,评估效果"远未达到预期":

  • 强信号:所有用例全部通过或全部失败
  • 弱信号:结果好坏参半
  • 缓解方案:重试失败的评估(例如:"三次尝试中至少通过一次")

权衡

优点

  • 端到端验证:将prompt与工具作为一个完整系统协同测试
  • 快速反馈:在回归问题进入生产环境前提前发现
  • 安全测试:通过模拟(Mocked)工具避免测试过程中的副作用
  • 明确评估标准:涵盖客观(工具调用)与主观(质量)两类衡量维度
  • CI/CD集成:在每一个PR上自动执行验证

缺点

  • 非确定性:LLM的输出可变性导致不稳定测试(Flaky Tests)频发
  • 模拟维护成本:需持续保持模拟工具与真实工具的行为同步
  • Prompt驱动的脆弱性:相比代码驱动的工作流,依赖prompt的工作流稳定性更差
  • 不适合作为阻塞性校验:因结果可变性,难以作为CI门控使用
  • 调优开销:需持续调整prompt与模拟响应
  • 信号有限:通过/失败混合的结果仅能提供模糊的指导意见

运营挑战

“目前这套方案运作尚可,但远未达到预期……当所有测试全失败或全通过时,信号非常明确,但大多数测试结果处于中间模糊地带。” “我们依赖prompt驱动而非代码驱动的工作流,这引入了大量非确定性问题,除非对prompt和模拟进行调优,否则我找不到解决办法。”

改进策略

  1. 重试逻辑:采用“三次尝试中至少通过一次”的机制降低测试不稳定性
  2. 优化Prompt:让评估用prompt更精准、更具确定性
  3. 优化模拟(Mocks):提升模拟响应的真实度
  4. 用代码替代Prompt:将复杂工作流从prompt驱动迁移至代码驱动
  5. 指导性校验而非阻塞性校验:用于上下文参考,而非作为CI门控

参考文献

关键词

围绕智能代理的验证与优化展开,涵盖内部代理工作流的评估验证方法、塞拉平台的模拟测试方案,以及执行后测试的停止钩子自动续行模式、基于工作流的智能代理强化微调技术。

直译
  • 塞拉平台:面向代理测试的模拟方法

来源摘要

正在获取来源并生成中文摘要…

来源: https://lethain.com/agents-evals/

← 返回社区