拓冰建站拓冰建站
首页 / 资讯中心 / 正文

agno Cookbook 实战:将评估基线持久化为 JSON——Saved Baselines 保存、重载与异步往返指南

agno Cookbook 实战将评估基线持久化为 JSON——Saved Baselines 保存、重载与异步往返指南【免费下载链接】agnoBuild, run, and manage agent platforms.项目地址: https://gitcode.com/GitHub_Trending/ag/agno本篇围绕 agno 仓库cookbook/environments/_13_saved_baselines/示例目录及其测试日志 TEST_LOG.md 展开讲解如何把一次 rollout 评估的完整结果含每次尝试的转录、评分与指纹保存为纯 JSON 基线并在新进程中重载验证其摘要与指纹的往返一致性。读完本文你能掌握result.save()/EnvironmentRunResult.load()及其异步孪生asave()/aload()的用法、JSON 工件的内部结构以及基线校准避免任务饱和的实操经验。Saved Baselines 要解决什么问题agno 的cookbook/environments/系列围绕Environment/Task/run_rollouts构建可重复的评估流程对每个任务运行 K 次尝试用CodeScorer等打分器逐次评分产出EnvironmentRunResult。基线baseline正是这样一个结果对象——它携带特定环境和策略下的完整证据。cookbook/environments/_13_saved_baselines/README.md 明确了两点使用前提适用场景当基线运行与候选candidate运行无法在同一个进程中完成或者 CI 需要一个经过人工审阅的参考工件reference artifact时就用 Saved Baselines 把第一次运行的结果落盘供后续运行逐任务对比边界警示基线是来自某个特定环境与策略的证据并不是对未来任务或提示词修改依然保持可比较性的承诺。README 同时强调保存的工件包含完整的提示词与响应应按敏感评估数据对待store it with the same care as the evaluated prompts。三个示例脚本分别是脚本职责basic.py运行环境并把结果保存为基线reload_baseline.py重载工件并验证其summary()往返一致async_save_load.py在事件循环内使用arun_rollouts/asave/aload运行环境与执行方式三个示例都依赖OPENAI_API_KEY并且统一通过OpenAIResponses使用gpt-5.5agent Agent( modelOpenAIResponses(idgpt-5.5, reasoning_effortlow), output_schemaAnswer, # class Answer(BaseModel): value: int )从仓库根目录执行python cookbook/environments/_13_saved_baselines/basic.py python cookbook/environments/_13_saved_baselines/reload_baseline.py python cookbook/environments/_13_saved_baselines/async_save_load.py测试日志记录这些示例于 2026-07-20 以OpenAIResponses(idgpt-5.5, reasoning_effortlow)完成验证。示例一basic.py —— 把一次完整 rollout 存为基线basic.py 的核心结构agent Agent( modelOpenAIResponses(idgpt-5.5, reasoning_effortlow), output_schemaAnswer, ) env Environment( namesaved-baseline-basic, agentagent, tasks( Task(idproduct-a, inputCompute 2718281828459045 times 1618033988749895. ..., expected20944939), Task(idproduct-d, inputCompute 2236067977499789 times 2449489742783178. ..., expected76998482), ), scorerCodeScorer(exact_value), ) baseline_path Path(__file__).parent / data / generated / baseline.json if __name__ __main__: result run_rollouts(env, k6) print(result) baseline_path.parent.mkdir(parentsTrue, exist_okTrue) result.save(baseline_path) print(fsaved {result.n_attempts} attempts to {baseline_path})关键点任务是大整数乘法 数字和 取模的确定性数学题expected固定因此CodeScorer(exact_value)用run.content.value expected做精确判定run_rollouts(env, k6)对 2 个任务各跑 6 次共产生 12 次尝试result.save(baseline_path)把整个结果写成 JSON 工件落在示例目录下的data/generated/baseline.json。TEST_LOG.md 对该脚本的验证结论Status: PASS。一次实时运行的 12 次尝试结果被存为纯 JSON 基线Resultproduct-a通过 3/60.50product-d通过 3/60.50全部 12 次尝试都写入了生成的基线工件Calibration校准最初的任务集是product-a、product-bk4两行都在 4/4 饱和saturated。为了让基线具备区分度把product-b替换为product-d并把 k 从 4 提升到 6之后才记录了本次 PASS。这段校准说明是本目录最有实操价值的经验任务太简单、通过率 100% 的饱和基线没有对比价值换题与加大采样次数 k 是标准手段run_rollouts的默认 k 为 8见 runner.py 中arun_rollouts(env, *, k: int 8, ...)的签名。示例二reload_baseline.py —— 重载并验证摘要往返一致reload_baseline.py 在保存之后立即做存-取往返校验result run_rollouts(env, k4) print(result) baseline_path.parent.mkdir(parentsTrue, exist_okTrue) result.save(baseline_path) loaded EnvironmentRunResult.load(baseline_path) assert loaded.summary() result.summary() print(freloaded pass rate: {loaded.pass_rate}) print(ffingerprints preserved: {loaded.env_fingerprint result.env_fingerprint})这里断言的是完整summary()结果相等而不只是单个通过率。summary()返回的是源码注释中明确标注CI 契约、键已冻结The CI contract; these keys are frozen的字典包含env、k、n_tasks、n_attempts、n_scored、n_unscored、pass_rate、mean_value、env_fingerprint、policy_fingerprint、stopped_early以及逐任务的id / pass_rate / mean_value / n_unscored / learning_zone实现见 runner.py 的EnvironmentRunResult.summary。测试日志中该脚本的结果Status: PASS。保存并重载基线后其完整summary()与活对象一致Resultproduct-a通过 2/40.50product-c通过 4/41.00聚合通过率 0.75两个指纹env 与 policy都完整通过了往返。指纹之所以重要后续跨进程对比时EnvironmentRunResult.diff()会先校验env_fingerprint是否匹配不匹配直接抛MismatchErrorthese results are not from the same environment见 runner.py。也就是说重载后的基线能否参与逐任务对比取决于指纹在 JSON 往返后是否原样保留——这正是 reload 示例断言两行输出pass rate 与 fingerprints preserved的原因。示例三async_save_load.py —— 异步孪生在同一事件循环内当宿主应用已经拥有事件循环时应使用异步孪生。async_save_load.py 的完整主流程async def main(): result await arun_rollouts(env, k4) print(result) baseline_path.parent.mkdir(parentsTrue, exist_okTrue) await result.asave(baseline_path) loaded await EnvironmentRunResult.aload(baseline_path) assert loaded.summary() result.summary() print(fasync round trip preserved {loaded.n_attempts} attempts) if __name__ __main__: asyncio.run(main())从 runner.py 的实现看asave与aload都是asyncio.to_thread包装的同步版本async def asave(self, path: Union[str, Path]) - None: Async twin of save. await asyncio.to_thread(self.save, path) classmethod async def aload(cls, path: Union[str, Path]) - EnvironmentRunResult: Async twin of load. return await asyncio.to_thread(cls.load, path)即 IO 被移出事件循环语义与同步路径完全一致。测试日志对该脚本的验证结论Status: PASS。在同一个事件循环内使用了arun_rollouts、asave、aloadResultproduct-a通过 3/40.75product-b通过 4/41.00异步往返保留了全部 8 次尝试和完整摘要。源码纵深JSON 工件里到底存了什么save()在 runner.py 中构建的 payload 结构format_version 1{ format_version: 1, env_name, k, env_fingerprint, policy_fingerprint, duration_seconds, stopped_early, task_results: [ { task: { id, input, expected, metadata }, attempts: [ { run: RunOutput.to_dict() 的完整转录 | null, score: { value, passed, reason, detail } | null, stop_reason, duration_seconds, error, tool_call_limit_hit, error_type }, ... ] }, ... ] }源码中有两处值得注意的工程细节先序列化、后开文件save()先json.dumps再open(path, w)因为open(w)会立即截断目标文件——如果 dumps 在截断之后才失败就会摧毁diff()所需的现有基线。序列化失败会抛出带定位信息的TypeError指明是哪一个任务的expected或metadata字段不可 JSON 序列化_name_unserializablerunner.py。加载时的版本校验load()读取format_version与当前构建支持的版本不符时抛出ValueError(unsupported format_version ...)runner.py。这为工件格式的未来演进留了显式失败点而不是静默读错。load()还会重建出与活对象同构的Task、AttemptResult含RunOutput.from_dict恢复转录、StopReason枚举还原、Score还原因此重载对象可以直接参与summary()、diff()、print_report()等后续操作。测试日志全景三个脚本的验证结论按 TEST_LOG.md 的原始记录汇总测试模型均为OpenAIResponses(idgpt-5.5, reasoning_effortlow)脚本状态任务通过率关键验证点basic.pyPASSproduct-a3/6 (0.50)、product-d3/6 (0.50)12 次尝试全部写入 JSON 工件此前 k4 时任务 4/4 饱和替换product-b为product-d并升 k 至 6reload_baseline.pyPASSproduct-a2/4 (0.50)、product-c4/4 (1.00)聚合 0.75完整summary()与活对象一致两个指纹往返保留async_save_load.pyPASSproduct-a3/4 (0.75)、product-b4/4 (1.00)异步往返保留全部 8 次尝试与完整摘要值得注意basic.py的校准记录揭示了一个迭代过程饱和基线两行 4/4被识别为不合格通过换题product-b→product-d和增大 k4 → 6恢复区分度后才记录 PASS。这与TaskResult.in_learning_zone属性部分通过且部分失败的 scored 尝试runner.py背后的理念一致既有失败又有成功的任务行才有对比与学习价值。限制与后续步骤可比性前提基线只对env_fingerprint相同的结果有效。diff()在指纹分叉时抛MismatchErrorpolicy_fingerprint变化如换模型、改指令本身不阻止对比但会体现在EnvironmentDiff.policy_changed标记上。敏感数据工件含完整提示词与响应转录README 明确要求按敏感评估数据处理落盘位置示例中为data/generated/下的 JSON应纳入相应的访问控制。下一步得到可重载的基线工件后继续 cookbook/environments/_14_environment_diff/ 对兼容结果做逐任务对比summary()的输出则是 CI 作业可直接消费的契约格式。【免费下载链接】agnoBuild, run, and manage agent platforms.项目地址: https://gitcode.com/GitHub_Trending/ag/agno创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门