尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
用 Agno Environments 搭建你的第一个评测环境:以 K 次滚动网格衡量 Agent 可靠性
用 Agno Environments 搭建你的第一个评测环境以 K 次滚动网格衡量 Agent 可靠性【免费下载链接】agnoBuild, run, and manage agent platforms.项目地址: https://gitcode.com/GitHub_Trending/ag/agno导读Agno 的 Environments 子模块cookbook/environments/面向验证与数据集生成场景让同一个 Agent 对一小批任务重复运行 K 次对每一次尝试都打分最终产出一张通过率网格。本文以仓库中首个入门示例_01_first_environment为骨架完整讲解Environment、Task、CodeScorer、run_rollouts的组装方式并深入源码environment.py 与 runner.py剖析尝试隔离、环境指纹与策略指纹等底层机制。读完你既能直接运行三份示例脚本也能照此搭建属于自己的 K 次滚动评测流程。为什么需要环境一次成功不等于可靠单个 Agent 的一次成功运行无法说明任何可靠性问题——LLM 的采样具有随机性同一提示词可能时而答对、时而答错。_01_first_environment的核心主张是让一个 Agent 对同一小任务集运行 K 次并对每次尝试打分得到的是通过率网格而不是基于一次幸运样本得出的结论。网格的价值在于让可靠性变得可视化、可区分整行打满full rows说明任务已被掌握mastered整行空白empty rows说明需要不同的干预手段a different intervention部分通过的行partial rows正是学习区learning zone——任务既没有饱和也没有彻底失败每一次失败都能与同任务的通过尝试形成对照是最值得研究的部分。该目录下共有三个文件见 README.md文件定位basic.py最小完整环境类型化输出、任务集、CodeScorer与 K 次尝试网格with_summary.py通过稳定的summary()映射读取同一份网格with_fingerprints.py检查运行结果上盖戳的环境指纹与策略指纹组装最小完整环境basic.pybasic.py 是最小的完整环境由四个部分组成输出模型、评分函数、Agent、Environment。第一步类型化输出与评分函数from agno.agent import Agent from agno.environments import Environment, Task, run_rollouts from agno.models.openai import OpenAIResponses from agno.scorer import CodeScorer from pydantic import BaseModel class Answer(BaseModel): value: int def answer_matches(run, expected): return run.content.value expected这里用 Pydantic 模型声明了类型化输出Answer只有一个整数字段value。评分函数answer_matches直接读取run.content.value与任务期望值比较——在output_schema生效时run.content是 pydantic 模型而非字符串比较类型化字段正是官方推荐写法code.py 的 docstring 亦明确说明run.get_content_as_string()存在但有损。第二步定义 Agentagent Agent( modelOpenAIResponses(idgpt-5.5, reasoning_effortlow), output_schemaAnswer, instructionsReturn only the requested final integer in the typed field., )Agent 使用OpenAIResponses模型显式指定gpt-5.5与reasoning_effortlow。指令要求模型只在类型化字段中返回最终整数确保输出可以稳定落入Answer结构。第三步定义任务集与 Environmentenvironment Environment( namefirst-environment, agentagent, tasks( Task(inputWhat is 17 multiplied by 23?, expected391, ideasy-product), Task( input( Compute 2718281828459045 multiplied by 1618033988749895. Add the decimal digits of that product, multiply the digit sum by 131071, subtract the product remainder modulo 65521, and return the final integer. ), expected20944939, idchained-product-a, ), Task( input( Compute 3141592653589793 multiplied by 1414213562373095. Add the decimal digits of that product, multiply the digit sum by 104729, subtract the product remainder modulo 65537, and return the final integer. ), expected16731173, idchained-product-b, ), ), scorerCodeScorer(answer_matches), )任务集刻意采用简单锚点 链式算术的搭配easy-product17×23391几乎必然全对作为难度锚点两个链式乘积任务要求先做大数乘法、再对乘积做数位求和、乘以素数、取模相减被校准为在gpt-5.5上产生分歧——既不会全对也不会全错。README 特别提醒若所有任务都打满网格就失去了作为可靠性示例的价值。在源码层面environment.py 中Task是一个frozenTrue, eqFalse的数据类字段包括字段类型说明inputstr任务输入必填expectedAnyAgent 应产生的期望值可选idstr \| None展示与选择用 id缺省时按位置自动命名为t1..tNmetadataMapping附加元数据默认空字典Environment同样为frozenTrue, eqFalse数据类environment.py字段为name、tasks、scorer、agent与默认 120 秒的timeout_seconds。其__post_init__会做三件事强制将tasks转为元组并校验元素类型、拒绝重复的显式任务 id、拒绝把Team当作agent同时接受Agent实例或返回Agent的零参工厂。第四步运行 K 次滚动并打印网格if __name__ __main__: results run_rollouts(environment, k4) print(results)run_rollouts(environment, k4)表示每个任务运行 4 次。print(results)调用EnvironmentRunResult.__str__runner.py经由 _render.py 渲染出静态网格。网格中每次尝试对应一个字形实心块█表示通过浅色块░表示已评分但失败三角▲表示未评分超时、报错、被中断等。每行还附带通过/已评分计数、通过率与learning zone标签。读懂网格通过率与学习区的判定网格行背后的统计逻辑定义在 runner.py 的TaskResult中值得逐条明确pass_rate已通过次数 / 已评分次数。未评分尝试被排除在统计之外绝不折算为 0 分——超时不是答错源码注释原文a timeout is not a wrong answer当已评分次数为 0 时返回Nonein_learning_zone0 n_passed n_scored即同一任务既有通过的已评分尝试、也有失败的已评分尝试。这正是 README 所说partial rows 是学习区的精确判据也与 TEST_LOG.md 中记录的 Agno 2.8.0 定义一致mean_value已评分尝试的分值均值在 code.py 的CodeScorer下bool会被转换为 1.0/0.0 的Score。以 TEST_LOG.md 记录的一次实际运行Agno 2.8.0、gpt-5.5、k4为例basic.py的网格形如easy-product ████ 4/4 1.00 chained-product-a ██░░ 2/4 0.50 learning zone chained-product-b ██░░ 2/4 0.50 learning zoneeasy-product打满说明锚点任务已被掌握两个链式任务落在学习区意味着调整提示词或模型后重跑就能在网格上直接看到行长的变化——这正是该环境服务于迭代式调优的工作方式。用 summary() 读取稳定的统计契约with_summary.pybasic.py用终端网格展示结果适合人读而 with_summary.py 展示了面向脚本与 CI 的读取方式EnvironmentRunResult.summary()返回一个键固定的字典。源码中runner.py该契约被明确注释为The CI contract; these keys are frozen即键集合冻结、不可随意变更if __name__ __main__: results run_rollouts(environment, k4) print(results) print() summary results.summary() print(foverall pass rate: {summary[pass_rate]}) print(fscored attempts: {summary[n_scored]} of {summary[n_attempts]}) for task in summary[tasks]: print( f{task[id]}: pass_rate{task[pass_rate]}, funscored{task[n_unscored]}, learning_zone{task[learning_zone]} )summary()的完整键包括整体层env、k、n_tasks、n_attempts、n_scored、n_unscored、pass_rate、mean_value、env_fingerprint、policy_fingerprint、stopped_early每个任务tasks列表元素id、pass_rate、mean_value、n_unscored、learning_zone。这使结果可被直接写入 CI 断言或生成报告而不必解析终端文本。此外结果对象还提供save(path)/load(path)JSON 持久化带format_version校验、learning_zone()仅保留学习区任务的过滤副本、errors()按任务 id 分组的错误列表与diff(baseline)与基线运行逐任务对比增量指纹不一致时抛出MismatchError等编程接口可支撑完整的评测工作流。指纹环境指纹与策略指纹with_fingerprints.pywith_fingerprints.py 展示了 Agno 环境设计的独到之处——双指纹if __name__ __main__: results run_rollouts(environment, k4) print(results) print() summary results.summary() print(fenvironment fingerprint: {summary[env_fingerprint]}) print(fpolicy fingerprint: {summary[policy_fingerprint]}) print(fenvironment matches result: {environment.env_matches(results)})脚本 docstring 给出了直觉判据改评分器、改任务、改提示词 → 环境指纹变化换模型 → 策略指纹变化。两个指纹在run_rollouts运行开始时计算并盖戳在结果上其实现位于 environment.py环境指纹env_fingerprint是对环境身份整体做 sha256载荷包括任务三元组id、input、expected、评分器摘要CodeScorer.digest()对函数源码与pass_threshold的 sha256、声明的工具 schema、tool_choice、各类提示词字段instructions、description、system_message、additional_context、expected_output、role、additional_input、提示词开关markdown、add_name_to_context等按标志值而非渲染文本哈希避免add_datetime_to_context注入墙钟时间导致指纹不稳定、模型级提示词、声明的session_state与终止设置timeout_seconds、tool_call_limit。返回串带版本前缀envfp2:跨版本指纹永不相等。策略指纹policy_fingerprint是对策略身份做 sha256载荷来自model_identity_payload见 _model.py模型类、id、provider、base_url 及所有枚举出的请求塑形参数。gpt-5.5与gpt-5.5-mini必须哈希不同——这正是双指纹拆分要捕获的漂移。env_matches(other)用于确认一份结果确实来自某个环境定义两边任一指纹为None都返回False避免两个 None 相等的假绿。任何指纹组件失败如 REPL 中定义的无源码函数、不可序列化值都会抛FingerprintError而 runner 会捕获并降级为None加警告——指纹永远不应当使一次运行崩溃。运行方式与前置条件三份脚本的运行命令见 README.mdpython cookbook/environments/_01_first_environment/basic.py python cookbook/environments/_01_first_environment/with_summary.py python cookbook/environments/_01_first_environment/with_fingerprints.py前提条件需要设置OPENAI_API_KEY环境变量。示例中的所有模型调用均使用OpenAIResponses且模型 id 为gpt-5.5并搭配reasoning_effortlow因此需要 OpenAI 兼容的gpt-5.5访问能力TEST_LOG.md 记录了在 Agno 2.7.4 / 2.8.0 源码下对gpt-5.5的实测结果三个脚本均通过且 12/12 尝试全部被评分、无未评分项。底层原理run_rollouts 的关键机制run_rollouts的完整签名runner.pyasync def arun_rollouts(env, *, k8, tasksNone, modelNone, concurrency4) - EnvironmentRunResultrun_rollouts是其同步门面内部asyncio.run且拒绝在已运行的事件循环中调用。k默认 8concurrency默认 4tasks可从env.tasks中筛选子集须保持环境身份重建的任务会被拒绝model可覆盖采样模型——被覆盖时以实际生效模型计算策略指纹避免结果盖着声明模型的戳、跑的却是别的模型。尝试级隔离没有开关、永远生效源码最强调的设计是每次尝试无条件隔离且没有任何关闭开关。每个尝试要么是环境工厂agent()的新产物、要么是env.agent.deep_copy()的深拷贝随后_isolate_attempt通过输入置换完成隔离runner.py全新用户世界每个尝试拿到全新的InMemoryDb与全新用户 idrollout-user-uuid会话历史、记忆、会话摘要等按用户隔离的状态全部为空——尝试之间互不污染也不会污染你的真实数据响应缓存关闭所有模型槽位主模型、*_model字段、fallback 列表、各 manager 的模型都运行在关闭缓存的副本上因为命中缓存的尝试是重放不是采样写路径被切断记忆捕获、知识写工具、学习learning提取与保存工具、会话摘要写入、save_response_to_file全部被禁用K 次并发尝试若写入同一文件会互相竞争全局只读路径保留知识检索走knowledge.vector_db而非agent.db因此 RAG Agent 在滚动内可以正常检索学习learned-knowledge的读通过保留调用方 db 的写隔离副本继续存活其process/aprocess被替换为 no-op——源码注释明确警告这是隔离写路径的唯一屏障。错误风暴中止如果一批运行的开头连续尝试以完全相同的错误失败典型的配置错误坏 key、不可达的 base_urlrunner 会提前中止整轮运行并标记stopped_earlyerror-stormrunner.py。该检查仅对单任务运行生效多任务按输入优先调度首个批次只覆盖一个任务单个任务前端失败不应牺牲其他健康任务且要求错误类型一致、数量达到下限max(concurrency, 4)避免把偶发抖动误判为系统性故障。MCP 工具与工厂环境对于携带MCPTools的活体 Agentrun_rollouts会在运行开始时直接拒绝deep_copy按引用共享 MCP 会话并发尝试会互相连接/关闭同一个会话导致整批尝试作废。正确姿势是使用工厂环境让每个尝试拥有独立连接environment Environment( namemcp-env, agentlambda: Agent(..., tools[MCPTools(...)]), ... )源码同时防御工厂闭包共享同一 MCP 实例与callable 工具工厂隐藏 MCP两种反模式均在第一个尝试运行前抛出RuntimeError。Agent 子类的深拷贝陷阱若env.agent是声明了**kwargs的Agent子类deep_copy会丢失所有字段——尝试可能采到与策略指纹不同的模型。runner 在隔离后校验实际模型 id若与指纹时模型不一致则报错并建议改用工厂环境runner.py。这是设计上的取舍活体 Agent 必须能安全深拷贝否则请使用工厂。适用场景与后续路线README 明确给出使用建议何时从本示例开始当一次成功的 Agent 运行不足以作为证据时。示例用简单锚点 校准过的链式算术制造分歧——若网格全满反而不能作为有用的可靠性示例继续前进当任务需要 id、元数据或随仓库提交的 JSONL 文件时进入_02_task_sets。Task.from_jsonlenvironment.py可从 JSONL 批量加载任务仅允许input、expected、id、metadata四个键任何未知键都会带行号报错边界说明逐轮turn-by-turn的在线奖励循环不属于本版本这些环境当前承担的是验证verification与数据集生成dataset generation两类职责。从仓库结构看_02_task_sets、_08_async_rollouts、_10_export_sft等Environments 模块是一个逐步深入的体系从本示例的最小网格延伸到带 id 与元数据的任务集、异步大规模滚动、以及 SFT 数据导出等生产化能力而本示例正是理解后续一切的基础入口。小结通过_01_first_environment的三个脚本你可以快速掌握 Agno 环境评测的最小闭环类型化输出 CodeScorer评分、Task/Environment组装、run_rollouts的 K 次滚动、summary()的稳定统计契约以及双指纹对测量装置与被测策略的忠实记录。配合 runner.py 的尝试隔离、错误风暴中止等实现细节你可以自信地把网格输出接入脚本与 CI让可靠性从一次抽样变成可复现、可对比、可改进的数字。【免费下载链接】agnoBuild, run, and manage agent platforms.项目地址: https://gitcode.com/GitHub_Trending/ag/agno创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

