ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

DeerFlow 子代理卡片实时元数据:在折叠卡片上展示有效模型与累计 Token 用量的完整设计方案

DeerFlow 子代理卡片实时元数据:在折叠卡片上展示有效模型与累计 Token 用量的完整设计方案 DeerFlow 子代理卡片实时元数据在折叠卡片上展示有效模型与累计 Token 用量的完整设计方案【免费下载链接】deer-flowAn open-source long-horizon SuperAgent harness that researches, codes, and creates. With the help of sandboxes, memories, tools, skill, subagents and message gateway, it handles different levels of tasks that could take minutes to hours.项目地址: https://gitcode.com/GitHub_Trending/de/deer-flow本文基于 DeerFlow 仓库中的规划文档 plans/subagent-card-runtime-metadata.md 展开解读在折叠状态的子代理subagent卡片上实时展示有效 LLM 名称与累计 Token 用量这一特性背后的架构决策、三阶段实施计划与验收标准并结合仓库源码SubagentTokenCollector、status_contract、step_events、task_tool与前端subtask-result.ts说明每个设计点是如何落地、如何保持向后兼容的。读完后你将理解为什么运行期元数据必须按累计快照而非增量下发、为什么以task_id为键、以及终端状态持久化如何做到不新增数据库迁移即可回放。背景折叠卡片上的两个实时信号DeerFlow 的 Lead Agent 可以通过task工具把子任务委派给子代理并行执行。用户在前端工作区看到每张子代理卡片时可以将其折叠——此时卡片不再展示完整过程但仍需要回答两个问题这个子代理正在用哪个配置的 LLM 执行模型身份Model Identity它目前消耗了多少 Token累计用量Cumulative Token Usage规划文档的来源需求是Conversation request approved on 2026-07-10 — show live token usage and the effective LLM name on collapsed subagent cards。围绕这一需求文档给出了完整的架构决策集与分阶段Phase 1/2/3的建设内容和验收标准。架构决策八条不变量原文档 Architectural decisions 一节是整个方案的灵魂逐条对应了仓库中的具体实现约束运行时身份Runtime identity所有元数据更新都按键控于既有的子代理task_id因此同一个 Lead Agent 回合内的并行委派彼此隔离。在 frontend/src/core/tasks/subtask-result.ts 中可以看到前端以SUBAGENT_MODEL_NAME_KEY subagent_model_name与SUBAGENT_TOKEN_USAGE_KEY subagent_token_usage为键从结构化元数据中读取正是这套键控协议的前端镜像。用量模式Usage schema运行期负载携带累计的input_tokens、output_tokens、total_tokens。它们是快照snapshot而不是增量delta因此重放的或乱序到达的流帧不会造成重复计数。这正是前端把快照作为权威累计值合并进任务状态这一设计的前提。更新节奏Update cadence实时指的是每次子代理 LLM 响应完成后。大多数 Provider 在响应完成前不会暴露权威用量因此不存在响应中部的用量帧。模型身份Model identity线上契约wire contract携带的是为子代理解析出的有效 DeerFlow 模型名。UI 优先展示配置中的显示名display name取不到时回退到原始模型名Provider 的部署标识只作为观测数据不作为卡片主标签。实时与持久来源自定义任务生命周期事件custom task lifecycle events驱动运行中更新终态 ToolMessage 元数据从 checkpoint 化的聊天历史中恢复相同取值持久化的subagent.end事件保留终态快照供审计/调试消费者使用。兼容性Compatibility所有协议新增字段都是可选的。旧 run 渲染时没有运行元数据缺失的 provider 用量渲染为不可用而不是 0既有 JSON 负载是增量式扩展不需要数据库迁移。既有总额不动Existing totals父 run 与线程thread的 Token 记账保持不变卡片元数据只是一个展示投影presentation projection绝不能把用量第二次上报给RunJournal。特性开关Feature gateToken 渲染遵循既有的token_usage.enabled配置即使 Token 渲染被禁用模型身份仍然可以展示。Phase 1实时模型身份用户故事用户可以折叠一个正在运行的子代理卡片并立即看到是哪个配置的 LLM 在执行它。建设内容规划要求把有效的子代理模型名通过 task-start 生命周期事件传递出去并按task_id合并进任务状态在工作区解析友好模型显示名在折叠卡片头部渲染且不挤占既有状态指示器。源码印证在 backend/packages/harness/deerflow/tools/builtins/task_tool.py 中可以看到落地路径工具入口先通过resolve_subagent_model_name(config, parent_model, app_config...)定义于 backend/packages/harness/deerflow/subagents/config.py解析出effective_model随后在发出的task_started自定义事件 chunk 中携带model_name: effective_model。执行器一侧同样持有该名字——backend/packages/harness/deerflow/subagents/executor.py 中SubagentExecutor初始化时self.model_name resolve_subagent_model_name(config, parent_model, app_configapp_config)并用它构建实际create_chat_model(nameself.model_name, ...)。也就是说卡片上展示的名字与真正发请求的模型来自同一个解析结果不会出现展示与执行漂移。验收标准原文档完整保留运行中的折叠卡片在 task-start 事件到达时立即显示其有效模型使用不同模型的并行子代理在各自的卡片上显示正确的模型配置了显示名的模型优先展示显示名未知模型回退到原始标识不带模型字段的旧任务事件仍能正常渲染。Phase 2实时累计 Token 用量用户故事用户观察一个折叠且正在运行的子代理卡片能在每次子代理 LLM 调用完成后看到 Token 总量增加。建设内容规划要求在子代理运行期间发布采集器collector最新的累计用量快照并把它挂到任务进度事件上前端把快照合并进任务状态作为权威累计值然后在模型标签旁渲染格式化后的总量。同时要保留父 run 的既有记账路径不新增任何一次记账写入。源码印证SubagentTokenCollector 如何产出快照快照的生产者是 backend/packages/harness/deerflow/subagents/token_collector.py 中的SubagentTokenCollector它是一个 LangChainBaseCallbackHandler每次子代理执行创建独立实例caller标识归属on_llm_end中用_counted_run_ids集合按run_id去重保证同一次 LLM 调用的重复回调不会双计——这对应架构决策中重放/乱序帧不会双计的底线每条记录携带source_run_id、caller、真实产出的model_name从response_metadata读取用于父日志按真实模型分桶而不是用 Lead Agent 的模型、input_tokens、output_tokens、total_tokens以及稀疏存在的cache_read_tokens仅当 Provider 报告了缓存命中才写入与父日志按模型分桶的稀疏结构一致total_tokens缺失时回退为input output两者都非正数的响应直接跳过不伪造 0。在 executor.py 中每次 LLM 响应完成后调用collector.snapshot_records()将最新累计记录写入共享的SubagentResultupdate_token_usage_records下一个task_running事件携带该快照折叠卡片即可无记账副作用地更新。子代理结束后记录经RunJournal.record_external_llm_usage_records一次性移交父日志完成唯一一次正式记账——这正是卡片是投影、不做第二次记账的实现保障。验收标准原文档完整保留首次完成的子代理 LLM 调用在用量可用时把折叠卡片从采集中更新为非零总量后续调用用新的累计总量替换卡片快照而不是把总量再加一次重放的、重复的或更早的进度事件绝不双计或使显示总量减小并发子代理按task_id保持相互独立的总量省略用量元数据的 Provider 显示不可用/采集中状态绝不显示伪造的 0。Phase 3终端持久化与边缘路径用户故事无论完成、失败、取消、超时还是页面刷新用户看到的最终模型与 Token 用量都一致。建设内容规划要求把最终模型与累计用量戳入既有结构化任务 ToolMessage 元数据和持久化的subagent.end事件让历史重建逻辑学会读取这些可选元数据实时快照与终态历史收敛到同一个任务模型上覆盖所有终态状态并安全地容忍遗留/畸形元数据。源码印证一ToolMessage 元数据契约backend/packages/harness/deerflow/subagents/status_contract.py 定义了跨前后端的结构化结果元数据契约其中与本特性直接相关的字段subagent_model_name可选本次委派 run 使用的有效 DeerFlow 模型标识subagent_token_usage可选Provider 报告时的最终累计input_tokens/output_tokens/total_tokens快照。两个值得注意的工程细节make_subagent_additional_kwargs在生产边界校验status不在枚举内或stop_reason不在{token_capped, turn_capped, loop_capped}内会直接抛ValueError——拼写错误必须在生产端就失败而不是以缺失元数据的形式悄悄漏给消费者normalize_token_usage是两个元数据表面的唯一共享校验器终态 ToolMessage 元数据与持久化的subagent.step/subagent.end事件要求三个键全部为非负int显式拒绝bool任何非 Mapping 或畸形输入返回None——Provider 没有用量时字段整体缺席前端据此渲染不可用而不是 0。枚举值本身由跨语言共享夹具 contracts/subagent_status_contract.json 钉住completed/failed/cancelled/timed_out/polling_timed_outPython 侧SUBAGENT_STATUS_VALUES与 TypeScript 侧通过契约测试互相锁定。源码印证二subagent.end 事件保留终态快照backend/packages/harness/deerflow/subagents/step_events.py 的subagent_run_event负责把task_*自定义流块映射为RunEventStore的持久化 kwargstask_started→subagent.starttask_running→subagent.step经build_subagent_step截断到SUBAGENT_STEP_MAX_CHARS 8192防止一次大write_file产生无界行task_completed/task_failed/task_cancelled/task_timed_out→subagent.end其content在task_id与status之外额外携带可选的model_name与usagemodel_name经非空字符串校验后写入usage经normalize_token_usage归一化后写入畸形则整字段缺席大块result/error文本按SUBAGENT_STEP_MAX_CHARS截断并打result_truncated/error_truncated标志保证持久化行有界。这些事件挂在专门的subagent类别下见SUBAGENT_EVENT_CATEGORY因此不会混入list_messages线程消息流只通过list_events暴露给前端展开时按需回填fetch-on-expandlist_events支持按metadata[task_id]过滤加after_seq前向游标分页——卡片按单个子代理翻阅步骤时不会被 run 级limit截断尾部且全程无 schema 迁移过滤复用既有 run 级索引。源码印证三前端读取路径frontend/src/core/tasks/subtask-result.ts 从additional_kwargs读取subagent_model_name/subagent_token_usage经由normalizeTokenUsage见 frontend/src/core/messages/usage.ts与实时事件流合并到同一任务模型上完成live 与 durable 收敛。验收标准原文档完整保留完成、失败、取消、超时的卡片都保留其最终模型与用量重新加载线程时从常规消息历史恢复元数据不需要每张卡片一次请求持久化的subagent.end事件包含相同的终态快照供审计/调试使用不带元数据的遗留卡片、以及没有用量的 Provider保持可读并显式显示不可用状态右侧线程 Token Usage 总额保持不变且子代理用量仍只被计数一次后端测试、前端单测、类型检查、格式化与相关回归套件全部通过。兼容性与边缘设计为什么全部可选是硬约束这份规划最值得沉淀的经验是它对兼容性的系统性处理仓库中多处可见其对应实现增量式 JSON 扩展零迁移subagent.end的content只是在既有{task_id, status}上追加可选键ToolMessage 的additional_kwargs同理。旧数据、旧前端读取时看不到新字段即按不可用渲染没有任何读路径依赖新字段存在。缺失 ≠ 0normalize_token_usage返回None的语义是Provider 没报前端据此渲染 collecting/unavailable 状态SubagentTokenCollector侧也跳过total_tokens 0的响应。两处一致避免了伪造的零污染成本曲线。累计快照 run_id 去重因为线上是累计值合并策略天然幂等——重复帧、重放帧、乱序帧都不会改变取最新累计值的语义_counted_run_ids去重与前端替换而非累加的合并逻辑互为补充把双计风险分别堵在生产端与消费端。投影不记账卡片消费的是SubagentResult上共享的快照与subagent.end事件正式记账只发生在子代理结束时向RunJournal的一次性移交record_external_llm_usage_records右侧线程总额因此不受卡片渲染开关影响。遗留值归一化status_contract.py中的read_subagent_result_metadata对历史上已 checkpoint 进线程历史的max_turns_reached等已停产状态值做了读侧归一化映射为turn_capped避免历史数据在新版本下悬空为 in-progress——这是容忍遗留/畸形元数据的具体形态。关键文件索引关注点文件方案与验收标准plans/subagent-card-runtime-metadata.mdToken 快照采集backend/packages/harness/deerflow/subagents/token_collector.py元数据契约与校验器backend/packages/harness/deerflow/subagents/status_contract.py事件构建与 subagent.end 持久化backend/packages/harness/deerflow/subagents/step_events.pytask_started 携带模型名backend/packages/harness/deerflow/tools/builtins/task_tool.py模型解析backend/packages/harness/deerflow/subagents/config.py跨语言枚举夹具contracts/subagent_status_contract.json前端读取与合并frontend/src/core/tasks/subtask-result.ts事件流文档backend/docs/RUN_EVENT_STREAM.md小结这份规划把折叠卡片上的两个实时信号拆解为一条清晰的链路SubagentTokenCollector按 run_id 去重产出累计快照 →task_started/task_running自定义事件携带模型名与用量按task_id下发 → 前端以替换语义合并并渲染 → 终态时戳入 ToolMessageadditional_kwargs并持久化进subagent.end事件 → 刷新后从历史事件恢复同一份快照。贯穿全程的四条不变量——累计而非增量、全字段可选、缺失渲染为不可用、投影不做第二次记账——使整个特性可以在不触碰数据库 schema、不破坏旧 run 回放的前提下平滑上线。【免费下载链接】deer-flowAn open-source long-horizon SuperAgent harness that researches, codes, and creates. With the help of sandboxes, memories, tools, skill, subagents and message gateway, it handles different levels of tasks that could take minutes to hours.项目地址: https://gitcode.com/GitHub_Trending/de/deer-flow创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表