ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

agno 学习区(Learning Zone)任务筛选指南:用重复 Rollout 的通过率分歧定位策略边界

agno 学习区(Learning Zone)任务筛选指南:用重复 Rollout 的通过率分歧定位策略边界 agno 学习区Learning Zone任务筛选指南用重复 Rollout 的通过率分歧定位策略边界【免费下载链接】agnoBuild, run, and manage agent platforms.项目地址: https://gitcode.com/GitHub_Trending/ag/agno导读在基于 agno 环境agno.environments构建离线评测与数据筛选流水线时学习区Learning Zone是一种极具实操价值的任务选择策略对同一任务重复执行 K 次 rollouts保留那些通过率严格介于 0 与 1 之间的任务——它们既不是已被策略完全掌握饱和也不是当前策略完全无法触及绝望而是恰好位于模型能力边界上的含金量样本。本文以 cookbook/environments/_06_learning_zone/ 下的三个可运行示例为主线结合 agno 仓库中environments模块的源码实现讲解学习区的判定原理、API 用法、与饱和任务的对比实验以及它如何衔接 scorers、难度校准与 SFT 数据导出帮助你直接用这套机制沉淀更有信息增量的训练语料。什么是学习区0 pass_rate 1学习区的定义非常简洁在一组针对同一任务的重复尝试中若既有通过pass又有失败fail则该任务位于学习区。对于二元评分binary scorer每个 attempt 只产出对/错学习区恰好等价于0 pass_rate 1——既不是已被完全掌握pass_rate 1也不是始终失败pass_rate 0。这一判定在 agno 源码中由TaskResult.in_learning_zone属性直接实现见 libs/agno/agno/environments/runner.py#L79-L83property def in_learning_zone(self) - bool: Some scored attempts passed and some failed -- the task is neither saturated nor hopeless, so every failure has a passing attempt to contrast against. Unscored attempts are excluded, as everywhere. return 0 self.n_passed self.n_scored从源码可以提炼出三个关键语义基于 n_passed 与 n_scored 的原始计数而不是直接比较浮点 pass_rate。这意味着判定天然规避了浮点精度问题。未评分的尝试unscored被彻底排除。超时、运行错误等没有Score的 attempt 不进入统计更不会被强行为 0——源码注释明确指出a timeout is not a wrong answer超时不是错误答案见 runner.py#L66-L71。每个被保留的任务都至少包含一次失败的评分尝试因此其中的失败样本天然拥有一个可对照的通过样本——这正是后续构造 SFT 数据、做 prompt 改进时最理想的正反对照组。为什么不使用全通过或全失败的任务学习区的使用动机直接决定了筛选价值README 给出了清晰的说明cookbook/environments/_06_learning_zone/README.md全通过saturatedpass_rate 1的任务只是重复已有的能力几乎不增加新信息。它们适合作为锚点任务anchor验证运行管线本身工作正常但对策略改进没有增量。全失败pass_rate 0的任务可能超出了当前策略的能力边界属于跳一跳够不着的样本当前阶段对其投入 prompt 工程或示例往往性价比不高。因此学习区任务正是更多示例、prompt 打磨、数据集校验verified dataset curation最值得投入信号的地方。运行环境与前置知识运行命令README 给出了三个示例脚本的完整运行方式依赖OPENAI_API_KEYpython cookbook/environments/_06_learning_zone/basic.py python cookbook/environments/_06_learning_zone/select_middle_band.py python cookbook/environments/_06_learning_zone/saturated_tasks.py需要特别说明的是 README 强调的定位这是重复验证与任务选择repeated verification and task selection而不是实时的 RL 奖励循环live RL reward loop。学习区筛选服务于离线数据与评测闭环不会在运行中动态改变策略。与相邻模块的关系本目录构建在前置的评分器示例之上_03_code_scorer/用代码逻辑对输出做精确判定_04_judge_scorer/用大模型作为评判者_05_tool_call_scorer/对工具调用过程进行评分。学习区消费这些 scorer 产出的二元/数值评分而下一个目录_07_difficulty_calibration/则展示了如何把一个任务调整进这个区间即难度标定把任务难度校准到模型能力边界附近。示例一basic.py— 跑一个混合任务集并调用learning_zone()basic.py 是学习区的最短演示把同一组带类型约束的算术任务重复跑 K 次然后筛选出二元结果发生分歧的行。任务与评分器的构造class FinalInteger(BaseModel): value: int Field(descriptionThe final integer after every requested operation) def exact_integer(run, expected) - bool: return isinstance(run.content, FinalInteger) and run.content.value expected agent Agent( modelOpenAIResponses(idgpt-5.5, reasoning_effortlow), instructionsCalculate exactly. Return only the final integer in the response schema., output_schemaFinalInteger, )这里展示了一个完整的最小闭环模型通过output_schemaFinalInteger强制输出结构化整数评分函数exact_integer校验输出类型与数值是否完全一致返回布尔值。任务集刻意设计为锚点 边界混合easy-anchorMultiply 17 by 23.预期 391——极容易作为饱和锚点edge-e/edge-pi两个多步骤大整数运算先乘超大数、再求十进制数字和、再乘一个梅森素数、再取模——难度显著提升预期结果分别为 20944939 与 10481347正是设计来制造部分通过分歧的边界任务。CodeScorer接收这个布尔函数libs/agno/agno/scorer/code.py#L12。从源码看CodeScorer接受任何(run, expected) - bool | float | Score形式的可调用对象布尔值被映射为Score(1.0, True)或Score(0.0, False)此路径不查询pass_threshold浮点数则按value pass_threshold判定通过Score原样使用见 libs/agno/agno/scorer/code.py。评分结果Score.value始终落在 [0, 1] 区间libs/agno/agno/scorer/base.py#L27-L40。环境与 rollout 运行env Environment( namefirst-learning-zone, agentagent, tasks(...), scorerCodeScorer(exact_integer), ) if __name__ __main__: result run_rollouts(env, k4, concurrency4) print(result) zone result.learning_zone() print(Learning-zone rows:) for task_result in zone.task_results: print(f {task_result.task.id}: pass rate {task_result.pass_rate})Environment是 agno 环境系统的核心单元。从 libs/agno/agno/environments/environment.py#L88-L139 可以看到它是一个frozenTrue的 dataclass字段为字段类型说明namestr环境名称用于展示与结果标识tasksTuple[Task, ...]任务集每个Task含input、expected、id、metadatascorerScorer评分器把一次 run 变成ScoreagentAgent 或零参工厂每个 attempt 会被深拷贝live agent或调用工厂构建callabletimeout_secondsint 120单次 attempt 的超时上限run_rollouts的签名libs/agno/agno/environments/runner.py#L1221-L1243run_rollouts(env, *, k8, tasksNone, modelNone, concurrency4) - EnvironmentRunResultk每个任务重复执行次数示例中用 4默认 8tasks可选的子集选择必须来自env.tasks保持对象同一性model可选的模型覆盖必须传Model实例不支持字符串concurrency并发数。尝试隔离rollout 的统计纯净性保障run_rollouts有一个值得强调的底层保障每一次 attempt 都在完全隔离的环境里执行源码注释称之为unconditional, no knob。从 runner.py#L930-L980 和_isolate_attemptrunner.py#L763-L912可以看到具体做法每个 attempt 使用全新的内存数据库freshInMemoryDb和全新的 user/session id尝试之间互不污染所有模型槽位运行在关闭响应缓存cache off的副本上——因为缓存是按消息键控的共享磁盘缓存缓存命中的 attempt 是回放而非采样只切断写路径记忆捕获、知识/学习写入、会话摘要写入、save_response_to_file而知识读取等全局只读路径保留使 RAG 类 agent 在 rollout 内也能正常检索运行前会计算env_fingerprint环境指纹覆盖任务集、scorer、声明的工具 schema、prompt 字符串与 flag与policy_fingerprint策略指纹覆盖实际生效模型的身份并盖在结果上用于后续diff()的可靠对比。换句话说污染后的统计数字会错误地回答我的 agent 行不行污染后的轨迹则会毒化训练集所以隔离是强制且无开关的。learning_zone()返回什么EnvironmentRunResult.learning_zone()runner.py#L147-L156不是原地修改而是通过dataclasses.replace返回一个只保留学习区任务的过滤副本def learning_zone(self) - EnvironmentRunResult: return replace( self, task_resultstuple(task_result for task_result in self.task_results if task_result.in_learning_zone), )过滤副本保留了相同的指纹因此它上面的网格展示、summary()、导出器都能继续正常工作。由于保留的每个任务都至少含一次失败评分尝试这也直接保证了基于它的 SFT JSONL 导出默认only_passed语义安全。示例二select_middle_band.py— 把严格中间带过滤写显式select_middle_band.py 与basic.py几乎相同区别在于它不用learning_zone()方法而是用列表推导把 README 中的定义显式写出来middle_band [ task_result for task_result in result.task_results if task_result.pass_rate is not None and 0 task_result.pass_rate 1 ]这个写法把严格部分通过率这一标准直观地摆到明面上适合作为教学演示或对判定逻辑有自定义需求时的改造起点。注意它显式处理了pass_rate is not None从源码看当某个任务的n_scored 0全部 attempt 都未评分例如全部超时时pass_rate为Nonerunner.py#L66-L71此时0 pass_rate 1的比较必须跳过。任务集在此处命名为candidate-a / candidate-b与basic.py中的edge-e / edge-pi使用相同的大整数链式运算意图就是让这两个候选任务落在中间带上而easyMultiply 29 by 31.保持在饱和区。示例三saturated_tasks.py— 饱和任务与有效中间带任务的对比saturated_tasks.py 是一个对比实验README 对其动机的描述是easy 行证明 runner 能跑通但一排全绿的格子对策略边界毫无信息量。任务集被分成两组饱和组saturatedsaturated-17x23Multiply 17 by 23.和saturated-two-stepMultiply 127 by 89, then subtract 41.——策略几乎必然全对校准组calibratedcalibrated-edge-a、calibrated-edge-b——与前两个示例同款的链式大整数运算被校准到同一张网格里出现真正的分歧。脚本运行后直接打印全部任务行的 pass rate并给出明确提示print( Rows at 1.0 are anchors; rows strictly between 0 and 1 carry learning signal. ) for task_result in result.task_results: print(f {task_result.task.id}: pass rate {task_result.pass_rate})设计要点把 1.0 的饱和行保留为锚点anchor用于确认管线本身可靠同时持续校准更难的候选行直到同一张网格里出现真实分歧。锚点与学习区任务在同一环境中并存正是_07_difficulty_calibration将深入的主题——如何把任务移动进这个区间。从结果对象还能拿到什么统计与后续流水线run_rollouts返回的EnvironmentRunResult是一个信息丰富的 dataclassrunner.py#L86-L400在学习区筛选之外它提供了一系列与数据流水线直接相关的能力能力方法/属性用途汇总summary()返回 CI 契约级的 dictkey 固定env、k、n_tasks、n_attempts、n_scored、n_unscored、pass_rate、mean_value、两个指纹、stopped_early且每个任务行都带有learning_zone布尔标记对比diff(baseline)与同环境基线运行做逐任务 delta区分improved/regressed环境指纹不一致会抛MismatchError绝不静默配对错误行持久化save(path)/load(path)/ async 变体完整 JSON 往返保留每次 attempt 的 run、score、stop reason 等明细供二次分析与复跑对比证据检视print_report(onlyfailed, attemptsNone)逐 attempt 打印评分理由、工具执行、答案与 token 开销print_attempt(task_id, attempt)可单条完整回放错误归因errors()按任务 id 归组所有错误信息其中summary()返回的每个任务行都包含learning_zone: task_result.in_learning_zone因此即使不走learning_zone()方法也能从汇总 dict 中直接读取每个任务的学习区标记方便接入 CI 或后续的_10_export_sft等导出环节。实践建议与注意事项综合 README 与源码落地学习区筛选时有几点值得注意k的选择影响判定可靠性k4示例是快速验证默认k8能给出更稳定的 pass rate 估计学习区判定依赖多次重复的真实分歧k过小会放大随机性。区分未评分与失败超时/错误是n_unscored不参与pass_rate也不会把任务推入学习区。如果大量 attempt 都未评分应当先排查运行错误用errors()归因而不是急着调难度。锚点任务应保留全绿任务不是垃圾它们是管线正常性的探针。saturated_tasks.py展示的正确姿势是锚点 校准候选并存。需要OPENAI_API_KEY三个示例都通过OpenAIResponses(idgpt-5.5, reasoning_effortlow)调用 OpenAI 模型替换其他模型只需构造对应的Model实例传入Agent。这是离线验证不是 RL 奖励环学习区只负责挑选值得投入的任务策略的更新与难度调整在后续目录如_07_difficulty_calibration完成。小结学习区把这个任务值得更多投入吗这一问题变成了一个可计算的、基于重复 rollouts 的量化判定0 pass_rate 1。本文覆盖的三个示例分别演示了直接调用learning_zone()、显式手写中间带过滤和饱和任务对照实验三种用法而 agno 的源码为这一薄薄的概念提供了坚实的工程支撑——强制尝试隔离保证统计纯净、双指纹保证对比可复现、CodeScorer支持任意(run, expected) - bool | float | Score评分逻辑、EnvironmentRunResult的summary/diff/save让学习区筛选可以无缝嵌入 CI 与 SFT 数据导出流水线。当你面对模型为什么在这个任务上时好时坏的困惑时学习区就是定位那条能力边界的第一站。【免费下载链接】agnoBuild, run, and manage agent platforms.项目地址: https://gitcode.com/GitHub_Trending/ag/agno创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表