FEATURED · 精选文章

agno Team 回答重生成(Regenerate)实战:重新生成团队最终回答而不重跑成员委派

发布时间 / 2026/9/9 12:28:17
来源 / 创域科博编辑部
栏目 / 资讯中心
agno Team 回答重生成(Regenerate)实战:重新生成团队最终回答而不重跑成员委派 agno Team 回答重生成Regenerate实战重新生成团队最终回答而不重跑成员委派【免费下载链接】agnoBuild, run, and manage agent platforms.项目地址: https://gitcode.com/GitHub_Trending/ag/agno团队型 Agent 在多次与用户交互时往往会出现委派结果都对但最后的总结答得不好的情形。agno 为 Team 提供了一等公民的Regenerate重生成能力通过Team.continue_run(..., regenerateTrue)只丢弃上一次运行末尾的纯文本回答保留中间全部工具交换即各成员 Agent 的委派结果用一个全新的run_id重新生成一份最终答案——成员不会被重复委派、中间结果不会被浪费。本文基于仓库中的 Team Regenerate 官方示例完整讲解它的触发方式、replace_original可见性语义、fork 血统与成员行的保留规则并下沉到 libs/agno/agno/team/_run.py 与 libs/agno/agno/run/team.py 的源码实现帮助你在自己的多 Agent 应用中安全地使用只重写结论、不重跑过程。一、什么是 Team Regenerate能力边界一图看懂根据 24_regenerate 目录下的 READMEregenerateTrue的语义可拆成三点只丢弃尾部的助手回答Team 运行中会产生多条消息其中末尾那一条不含任何 tool_calls 的纯文本 assistant 消息就是最终总结。Regenerate 只把它丢掉。保留中间工具交换成员委派在 Team 视角下就是调用了一个工具成员输出以 tool-role 消息形式出现在 Team 会话中。这些中间消息原样保留因此成员委派不会重新执行模型基于同一份委派结果生成全新总结。总是 fork重生成不是在原 run 上原地改写而是产生一个新的run_id与全新的RunMetrics源 run 永远被保留在存储中。一句话概括Regenerate 同样的事实成员输出换一种说法新的最终总结。二、运行前准备与示例文件结构示例位于 cookbook/03_teams/24_regenerate/01_regenerate.py该目录同时包含 TEST_LOG.md 用于记录验证状态。运行方式.venvs/demo/bin/python cookbook/03_teams/24_regenerate/01_regenerate.py需要注意两点前提示例使用OpenAIResponses(idgpt-5.4)依赖OPENAI_API_KEY环境变量据 TEST_LOG 记录该脚本在无 Key 环境下仅做语法/编译校验Status: NOT RUN。Regenerate 依赖会话持久化成员与 Team 都配置了SqliteDb该功能建立在 23_checkpointing 团队断点续跑 基础之上README 亦明确标注 Foundation 为该目录。三、分步实战原始运行 → Regenerate → 会话检查示例脚本演示了旅游问答团队天气 人口两个子 Agent的完整重生成链路值得逐段拆解。3.1 构造成员与团队含持久化weather_agent Agent( nameweather-agent, roleAnswers weather questions., modelOpenAIResponses(idgpt-5.4), tools[get_weather], dbSqliteDb(session_tableteam_demo, db_fileDB_FILE), ) population_agent Agent( namepopulation-agent, roleAnswers population questions., modelOpenAIResponses(idgpt-5.4), tools[get_population], dbSqliteDb(session_tableteam_demo, db_fileDB_FILE), ) team Team( nametravel-team, modelOpenAIResponses(idgpt-5.4), members[weather_agent, population_agent], dbSqliteDb(session_tableteam_demo, db_fileDB_FILE), instructions( Delegate weather questions to weather-agent and population questions to population-agent. Summarize in one sentence. ), )要点三个对象共享同一个SqliteDb(session_tableteam_demo, db_fileDB_FILE)其中DB_FILE ftmp/team_regenerate_{int(time.time())}.db按时间戳生成独立库文件便于反复试验团队成员get_weather/get_population是纯内存 mock 函数Paris/Tokyo/Lagos 三城市确保流程可离线重现。3.2 STEP 1创建原始 runoriginal await team.arun( inputWhats the weather and population of Paris?, session_idteam-sess-1, ) print(f run_id: {original.run_id}) print(f content: {original.content})这一轮中Team 的模型循环会依次把问题委派给weather-agent与population-agent两个成员的返回以 tool-role 消息沉淀进会话最后模型生成一句总结。返回的original.run_id是后续重生成的源坐标。3.3 STEP 2带转向指令的 Regenerateforked await team.acontinue_run( run_idoriginal.run_id, session_idteam-sess-1, regenerateTrue, additional_instructionsThis time, only mention weather. Skip population., ) print(f run_id: {forked.run_id} (new)) print(f forked_from_run_id: {forked.forked_from_run_id}) print(f regenerated_from: {forked.regenerated_from}) print(f content: {forked.content})这是全篇最关键的一次调用注意三个细节同步 API 是team.continue_run(...)异步 API 是team.acontinue_run(...)两者的方法签名在 libs/agno/agno/team/team.py 中成对出现continue_run定义在 1113 行附近acontinue_run定义在 1198 行附近并都接受regenerate、replace_original、additional_instructions、input、continue_from、fork等快照分发参数。regenerateTrue触发重生成additional_instructionsThis time, only mention weather...提供转向指引代码注释称之为steering转向——不传时则按原样重述一次结论。结果对象forked同时携带两类血统字段forked_from_run_id来自 fork 机制与regenerated_from专用于标识从哪个 run 重生成而来都指向源 run。3.4 STEP 3会话内验证明细session team.db.get_session(session_idteam-sess-1, session_typeteam) team_runs [r for r in (session.runs or []) if hasattr(r, member_responses)] agent_runs [r for r in (session.runs or []) if not hasattr(r, member_responses)]脚本用是否含member_responses字段区分 Team 行与成员 Agent 行然后打印两类结论Team 行 2original fork且都持久化源 run 与重生成 run 各自作为一条独立 run 记录存在用forked_from_run_id前缀输出能看出从属关系。成员行 0 新增成员 run不会被克隆仍然挂在原始 Team 之下通过parent_run_id标识其归属。这正是 Regenerate 与整段复制的分水岭已经发生的委派是历史事实fact of history不是需要拷贝的状态state to copy。README 的表述与脚本输出完全一致Member rows the original team produced stay attached to the original team。四、replace_original源 run 的可见性开关README 明确指出 Regenerate总是 fork——新run_id 新指标源 run 永远保留。那么重生成后旧的总结还显不显示就由replace_original控制它只影响源 run 在历史中的可见性replace_original源 run 状态历史可见性典型用途True默认被标记为REGENERATED隐藏由新 run 顶替其位置旧答案作废只展示重写后的False保持COMPLETED保留两个尝试都显示AB 对比让用户/裁判选择结合源码libs/agno/agno/team/_run.py 的_normalize_regenerate_params_team7252 行起还会做这些一致性校验replace_original只在regenerateTrue时有意义否则抛ValueError(replace_original only makes sense with regenerateTrue)regenerateTrue时不允许再传forkTrue——因为是否 fork已由replace_original推导README 注释称之为1-run-1-loop invariantregenerateTrue要求调用前已加载到目标 run 的run_response否则无法计算截断点additional_instructions与input互斥二者只能选其一作为转向输入。五、源码深读截断点如何计算、成员为何不被重跑5.1 边界计算_find_regenerate_checkpoint_teamRegenerate 的落点是一个消息截断索引由 libs/agno/agno/team/_run.py 中的_find_regenerate_checkpoint_team7158 行起计算messages run_response.messages or [] i len(messages) while i 0 and messages[i - 1].role assistant and not messages[i - 1].tool_calls: i - 1 if i 0: raise ValueError(Cannot regenerate: team run has no non-assistant messages to regenerate from.) return i逻辑是从消息尾部向前扫描凡是assistant 角色且不含 tool_calls的消息一律剔除这通常正是末尾的最终总结中间推理性质的 assistant 消息同理被剥掉遇到第一条带工具调用的 assistant 消息或非 assistant 消息即停。因此成员委派对 Team 而言就是工具调用及其 tool-role 结果消息全部留在边界之前。值得对照的是同一文件中的_find_last_user_message_index_team7177 行起它对应continue_fromlast_user的语义——回退到最后一条 user 消息把其后的中间工具交换也一并丢弃。源码 docstring 明确点出二者差异last_user与regenerateTrue语义不同前者把中间工具调用也丢掉。也就是说continue_fromlast_user→ 从用户提问后整段重来重跑委派regenerateTrue→ 只重写末尾总结不重跑委派。5.2 fork 血统与成员引用Team 行的深拷贝成员行的零拷贝_resolve_continue_from_team里regenerateTrue会自动推导边界不允许手工指定continue_from否则报错。而真正执行时fork 出的新 run 会携带两类血统字段它们定义在 libs/agno/agno/run/team.py 的 TeamRun 模型上810–819 行附近forked_from_run_id/forked_from_message_indexfork 血统与截断坐标regenerated_from本 run 由哪个 run 重生成而来即父 run 的run_id。关于成员数据的处理01_regenerate.py 顶部的 docstring 说得非常直白fork 出的 Team 其member_responses字段引用deep-copy了同一份成员数据但不会向会话写入任何新的成员 run 行。这与 Agent fork 不克隆工具执行行完全对仗——成员之于 Team就像工具之于 Agent是一个被调度的资源而非被复制的状态。同时深拷贝也保证了 fork 无法污染源数据。5.3 状态流转与默认替换regenerateTrue且未显式关闭替换时源码在写新 run 的同时会调用_mark_team_run_regenerated7354 行起把父 run 状态翻转为RunStatus.regenerated并持久化使历史构建器history builders在拼上下文时跳过它——这正是replace_originalTrue默认行为的落点。示例代码forked_from_run_id[:8]与 run 状态的一并打印可以让开发者直接观察这条状态变迁。六、同步/异步双 API 与团队模型循环语义Regenerate 是/continue快照分发能力snapshot dispatch的一部分参数在 libs/agno/agno/team/team.py 的continue_run与acontinue_run中被透传continue_run同步1078–1160 行签名区可直接传入上次的run_response或以run_id session_id定位acontinue_run异步1163–1247 行签名区同样的参数集适用于async def main()场景示例即采用此写法最后以asyncio.run(main())收尾。无论哪种形态重生成都是让 fork 出的 Team 用新的run_id重放 Team 自己的模型循环仅一次模型循环 复用既有成员输出因此 fork run 会获得一套全新的RunMetricstoken 消耗、耗时、工具调用数等便于与原始 run 做质量对比。七、成员为何不在作用域内与 Agent 面的 Parity 设计整个 Regenerate 机制最核心的设计决策是members are out of scope。团队断点checkpoint只作用于 Team 自身的状态——从 Team 视角看成员只是它委派出去的工具成员的输出只是会话中一条 tool-role 消息。这一点在 23_checkpointing 的 README 中被表述为 Fork / regenerate / time-travel operate on the teams own state, not member state。由此带来一个工程师必须养成的习惯如果你希望重生成时连委派过程一起重来那不应使用 Regenerate而应使用同目录族的time-travel / fork / 新的 run能力详见 03_teams 下的25_time_travel/与26_fork_session/兄弟目录。Regenerate 的适用场景非常聚焦委派结果有效、需要换一种总结口径或修正措辞——例如示例中这次只提天气、跳过人口的转向需求。八、测试支撑与验证手段该功能不是孤例代码而是有系统化单测覆盖的单元测试位于 libs/agno/tests/unit/team/test_team_checkpointing.py其中TestTeamRegenerateSugar与TestRegenerateSugarNormalization两组用例分别覆盖重生成语法糖的端到端行为与参数规范化/校验TEST_LOG 说明 01 号脚本在无 Key 环境下仅做语法/编译验证其运行时行为交由上述单测保障。因此即便你的环境没有模型 API Key也可以先跑单测确认 Regenerate 语义再配置OPENAI_API_KEY后运行示例脚本做端到端观察。推荐关注的输出点有三个forked.run_id ! original.run_id、forked.regenerated_from original.run_id、以及会话中 Team 行数变为 2 而成员行数不变。结语Team Regenerate 是 agno 把Agent 的 fork/regenerate 能力推广到多 Agent 团队后的自然延伸它通过只截断无工具调用的尾部助手消息实现低成本改写通过总是 fork 源 run 保留保证可追溯通过成员行不克隆守住已发生的委派是事实的边界。配合replace_original开关你既可以旧答案作废、新答案顶上也可以两次尝试并存、供人审阅对比。在需要反复打磨团队最终输出、又不想为每次微调都付出整轮委派成本的生产场景里这是一个值得优先纳入工具箱的 API。【免费下载链接】agnoBuild, run, and manage agent platforms.项目地址: https://gitcode.com/GitHub_Trending/ag/agno创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