Windows 上 goose 的 Node.js 扩展报 “Node.js installer script not found” 怎么排查?

Windows 上 goose 的 Node.js 扩展报 “Node.js installer script not found” 怎么排查?

Windows 上 goose 的 Node.js 扩展报 “Node.js installer script not found” 怎么排查? 【免费下载链接】goose an open source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM 项目地址: https://g…

📅 2026/9/10 12:50:25
Ruffle:用 Rust 重写、免插件播放 SWF 的 Flash Player

Ruffle:用 Rust 重写、免插件播放 SWF 的 Flash Player

Ruffle:用 Rust 重写、免插件播放 SWF 的 Flash Player 【免费下载链接】ruffle A Flash Player emulator written in Rust 项目地址: https://gitcode.com/GitHub_Trending/ru/ruffle 硬盘里那批二十年前的 SWF 游戏,自 2020 年 Flash Player 退…

📅 2026/9/10 12:50:25
AI驱动的自动化逆向工程:提升反编译与漏洞挖掘效率

AI驱动的自动化逆向工程:提升反编译与漏洞挖掘效率

1. 项目概述 在软件安全分析和漏洞挖掘领域,逆向工程一直是核心技术手段。传统逆向工作高度依赖工程师的经验积累和手动分析,面对日益复杂的软件架构和海量代码库,这种工作模式正面临效率瓶颈。我们尝试将AI技术引入逆向工程全流程&#xff0…

