Agno 可靠性评估(Reliability Eval)实战指南:验证 Agent 与 Team 的工具调用是否按预期执行
2026/9/10 12:06:55 网站建设 项目流程

Agno 可靠性评估(Reliability Eval)实战指南:验证 Agent 与 Team 的工具调用是否按预期执行

【免费下载链接】agnoBuild, run, and manage agent platforms.项目地址: https://gitcode.com/GitHub_Trending/ag/agno

在 Agno 中构建 Agent 与 Team 时,模型是否"说到做到"——即是否真的调用了我们期望的工具、并以正确的参数调用——直接决定了系统的稳定性与可信度。本文围绕 cookbook/09_evals/reliability 目录下的可靠性评估示例,系统讲解 Agno 的ReliabilityEval评估框架:如何校验单次工具调用、多次工具调用、参数级匹配,如何评估 Team 的委派与搜索流程,如何将评估结果持久化到 PostgreSQL,以及如何以异步方式运行评估。读完本文,你将掌握一套可复制、可接入 CI 的 Agent 工具调用可靠性验证方案。

什么是 Reliability Eval

可靠性评估(Reliability Eval)用于回答一个核心问题:模型是否做出了预期的工具调用(expected tool calls)。它不评判答案的语义质量,而是聚焦调用行为的正确性——工具名是否匹配、参数是否精确、是否调用了预期之外的工具。

以 ReliabilityEval 源码 为据,评估器通过对比agent_response(或team_response)中实际发生的工具执行expected_tool_calls声明,输出一个结构化的 ReliabilityResult,其中包含:

字段含义
eval_status评估结论,"PASSED""FAILED"
passed_tool_calls实际执行且匹配预期的工具调用列表
failed_tool_calls执行了预期之外的、在严格模式下被视为失败的工具调用
missing_tool_calls声明了预期但未产生干净执行(缺失、被拒或出错)的工具
additional_tool_callsallow_additional_tool_calls=True时记录的额外合法调用
failed_argument_checks/passed_argument_checks参数级校验的通过/失败结果

关键设计(从源码注释可确认):从 2.8.0 起,评估依据从"消息侧请求(requests)"升级为"执行侧证据(executions)"。一个预期工具只有在存在干净的 ToolExecution(即tool_call_error不为真、未被暂停)时才视为满足;被tool_call_limit拒绝、执行报错或参数非法的调用,即使曾在消息中出现过,也不再让评估通过。历史轮次注入的消息(from_history标记)会被排除,避免"昨天的调用"影响今天的严格评估。

ReliabilityResult.assert_passed()通过assert self.eval_status == "PASSED"将失败直接转化为断言异常,因而可以天然嵌入 CI 流程。

快速上手:单工具调用的可靠性校验

最简单也最常见的场景是:Agent 只被期望调用一个工具,例如使用CalculatorTools计算阶乘。参考 single_tool_calls/calculator.py:

from typing import Optional from agno.agent import Agent from agno.eval.reliability import ReliabilityEval, ReliabilityResult from agno.models.openai import OpenAIChat from agno.run.agent import RunOutput from agno.tools.calculator import CalculatorTools def factorial(): agent = Agent( model=OpenAIChat(id="gpt-5.2"), tools=[CalculatorTools()], ) response: RunOutput = agent.run("What is 10! (ten factorial)?") evaluation = ReliabilityEval( name="Tool Call Reliability", agent_response=response, expected_tool_calls=["factorial"], ) result: Optional[ReliabilityResult] = evaluation.run(print_results=True) if result: result.assert_passed() if __name__ == "__main__": factorial()

代码流程清晰可见:创建 Agent → 运行得到RunOutput→ 构造ReliabilityEvalrun()执行评估 →assert_passed()判定。其中:

  • expected_tool_calls=["factorial"]与 CalculatorTools.factorial 的方法名一一对应,是匹配的事实基准;
  • print_results=True会在终端用 Rich 渲染一张 "Reliability Summary" 表格(来自 ReliabilityResult.print_eval);
  • 若结果缺失(例如模型直接给答案而没调工具),missing_tool_calls将包含factorial,评估状态为FAILEDassert_passed()抛出断言。

这与单元测试 test_reliability_eval.py 中test_exact_match_passestest_fails_on_missing_expected_tooltest_fails_when_no_tools_called等用例验证的语义完全一致:预期工具未产生干净执行即判失败。

参数级校验:不仅调对工具,还要传对参数

仅校验工具名往往不够。当业务依赖精确参数时,需要使用expected_tool_call_arguments做参数匹配。同一文件中的第二个示例:

