尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

oh-my-pi task 工具全解析:子代理委派、批量扇出与隔离工作区实战指南

oh-my-pi task 工具全解析:子代理委派、批量扇出与隔离工作区实战指南 oh-my-pi task 工具全解析子代理委派、批量扇出与隔离工作区实战指南【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi本文以 oh-my-pi⌥ Coding agent with the IDE wired in中task工具的官方文档为主体系统讲解其批量tasks[]扇出、async.enabled后台执行、blocking: true内联执行、结构化输出、隔离工作区isolation与子代理生命周期管理并对照 packages/coding-agent/src/task/ 下的源码与 settings-schema.ts 中的相关配置项给出可直接复制运行的调用形态、参数语义与底层执行链帮助读者掌握在 oh-my-pi 中安全、高效地派生子代理并把控其产出质量。task是 oh-my-pi coding agent 的委派核心工具每一次调用可以派生一个子代理flat 形态也可以在一个调用内携带tasks[]批量扇出多个子代理batch 形态默认开启。它支持同步阻塞与后台异步两种执行模式、逐项独立指定 agent 类型与结构化输出契约、以及基于pi-natives隔离 PAL 的沙箱工作区isolation执行。读完本文你将能精确构造task调用参数、理解输出/进度/生命周期语义、配置隔离与并发上限并掌握通过hub、agent://、history://与已完成子代理交互的完整链路。概述一次调用 一个或多个子代理task工具的语义非常明确每个tasks[]条目派生一个子代理subagent每个子代理运行在一个全新的、独立的 childAgentSession中——它们不继承父会话的对话历史只能通过共享工作区树、skills、context files、local://根目录以及存在时的已批准计划引用获得上下文。核心入口在 task/index.ts模型侧提示词模板在 prompts/tools/task.md。从源码结构看task的调用形态由两个配置开关动态决定task.batch默认true启用 batch 形态{ context, tasks[] }一次调用对应 N 个子代理task.batch关闭退化为 flat 形态{ ...item }一次调用恰好派生一个子代理。两种形态在运行时都保持宽松兼容flat 形态即使在 batch 开启时也被接受供内部调用方与旧记录使用但模型永远只能看到其中一种形态——动态 schema 由 types.ts 中的getTaskSchema()依据isolationEnabled/batchEnabled/effortEnabled等组合生成。输入参数batch 形态与 flat 形态Batch 形态task.batch开启默认{ context: string, // 必填共享背景注入每个子代理系统提示词的 CONTEXT 段 tasks: [ // 必填每个元素对应一个子代理 { name?: string, // 稳定标识会成为 registry/IRC id省略则自动生成 AdjectiveNoun 名 agent?: string, // agent 类型省略则使用 spawn 策略默认 agent通常是 task task: string, // 必填完整、自包含的任务指令 effort?: lo|med|hi, // 仅当 task.enableEfforttrue 时出现 outputSchema?: ..., // 本次调用的结构化输出契约JSON Schema schemaMode?: permissive|strict, // 默认 permissive isolated?: boolean // 仅当 task.isolation.enabledtrue 且计划模式关闭时出现 } ] }Batch 形态的约束见 index.ts 中validateSpawnParams()context必填且非空每个条目的task必填且 trim 后非空提供的name在本次调用内必须唯一大小写不敏感顶层不能再出现task字段tasks与顶层task互斥context会原样进入每个子代理的系统提示词不要在每条task里重复共享背景。Flat 形态task.batch关闭{ name?, agent?, task, effort?, outputSchema?, schemaMode?, isolated? }此时tasks/context会被拒绝并从 schema 中移除。共享背景的推荐做法写入一个local://文件如local://ctx.md让每个 spawn 的task引用它——子代理共享父会话的local://根目录。参数明细表字段类型必填说明contextstring是batch共享背景经子代理系统提示词前置到每个 spawntask.batch关闭时被拒绝tasksarray是batch每个子代理一个条目提供的 name 在调用内唯一忽略大小写task.batch关闭时被拒绝namestring否稳定 agent 名成为 registry/IRC id缺省由AgentOutputManager生成 AdjectiveNoun 名并在会话内唯一化agentstring否该条目运行的 agent 类型如scout缺省为 spawn 策略默认 agent通常task同一 batch 内各条目可混用不同 agent 类型taskstring是工作指令必须完整、自包含trim 后为空会被拒绝effortlo \| med \| hi否仅当task.enableEfforttrue时出现。逐 spawn 思考强度映射到解析模型的最高/中/最低档如high/xhigh/max覆盖 agent 默认选择器包括auto。省略则保留 agent 配置的选择器——只有配置为auto的 agent如内置task才会逐提示自动分类scout/sonic配置为mediumoutputSchemaJSON Schemaobject \| boolean \| string \| null否调用级结构化输出契约优先级高于 agent frontmatteroutput与父会话继承的 schemaschemaModepermissive \| strict否生效输出 schema 的校验模式覆盖父会话模式默认permissiveisolatedboolean否在隔离工作区运行并返回补丁仅当task.isolation.enabledtrue且计划模式关闭时存在隔离 agent 完成后被拆除不可复活注意没有 wire 标签label字段。TUI/registry 中显示的单行 UI 标签由 tiny/title 模型从task文本自动生成fire-and-forget调用方从不提供它。同时不存在旧的 per-callschema参数——应使用outputSchema 可选schemaMode缺省时结构化输出依次回退到 agent 定义的outputfrontmatter、再到继承的父会话 schema。任务设计铁律来自模型侧提示词prompts/tools/task.md 明确了子代理指令的设计纪律Agent 类型要具体每个条目选最匹配的专用 agent只读调研必须交给scout跑在更快模型上见 prompts/agents/scout.md其 frontmatter 声明tools: read, grep, glob, web_search、model: smol、thinking-level: medium。只有当 spawn 策略默认 agent 恰好匹配时才省略agent绝不显式传默认 agent。零开销每条task必须指示 agent 跳过格式化器、linter 与全项目测试套件——最后统一跑一次。单趟完成优先让 agent 在一趟内调研 修改只有受影响文件确实未知时才派只读 scout。避免重叠并行化相互独立的模块所有权同一文件的并发编辑不保证可合并。若 IRC 可用让同辈 agent 在编辑共享文件前通过hub协调命名一个集成负责人只串行化不可简化的共享变更边界。并发 batch 有两个硬性前提① 每条 task 必须跳过构建/静态检查/测试避免中途验证互相阻塞② 跨任务契约如 A 实现的接口、B 消费的接口必须提前在 batchcontext或 flat 的task中写死留给 agent 自行协商是不允许的。task与context的推荐格式也由模板固定context用# Goal本 batch 达成什么/# Constraints规则与会话决策/# Contract共享接口三段task用# Target确切文件与符号、明确非目标/# Change逐步增删改、API 与模式/# Acceptance可观察结果不得含项目级命令三段。输出text 块 TaskToolDetails工具返回一个文本块外加details: TaskToolDetails。后台响应async.enabledtruecontent单个 spawn 返回Spawned agent(job). The result will be delivered when it yields. ...加一条协调提示消息可用时用hubDM否则用hub任务控制batch 调用返回Spawned N background agents using agent types. ...去重后的条目 agent 类型逗号连接以及逐 agent 的-(job)列表。details{ projectAgentsDir, results, totalDurationMs, progress: [AgentProgress per spawn], async: { state, jobId, type: task } }。整个调用共享一个progress[]快照async.jobId是第一个启动的 jobasync.state聚合所有后台 spawn每个 job 结算前为 running任一 spawn 失败则为 failed——在调用返回前已结算的 job 会反映在快照里。混合调用含阻塞条目的results携带阻塞 spawn 的内联SingleResult纯后台调用返回results: []。实时进度通过onUpdate(...)持续流入同一个工具块每个最终结果稍后以 async-result 注入父会话。投递文本追加后续提示id is now idle — message it via hub to follow up; transcript at history://idaborted 变体只指向 transcript。同步结算响应async.enabledfalse、无 job manager、或每个条目的 agent 都blocking: true、或 async job bodycontent由 prompts/tools/task-summary.md 渲染的摘要预览上限 5000 字符完整输出保存在agent://id。同步 batch 会拼接各 spawn 的摘要。details.results每个 spawn 一个SingleResultusage、outputPaths已填充同步 batch 跨 spawn 聚合。SingleResult 结构身份index、id、agent、agentSource、task、description、可选assignment内部负载名wire 字段为name/agent/task状态exitCode、可选error、可选aborted、可选abortReason、可选retryFailure输出output、stderr、truncated、durationMs、tokens、requests、可选contextTokens/contextWindow、usage模型可选modelOverride、resolvedModel、resolvedModelIsFallback结构化结果可选structuredOutput含 schema 来源/模式、校验状态、解析后的data、校验error产物元数据可选outputPath?、patchPath?、branchName?、branchBaseSha?、nestedPatches?、outputMeta?提取的工具数据可选extractedToolData?来自已注册的子进程工具处理器如yield。产物与旁路通道每个有 artifacts 目录的子代理都会写入id.mdagent://id解析到该文件。子代理自身的子代按点限定命名id.childagent://id/child读取嵌套输出。当路径不指向嵌套输出且文件是 JSON 时agent://id/path与agent://id?qquery执行 JSON 提取。父会话持久化 artifacts 时每个子代理获得id.jsonl会话历史history://id将其渲染为简明 transcriptlive 与 parked agent 均可用。隔离补丁模式在合并前写入id.patch。执行流从参数校验到生命周期收尾TaskTool.execute(...)的完整流程对应 task/index.ts 与 task/executor.ts创建期发现TaskTool.create(...)每个 cwd 通过进程级 memodiscoverAgentsForCreate发现一次 agent用于渲染动态提示词描述执行期发现保持新鲜。校验与归一化execute(...)先用repairTaskParams修复原始参数然后校验——schema永远拒绝tasks/context在task.batch关闭时拒绝batch 调用要求非空tasks每条目有task、提供的 name 唯一、非空共享context、且顶层不得有task与tasks并存flat 调用要求task。随后resolveSpawnItems(...)归一化为 spawn 列表。逐项执行分流agent 类型声明blocking: true的条目内联运行其余条目成为后台 job。当async.enabledfalse、会话没有AsyncJobManager孤立宿主、或每个条目都阻塞时整个调用同步运行内联 spawn 经#executeSync(...)在会话级信号量下执行。后台执行存在任一非阻塞条目且async.enabledtrue且有AsyncJobManager时agent id 先经AgentOutputManager.allocate(...)预分配每个条目的name或生成的 AdjectiveNoun 名每个 spawn 一个每个 spawn 向session.asyncJobManager注册一个type: taskjobid agent id、queued: true、ownerId 调用方 agent id工具立即返回每个 job body 获取会话级Semaphore每个TaskTool实例一个在每次 acquire/release 前按实时task.maxConcurrency就地 resize标记 job 运行用该 spawn 的参数执行#executeSync(...)并通过共享的buildAsyncDetails/onUpdate上报进度失败或中止的运行抛TaskJobError使 job 落入failed但 agent 本身仍保持注册、可被查询。混合调用先注册后台 job再内联运行阻塞条目并等其结算后返回——文本组合内联摘要与 spawn 列表工具块继续渲染仍在运行的背景行。spawn 路径#executeSync(...)运行#runSpawn会重新从磁盘发现 agent因此运行时解析可能与创建期描述不同解析每个 spawn 请求的agent类型拒绝未知或被设置禁用的 agent并强制父 spawn 策略与PI_BLOCKED_AGENT自递归防护。模型与输出 schema 优先级模型task.agentModelOverrides→ agent frontmatter → 配置的 task role/会话回退输出 schemaper-calloutputSchema→ agent frontmatteroutput→ 继承的父会话 schema。计划模式切换到带只读工具子集与计划模式提示词的effectiveAgentrunSubprocess(...)接收 effective agent。隔离执行isolated要求 git 仓库getRepoRoot(...)/captureBaseline(...)纯 Jujutsu 工作区会被明确拒绝并要求jj git init --colocate见 worktree.tsparseIsolationBackend把isolation.backend映射为后端种类提示经 natives PALensureIsolation→isoResolve/isoStart物化工作区后端不可用时遍历候选列表降级通过fellBack/fallbackReason上报。artifacts 目录来自父会话文件可用时否则用临时目录会话执行已批准计划时把计划引用交给子代理。子代理会话创建runSubprocess(...)创建带隔离设置快照的 child agent 会话——父设置被继承async.enabled与bash.autoBackground.enabled继承而非强制关闭tier.openai/tier.anthropic/tier.google经tier.subagent重新解析tools.approvalMode强制为yolo因为无头子代理没有 UI 可确认提示词advisor.enabled强制关闭除非该 agent 逐 spawn 选择加入per-spawn 覆盖可禁用读摘要化、为隔离运行清空额外工作区根childagentId等于分配的 id注入 child 内部 URL 路由器/AgentOutputManager、输出 schema、batch 调用共享的context系统提示词CONTEXT段与 IRC 同辈名册。子代理工具可用性显式agent.tools优先agent 有spawns且深度允许时自动加task在task.maxRecursionDepth处剥离task确保显式工具列表含hubexec展开为evalbash剥离父拥有的todo——除非该 spawn 已预走查prewalk武装其计划 nudge todo 门需要子代理在模型交接前提交自己的 todo 列表。收尾child 必须经隐藏的yield工具结束最多 3 条提醒提示词最后一条在支持时强制toolChoice yield。finalizeSubprocessOutput(...)调和原始文本、yield负载、结构化 schema 与 abort 状态。运行结束生命周期run finalizer 中keep-alive调用方信号、墙钟超时或内部硬中止 → registry 状态aborted会话销毁——终态非隔离 keep-alive agent 上的软请求预算中止 → 视为可恢复agent 变为idle可接收后续/复活隔离运行 → 状态parked且无 reviver工作区已合并清理会话不可复活transcript 经history://仍可读随后会话销毁并脱离其他一切成功与失败相同→ 状态idle且附着 live 会话AgentLifecycleManager.global().adopt(id, { idleTtlMs, revive })武装停车定时器reviver 重新打开会话 JSONL。此后生命周期idleagent 在task.agentIdleTtlMs默认 420_000ms 7 分钟后停车会话销毁保留AgentRef 会话文件消息hub或 Agent Hub 将其复活回idle。Main永不停车。模式与变体同步/后台、batch 开/关、隔离与合并执行模式后台 jobasync.enabledtrue非阻塞 spawn 走AsyncJobManager。同步内联async.enabledfalse、无 job manager、或条目 agent 声明blocking: true逐条目混合调用两种模式并存。Batch 模式task.batch默认开开{ context, tasks[] }——每个条目一个独立 spawn调用内共享必填contextagent、outputSchema、schemaMode逐条目effort仅当对应设置开启时出现isolated还要求计划模式关闭。生命周期、复活与并发语义等价于 N 个并行的单次调用。关每次调用恰好一个 spawntasks/context被拒绝并从 schema 移除effort/isolated同样条件性出现。隔离isolation由task.isolation.enabled启用isolation.backend可选auto、apfs、btrfs、zfs、reflink、overlayfs、projfs、block-clone、rcopyPAL 解析实际后端并带降级。默认auto由 PAL 选最佳可用后端。合并策略补丁模式捕获/应用根补丁git.patch.canApplyText(...)成功才应用失败保留.patch产物供手工处理或分支模式提交到omp/task/idcherry-pick 进父仓库——父仓库会在 cherry-pick 前临时 stashstash-pop 冲突不会撤销已落地的 cherry-pick冲突单独以stashConflict上报。嵌套 git 仓库在隔离工作区内独立 diff经applyNestedPatches(...)分别合并见 worktree.ts。Agent 来源优先级按名称精确匹配、first-wins项目.omp/agents→ 用户.omp/agent/agents→ OMP 扩展包agents/根CLI → 项目设置 → 用户设置 → 已安装 npm/link 插件顺序→ Claude marketplace 插件 agent项目先于用户→ 内置scout、reviewer、security-reviewer、task、sonic。直接.claude/agents、.codex/agents、.gemini/agents根会被跳过。创建期发现按 cwd memo 化仅用于提示词描述执行期发现始终新鲜。上述来源顺序与跳过规则见 discovery.ts 与 agents.ts。内置 agent 定义agents.ts 的EMBEDDED_AGENT_DEFSscout只读调研model: smol、thinking-level: mediumreviewer/security-reviewer代码审查与安全审查task通用 workerspawns: *、model: task、thinkingLevel: AUTO_THINKINGgeneric 的 prewalk 交接由task.prewalk默认关或/agentstask.agentPrewalk武装sonic低推理、纯机械更新/数据收集model: smol、thinkingLevel: medium。Prewalk 与 AdvisorPrewalkagent frontmatterprewalk或task.agentPrewalk[agentName]可在普通模型上开始、在首次编辑/写入时交接给更便宜的解析模型task.prewalk默认关为内置通用taskagent 武装此行为。缺失/未配置目标以及模型effort 完全相同的空操作会跳过交接而不是让 spawn 失败。Advisoragent frontmatteradvisor或task.agentAdvisor[agentName]on/off/模型模式为 child 会话配 advisor显式模式落到 child 的modelRoles.advisor。子代理默认无 advisor。副作用、资源与并发上限文件系统在会话 artifacts 目录或临时 task 目录写入id.jsonl与id.md隔离补丁模式写id.patch。创建/移除 worktree 或 overlay 挂载目录分支模式创建临时 worktree 与任务分支。网络Child 会话可使用其活动工具集允许的任何联网工具/模型。MCP 代理工具可调用既有父 MCP 连接超时 60_000ms。子进程 / native 绑定隔离后端经pi-nativesPALcrates/pi-iso运行Linux 上内核overlayfuse-overlayfs/fusermount[3]回退、APFS/Btrfs/ZFS/reflink 克隆、Windows 上 ProjFS、最后手段是递归复制rcopy。Git 操作基线捕获、补丁应用、worktree、分支、stash、cherry-pick、提交。会话状态创建带隔离设置快照的 childAgentSession完成的会话在进程全局AgentRegistry中保持idle/parked注册直到进程退出或显式释放。async.enabledtrue时每个 spawn 在session.asyncJobManager注册一个后台 job完成以 async-result 消息注入父会话。在AgentLifecycleManager武装 idle-TTL 定时器unrefd永不 hold 住进程。在父事件总线上发出task:subagent:event、task:subagent:progress、task:subagent:lifecycle。经AgentOutputManager分配会话级输出 id保证agent://跨调用唯一。与子代理共享父local://根与ArtifactManager。后台工作 / 取消hubcancel或父工具调用中止取消后台 job父工具调用中止经调用信号取消同步运行。硬中止的运行落入aborted并被拆除。缺失yield恢复最多向 child 会话发送 3 条内部提醒提示词。限制与上限Limits Caps逐 spawn effort 可选task.enableEffort默认false关闭时effort从动态模型侧 schema 中省略。并发一个会话级Semaphore在每次 acquire/release 前按实时task.maxConcurrency就地 resize然后约束跨并行task调用的并发子代理——后台 job body 与同步回退都会获取它。因此会话中途改设置会同时作用于新 spawn 与已排队在信号量上的工作。task.maxConcurrency默认 320表示无限。Idle TTLtask.agentIdleTtlMs默认 420_000ms7 分钟 0关闭停车idle 会话保持存活直到退出。逐子代理输出截断MAX_OUTPUT_BYTES 500_000与MAX_OUTPUT_LINES 5000定义在 task/types.ts可用环境变量PI_TASK_MAX_OUTPUT_BYTES/PI_TASK_MAX_OUTPUT_LINES覆盖。完整原始输出仍写入id.md。进度合并PROGRESS_COALESCE_MS 150近期输出尾部RECENT_OUTPUT_TAIL_BYTES 8 * 1024最后 8 个非空行。缺失 yield 提醒重试MAX_YIELD_RETRIES 3MCP 代理超时MCP_CALL_TIMEOUT_MS 60_000——两者都在 task/executor.ts。软请求预算task.softRequestBudget默认 200 次请求0关闭。跨越预算时在task.softRequestBudgetNotice开启下注入收尾提示预算 1.5× 时强制停止以产出部分发现。内置 scout/sonic 有更低的硬上限见 executor 中SOFT_REQUEST_BUDGET { scout: 100, sonic: 100, default: 200 }resolveSoftRequestBudget取两者更紧者。硬墙钟task.maxRuntimeMs作用于每个 spawn默认0关闭。递归深度门task.maxRecursionDepth默认 2tools/index.ts 在达到或超过限制时隐藏task工具runSubprocess(...)也在最大深度剥离 childtask访问。最终内联摘要预览fullOutputThreshold 5000字符task/index.tsagent://id指向完整产物。常见错误与排查参数校验失败以普通工具文本返回、results为空schema永不接受tasks/context在task.batch关闭时batch 调用缺失/空tasks、条目缺task、重复提供的 name、缺失共享context、顶层task与tasks并存flat 调用缺失/空task未知或被设置禁用的 agent 类型、spawn 策略拒绝、在隔离模式为none时请求isolated。其他错误形态无 git 仓库的隔离执行返回Isolated task execution requires a git repository. ...后端不可用时按 PAL 候选列表降级经fellBack/fallbackReason上报其他后端错误重抛耗尽所有候选时以降级原因报错。隔离基线过大 1GiB 未提交内容会抛IsolationBaselineTooLargeError并给出明确修复建议见 worktree.ts。job 注册失败返回Failed to start background task job(s): ...仅调度部分 job 的 batch 会在即时文本中报告失败 id 并保持已启动的 job 运行。child 失败以SingleResult.exitCode 1呈现stderr/error已填充后台 job 标记失败但投递文本仍携带输出 后续/transcript 提示。child 省略yield时finalizeSubprocessOutput(...)注入警告如SYSTEM WARNING: Subagent exited without calling yield tool after 3 reminders.对应常量SUBAGENT_WARNING_MISSING_YIELD。agent://id解析错误在另一工具读取时对模型可见无会话、无 artifacts 目录、缺失 id、冲突的提取语法、或提取 JSON 无效。实战要点与最佳实践并行 同一 assistant 消息中的多个task调用或task.batch下的一条tasks[]批量调用无论哪种方式会话级信号量都会约束扇出。async.enabledtrue时每个 spawn 是独立后台 job。无 batch 模式的共享背景约定一次性写入local://文件并在每个 spawn 的task中引用该路径——子代理共享父local://根batch 模式下必填context直接把共享背景带进每个 spawn 的系统提示词。优先向既有 agent 发消息hub而非重新 spawn做后续工作它已持有相关上下文。hubop:list 显示 idle/parked 候选向 parked agent 发消息会复活它。history://id显示 agent 做过什么。同辈消息可用性是推导出来的不是配置的isIrcEnabled见 tools/hub/messaging.ts恰好当有人可发消息时才存在——会话能 spawn 子代理或它本身就是子代理。消息是联系已完成子代理的唯一后续路径因此没有 hub 消息的 task 会让 idle agent 搁浅。child 会话不继承对话历史。内置继承物是工作区树/skills/context files、共享local://根、以及存在时的已批准计划引用。父传mcpManager时child 会话禁用独立 MCP 发现得到复用父连接的代理工具。agent://id 基于名称Task第一Task-2/Task-3仅在名称重复时出现嵌套如Parent.Child由AgentOutputManager生成——这正是防止重复/嵌套调用间产物冲突的机制。相关文档docs/task-agent-discovery.mdagent 发现与优先级的深入说明docs/tools/hub.md与子代理消息交互、job 控制与复活docs/tools/todo.md父子会话的 todo 门与计划交接docs/mcp-runtime-lifecycle.mdchild 会话的 MCP 代理行为【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表