📅 2026/9/10 12:50:25
MORE NEWS

更多资讯

📰

论文降重服务,真的靠谱吗?——从踩坑到建立可控流程的完整指南

引言:为什么降重服务让人又爱又怕? 每到毕业季,论文查重就成了悬在无数同学头上的达摩克利斯之剑。面对学校要求的重复率红线,不少同学把目光投向了市面上的降重或文本改写服务,希望在短时间内让论文顺利过关。 然而…

📰

Java构建开源物联网平台的核心架构与实战

1. 项目概述:为什么选择Java构建物联网平台? 在万物互联的时代,物联网平台作为连接物理设备与数字世界的桥梁,其重要性不言而喻。而Java凭借其独特的优势,成为构建物联网平台的热门选择。作为一个从业十余年的技术老兵…

📰

学生成绩预测机器学习系统:从数据清洗到Flask部署全流程

这个题目听起来像课程设计,但真正上手以后我发现它远比“做一个预测”要复杂。核心不只是调一个机器学习模型,而是要把数据处理、特征工程、算法对比、系统封装串成一条完整链路。我做了两版才跑通全流程,这篇文章把思路、代码、踩过的坑全部…

📰

libcurl 详解 CURLINFO_FILETIME_T:安全获取远端资源的修改时间(64 位时间戳)

libcurl 详解 CURLINFO_FILETIME_T:安全获取远端资源的修改时间(64 位时间戳) 【免费下载链接】curl A command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, H…

📰

Buck电路双闭环控制模型仿真研究(Simulink仿真实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 &#x1f381…

📰

用 Claude Code 的 /incident 命令建立结构化事故响应:devops-automation 插件实战指南

用 Claude Code 的 /incident 命令建立结构化事故响应:devops-automation 插件实战指南 【免费下载链接】claude-howto A visual, example-driven guide to Claude Code — from basic concepts to advanced agents, with copy-paste templates that bring immediat…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