def multiply_with_argument_check(): """Verify that the tool was called with the correct arguments.""" agent = Agent( model=OpenAIChat(id="gpt-5.2"), tools=[CalculatorTools()], ) response: RunOutput = agent.run("What is 10 * 5?") evaluation = ReliabilityEval( name="Tool Call Argument Validation", agent_response=response, expected_tool_calls=["multiply"], expected_tool_call_arguments={ "multiply": {"a": 10, "b": 5}, }, ) result: Optional[ReliabilityResult] = evaluation.run(print_results=True) if result: result.assert_passed()

参数声明的两种形态(源码字段定义):

  • 单次校验{"multiply": {"a": 10, "b": 5}}—— 期望至少有一次multiply调用的参数同时满足a == 10b == 5
  • 多次校验{"add": [{"a": 2, "b": 2}, {"a": 3, "b": 3}]}—— 列表中的每个 spec 都必须被至少一次干净调用命中,才判定通过。

从 参数匹配实现 看,参数取自ToolExecution.tool_args(已解析的 JSON 参数,空参数归一化为{}),且只从干净执行中收集——消息侧请求即使携带参数,若调用本身未真正工作,也不能满足参数检查。若某个工具已被判为缺失(missing_names),其参数检查会被自动跳过,避免重复报错。

多工具调用与子集匹配

真实任务往往需要一连串工具协同。参考 multiple_tool_calls/calculator.py:

严格模式:所有预期工具都必须出现

def multiply_and_exponentiate(): agent = Agent( model=OpenAIChat(id="gpt-5.2"), tools=[CalculatorTools()], ) response: RunOutput = agent.run( "What is 10*5 then to the power of 2? do it step by step" ) evaluation = ReliabilityEval( name="Tool Calls Reliability", agent_response=response, expected_tool_calls=["multiply", "exponentiate"], ) result: Optional[ReliabilityResult] = evaluation.run(print_results=True) if result: result.assert_passed()

默认allow_additional_tool_calls=False,语义是精确匹配(exact match)multiplyexponentiate都必须有干净执行;与此同时,任何不在预期列表内的工具调用都会被记入failed_tool_calls。单元测试 test_exact_match_fails_on_unexpected_tool 印证:预期["multiply"]而实际多调用了exponentiate,评估即失败。

宽松模式:子集匹配(subset matching)

def subset_matching(): """Only require 'multiply' -- extra tool calls like 'exponentiate' are allowed.""" agent = Agent( model=OpenAIChat(id="gpt-5.2"), tools=[CalculatorTools()], ) response: RunOutput = agent.run( "What is 10*5 then to the power of 2? do it step by step" ) evaluation = ReliabilityEval( name="Subset Tool Calls", agent_response=response, expected_tool_calls=["multiply"], allow_additional_tool_calls=True, ) result: Optional[ReliabilityResult] = evaluation.run(print_results=True) if result: result.assert_passed()

allow_additional_tool_calls=True时,评估退化为子集匹配:只要求multiply存在,exponentiate等额外调用被记入additional_tool_calls(仅作记录,不判失败)。这在模型"多走一步"但核心行为正确的场景下非常实用——例如你只关心 Agent 是否完成了主工具调用,而不强求它的推理路径完全固定。

团队可靠性:校验 Team 的委派与搜索流程

可靠性评估同样适用于 Team。参考 team/ai_news.py:一个 News Searcher 成员 Agent 负责调用WebSearchTools(enable_news=True)搜索新闻,外层 Team 负责委派任务。

from typing import Optional from agno.agent import Agent from agno.eval.reliability import ReliabilityEval, ReliabilityResult from agno.models.openai import OpenAIChat from agno.run.team import TeamRunOutput from agno.team.team import Team from agno.tools.websearch import WebSearchTools team_member = Agent( name="News Searcher", model=OpenAIChat("gpt-5.6-luna"), role="Searches the web for the latest news.", tools=[WebSearchTools(enable_news=True)], ) team = Team( name="News Research Team", model=OpenAIChat("gpt-5.6-luna"), members=[team_member], markdown=True, show_members_responses=True, ) expected_tool_calls = [ "delegate_task_to_member", "search_news", ] def evaluate_team_reliability(): response: TeamRunOutput = team.run("What is the latest news on AI?") evaluation = ReliabilityEval( name="Team Reliability Evaluation", team_response=response, expected_tool_calls=expected_tool_calls, ) result: Optional[ReliabilityResult] = evaluation.run(print_results=True) if result: result.assert_passed() if __name__ == "__main__": evaluate_team_reliability()

这里有两个关键差异点:

  1. 传入team_response(类型TeamRunOutput)而非agent_responseReliabilityEval.run()明确要求二者必须且只能提供一个(参数校验逻辑);
  2. 证据来自嵌套成员响应。Team 的工具调用发生在成员 Agent 上,且成员本身也可能是 Team。从 _collect_member_evidence 实现 可以确认:评估器会递归遍历member_responses,把每一层嵌套的toolsmessages汇总后统一匹配。因此expected_tool_calls可以同时包含 Team 层级的delegate_task_to_member和成员层级的search_news,二者都必须有干净执行。

评估结果持久化:写入 PostgreSQL

生产环境中评估结果需要留痕、可追溯。参考 db_logging.py,评估器内置数据库写入能力:

from typing import Optional from agno.agent import Agent from agno.db.postgres.postgres import PostgresDb from agno.eval.reliability import ReliabilityEval, ReliabilityResult from agno.models.openai import OpenAIChat from agno.run.agent import RunOutput from agno.tools.calculator import CalculatorTools # Create Database db_url = "postgresql+psycopg://ai:ai@localhost:5432/ai" db = PostgresDb(db_url=db_url, eval_table="eval_runs") # Create Agent agent = Agent( model=OpenAIChat(id="gpt-5.2"), tools=[CalculatorTools()], ) if __name__ == "__main__": response: RunOutput = agent.run("What is 10!?") evaluation = ReliabilityEval( db=db, name="Tool Call Reliability", agent_response=response, expected_tool_calls=["factorial"], ) result: Optional[ReliabilityResult] = evaluation.run(print_results=True) if result: result.assert_passed()
  • 通过PostgresDb(db_url=..., eval_table="eval_runs")指定连接串与评估结果表;
  • 评估通过EvalType.RELIABILITY类型,将run_idrun_data(即ReliabilityResult的完整序列化)、评估输入(expected_tool_callsallow_additional_tool_callsexpected_tool_call_arguments)以及agent_id/team_id/model_id/model_provider一并写入数据库(写入逻辑);
  • 同一套持久化机制也支持file_path_to_save_results参数(支持{name}{run_id}占位符),可将结果保存到本地文件。

注意:若使用异步数据库(AsyncBaseDb),run()会抛出ValueError,必须改用arun()(源码约束)。

异步评估:arun()与并发编排

需要将多个评估并行编排、或接入异步 Agent 平台时,使用异步接口。参考 reliability_async.py:

import asyncio from typing import Optional from agno.agent import Agent from agno.eval.reliability import ReliabilityEval, ReliabilityResult from agno.models.openai import OpenAIChat from agno.run.agent import RunOutput from agno.tools.calculator import CalculatorTools def factorial(): agent = Agent( model=OpenAIChat(id="gpt-5.2"), tools=[CalculatorTools()], ) response: RunOutput = agent.run("What is 10!?") evaluation = ReliabilityEval( agent_response=response, expected_tool_calls=["factorial"], ) # Run the evaluation calling the arun method. result: Optional[ReliabilityResult] = asyncio.run( evaluation.arun(print_results=True) ) if result: result.assert_passed() if __name__ == "__main__": factorial()

arun(print_results=True)run()具备对等的完整链路:生成run_id→ 富文本 spinner →_evaluate核心判定 → 可选落盘 → 可选打印 → 通过async_log_eval写入异步数据库 →async_log_eval_telemetry上报遥测(异步实现)。在异步 Agent 循环中,可直接await evaluation.arun(...)而无需包一层asyncio.run

将可靠性评估接入 CI

综合以上能力,一套推荐的接入模式是:对每个关键 Agent/Team,编写独立评估函数,最后统一断言。失败即抛出AssertionError,退出码非零,CI 自然红灯:

python single_tool_calls/calculator.py python multiple_tool_calls/calculator.py python team/ai_news.py python db_logging.py # 需本地 PostgreSQL 可用

调试小贴士:

  • eval_statusFAILED时,优先查看missing_tool_calls——若条目带有(requested but refused/errored — execution matching, new in 2.8.0)注释,说明模型发起了调用但执行被拒/出错,问题在运行环境或tool_call_limit配置,而非评估器本身;
  • failed_tool_calls出现预期外工具时,检查是否应设置allow_additional_tool_calls=True,或审视提示词是否约束不足;
  • 期望值写错(例如工具名与 CalculatorTools 中实际的multiply/exponentiate/factorial不一致)会导致误报,务必以工具类中的真实方法名为准;
  • 不需要终端输出的自动化场景,可设show_spinner=False关闭进度动画(对应测试 test_show_spinner_disabled)。

小结

Reliability Eval 是 Agno 评估体系(cookbook/09_evals)中专注"行为正确性"的一环。通过 ReliabilityEval 的expected_tool_callsexpected_tool_call_argumentsallow_additional_tool_calls三个核心配置,你可以分别验证工具是否被调用、参数是否精确、额外调用是否被容忍;通过agent_response/team_response双通道覆盖单 Agent 与嵌套 Team;通过dbfile_path_to_save_resultsrun/arun双接口满足持久化与异步编排需求。将其与 CI 结合,即可为每个模型迭代建立可回归的工具调用护栏。

【免费下载链接】agnoBuild, run, and manage agent platforms.项目地址: https://gitcode.com/GitHub_Trending/ag/agno

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询