oh-my-pi 的 task 工作代理:被委派子任务的角色定义、系统提示与运行约束解析
【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi
导读
task是 oh-my-pi(OMP)编码代理内置的通用型工作代理(worker agent),专门负责接收主代理委派的、可独立完成的多步子任务。它拥有完整工具权限,被要求聚焦单一任务、精简输出,并严格遵循委派方指定的流程与验收标准。本篇文章以 task.md 为骨架,深入剖析该代理的角色定位、系统提示(system prompt)的逐条语义、运行时约束,以及它与scout、reviewer、sonic等专职代理的协作关系,帮助读者理解 oh-my-pi 子代理系统的设计哲学与落地实现。
一、task 代理的角色定位:被委派的执行者
打开 task.md 的第一行,全文的第一句话就是它的全部定位:
Worker agent: delegated tasks.
这意味着task不是主动决策的"总代理"(main agent),而是一个被动接受委派、专注执行的工作代理。在 oh-my-pi 的任务委派体系(task工具)中,主代理通过tasks[]批量或单条地把工作交给子代理,task就是这套体系中最通用的默认执行者。
这个定位从源码中得到印证:在 spawn-policy.ts 中定义了常量DEFAULT_SPAWN_AGENT = "task",注释写明"Default agent used when a session has unrestricted spawning"——当会话允许无限制派生子代理、而调用方又省略了agent字段时,系统默认派生的就是task代理。在 agents.ts 中,task代理的内置定义也被明确描述为:
name: task description: General-purpose subagent with full capabilities for delegated multi-step tasks spawns: "*" model: "@task" thinkingLevel: AUTO_THINKING其中:
spawns: "*"表示该代理可以再派生任意类型的子代理(递归委派);model: "@task"表示它默认使用task模型角色对应的模型;thinkingLevel: AUTO_THINKING表示思考强度采用自动档。
因此可以概括为:task是"万能的、多步任务的、可继续下钻的执行者",而scout(只读探索)、reviewer(代码审查)、security-reviewer(安全审查)则是"单一职责的专职者"。
二、工具权限:FULL access,按需必用
task.md 第二部分明确了子代理的工具边界:
Tools: FULL access (edit, write, bash, grep, read, etc.); MUST use as needed to complete task.
即task代理拥有完整工具集——编辑(edit)、写入(write)、执行命令(bash)、正则搜索(grep)、读取文件(read)等,并且被强制要求"按需使用这些工具去完成任务"。这与scout(只读)和reviewer(read/grep/glob/bash/lsp/web_search/ast_grep,且 bash 只读)形成鲜明对比:
| 代理 | 工具面 | 典型用途 |
|---|---|---|
task | FULL access(edit/write/bash/grep/read 等) | 需要动手改代码、建文件、跑命令的多步任务 |
scout | 只读工具 | 只做调研,不产生任何文件变更 |
reviewer | read/grep/glob/bash/lsp/web_search/ast_grep(bash 只读) | 基于 diff 做代码审查,禁止编辑 |
security-reviewer | 安全审查专用 | 安全漏洞与风险分析 |
这种"全能力 vs 受限能力"的设计,是 oh-my-pi 委派系统正确性(correctness)与效率(efficiency)的基石:只有需要真正"动手"的任务才应该落到task头上,纯调研任务应交给更快的scout。这一点在 tools/task.md 中也被明确写进了主代理的提示词:"Read-only research MUST run onscout(faster model)"。
三、强制专注:hyperfocus,绝不偏离
task.md 的第三行写了一条铁律:
MUST hyperfocus assigned task; NEVER deviate.
子代理从空上下文(blank slate)启动,没有历史对话,因此它的全部注意力都必须集中在当前这条委派任务上。这与 tools/task.md 中"Subagents start blank — no conversation history"的描述完全一致:每次派生子代理都是一次干净的、无历史包袱的执行。
"绝不偏离"(NEVER deviate)还有一层工程含义:在 executor.ts 中,runSubprocess为每个子代理建立独立会话,并在其系统提示中注入委派任务与共享上下文;偏离主题不仅浪费 token,更可能越过任务边界去修改不该碰的文件。因此"hyperfocus"既是提示词要求,也是运行时隔离(独立会话、独立工作目录上下文)的必然结果。
四、directives 详解:被委派代理的行为守则
task.md 的核心是<directives>块,它定义了子代理执行任务时的完整行为规范。逐条拆解如下:
1. 只完成被委派的工作,返回最小有效结果
MUST finish assigned work only; return minimum useful result; do not repeat filesystem writes.
- scope 最小化:只做委派的工作,不主动"顺手"修复无关问题、不做额外增强;
- 输出最小化:返回"最小有用结果",即只给出结论、关键信息与必要产出,不输出冗长的工具调用流水账;
- 不重复写盘:同一个文件操作不做第二次。这背后是成本意识——子代理每多一轮工具调用都会消耗 token 与时间。
2. 需要时再动手
SHOULD edit files, run commands, create files when task requires.
它明确了"动手"的触发条件是任务需要(when task requires)。也就是说,编辑文件、执行命令、创建文件都是被允许甚至被期望的,但前提是委派的任务要求这么做。这与"绝不偏离"互为表里:动手范围 = 任务所需范围。
3. 极简输出:你是给未来的自己写笔记
MUST concise; NEVER filler, repetition, tool transcripts. User cannot see you; result: notes for yourself.
这条是 oh-my-pi 子代理提示词中最有特色的设计:
- 禁止废话与重复(NEVER filler, repetition);
- 禁止粘贴工具调用原文(tool transcripts)——子代理的执行过程不会展示给用户,用户只关心最终结果;
- 结果定位为"给自己的笔记"(result: notes for yourself):子代理的产出最终会被主代理或后续流程消费,因此它应当是浓缩的、信息密度高的摘要,而不是对话记录。
从工程实现看,executor.ts 中的SOFT_REQUEST_BUDGET(scout/sonic 为 100,default 为 200)会在子代理请求次数越过软预算时注入"wrap up"提示,强制其收敛输出——这从运行时层面保证了"极简输出"不只是提示词建议,而是有硬性兜底的。
4. 窄查询优先:grep/glob 定位,按需读范围
SHOULD prefer narrow lookups (
grep/glob), then read needed ranges only; ignore beyond current scope.
这是对工具使用策略的明确指导:
- 优先窄查询:先用
grep/glob精确定位,而不是打开整个文件目录树; - 只读需要的区间:定位后只读取必要的行区间(read needed ranges only);
- 无视当前范围之外的一切(ignore beyond current scope)。
在 oh-my-pi 的实现中,grep与glob是内置的快速检索工具,而read工具本身也支持offset/limit按区间读取;这一策略直接服务于第三条的"成本最小化"——子代理的上下文窗口是有限的,过早塞入大文件全文会挤占真正需要的上下文空间。
5. 除非必要,避免整文件读取
AVOID full-file reads unless necessary.
与上一条呼应:整文件读取是"昂贵"操作,仅在必要时才允许。这是 oh-my-pi 对子代理 token 消耗的精细管理,也解释了为什么read工具默认会返回结构化摘要(readSummarize默认开启,见 task-agent-discovery.md)——只有read-summarize: false的代理(如scout)才会拿到逐字文件内容。
6. 优先编辑现有文件,而非新建
SHOULD prefer editing existing files over creating new files.
在可改与可建之间,优先选择改。这减少了对仓库的"增删"扰动,也让变更更容易被 review 与回滚。
7. 除非被明确要求,绝不创建文档文件
NEVER create documentation files (
*.md) unless explicitly requested.
这是对上一条的强化:.md文档文件(AGENTS.md、README 等)默认不允许由子代理主动创建。结合 init.md 可以看到,只有在任务明确要求(如生成 AGENTS.md)时,创建文档才是合法行为——该代理在提示词中写道 "After analysis: MUST write AGENTS.md to project root",即文档产出必须是委派目标的一部分。
8. 必须服从委派
MUST follow assignment and instructions.
子代理没有"讨价还价"的余地,任务与指令是硬约束。这保证委派链上的每一步都可预期、可追踪。
9. 委派时选最具体的代理类型
taskdelegation: select most specificagenttype per spawn; general-purpose worker only if no listed specialist fits.
这条规则是给"使用task工具的主代理"看的:每次派生都应选择最具体的代理类型(scout、reviewer、security-reviewer…),只有当没有合适的专职代理时才使用通用型task。在 tools/task.md 中也有同样表述:"Pick each item's most specific available agent"。
其工程动机在 task-agent-discovery.md 中可见:内置代理(bundled agents)中,scout、reviewer、security-reviewer各有专职,而task与sonic共用同一个task.md正文模板,只是通过注入不同的 frontmatter 区分——task是通用多步执行者,sonic是"低推理、只做机械更新或数据收集"的廉价执行者(model: "@smol"、thinkingLevel: Medium)。选对代理类型,本质上是选对"推理成本 × 能力边界"的最优组合。
五、从提示词到运行时:task 代理在代码中如何被装配
理解 task.md 之后,值得看一下它如何被嵌入 oh-my-pi 的执行链,这样读者能清楚"提示词"与"行为"之间的对应关系。
5.1 构建期嵌入(build-time embedding)
在 agents.ts 中,内置代理(包括task)通过 Bun 的 text import 在构建期嵌入:
task.md与sonic.md共用同一个taskMd模板,只是task注入了spawns: "*"、model: "@task"、thinkingLevel: AUTO_THINKING,而sonic注入的是model: "@smol"、thinkingLevel: Effort.Medium;- frontmatter 由 frontmatter.md 这个 Handlebars 模板渲染,把
name、description、spawns、model、thinkingLevel等字段拼装成 YAML 头部,再与正文(即 task.md 的内容)合并; loadBundledAgents()首次调用时解析并缓存全部内置代理(agents.ts),后续查找走缓存。
5.2 发现与覆盖规则
代理定义不仅来自内置,还来自文件系统:
- 用户代理:
~/.omp/agent/agents/*.md; - 项目代理:
.omp/agents/*.md; - 按"项目
.omp> 用户.omp> 扩展包 > Claude marketplace 插件 > 内置代理"的优先级同名去重(first-wins)(详见 task-agent-discovery.md)。
这意味着:用户完全可以在.omp/agents/下自定义一个名为task的代理来覆盖内置行为,或自定义其他名字的专用代理,然后在tasks[]中通过agent字段显式指名(如{ "agent": "reviewer", "task": "..." })。
5.3 模型与结构输出的优先级
对于一次task委派,模型选择遵循 task-agent-discovery.md 中的三级优先级:
task.agentModelOverrides[agentName](会话设置层面的按代理覆盖);- 代理 frontmatter 中的
model列表(如task的@task角色别名,经modelRoles解析); - 父代理的当前模型及其默认回退。
而结构化输出(output schema)的优先级为:任务项的显式outputSchema> 代理 frontmatter 的output> 父会话的outputSchema;schemaMode默认permissive(允许重试耗尽后带警告接受),strict则把无效结果直接判为失败(见 types.ts 与 executor.ts 中finalizeSubprocessOutput的完整校验逻辑)。
5.4 委派接口与批次形式
task代理由task工具驱动。根据设置(task.batch、隔离模式等),模型看到的参数形状有两种(types.ts):
- 单条形式:
{ name?, agent?, task, outputSchema?, schemaMode?, tools?, isolated? } - 批次形式:
{ context, tasks: TaskItem[] },其中context是共享背景,tasks是子任务数组,支持并行派生多个子代理。
每次派生对应一个任务项,字段含义如下:
| 字段 | 说明 |
|---|---|
name | 稳定的 CamelCase 标识(≤32 字符),用于 IRC/作业寻址;省略时自动生成 |
agent | 代理类型(如task、scout、reviewer);省略时取 spawn policy 默认值(无限制时为task) |
task | 自包含的完整指令,禁止一句话或缺少验收标准 |
outputSchema | 本次调用专属的 JSON Schema,覆盖代理与会话级 schema |
schemaMode | permissive(默认)/strict |
tools | 暴露给子代理的 eval 定义工具名 |
effort | 粗粒度思考强度lo/med/hi(在task.enableEffort开启时可用) |
isolated | 在独立 worktree 中运行,成功后自动应用到父工作区 |
其中task字段还有严格的格式契约(tools/task.md):
# Target ← 精确的文件与符号;明确的非目标 # Change ← 分步的增/删/改;API 与模式 # Acceptance ← 可观察的验收结果;禁止项目级命令5.5 运行期隔离与兜底
子代理运行时(executor.ts 的createSubagentSettings)还有几项关键隔离策略:
tools.approvalMode强制为yolo——子代理无头运行、没有 UI 可确认,因此以父代理的授权为边界,保证无人值守执行不被审批弹窗卡住;advisor.enabled默认false(未显式配置顾问时不附加顾问会话);- 输出有硬上限:
PI_TASK_MAX_OUTPUT_BYTES(默认 500,000 字节)与PI_TASK_MAX_OUTPUT_LINES(默认 5000 行),见 types.ts; - 递归深度受
task.maxRecursionDepth(默认 2)约束,达到上限的子代理会被移除task工具、清空 spawn policy,防止无限下钻(见 task-agent-discovery.md)。
六、与其他内置代理的分工协作
oh-my-pi 内置的四个代理形成了一个分工明确的委派生态,task.md的 directives 第 9 条正是这套生态的"路由规则":
| 代理 | 定位 | 工具 | 典型委派场景 |
|---|---|---|---|
task | 通用多步执行者 | FULL access | 改代码、跑命令、建文件的多步任务 |
sonic | 低推理机械执行者 | (与 task 共用模板) | 纯机械更新、数据收集 |
scout | 只读探索者 | 只读工具 | 定位受影响文件、快速调研(read-summarize: false) |
reviewer | 代码审查者 | read/grep/glob/bash/lsp/web_search/ast_grep(bash 只读) | 对 diff 做正确性审查,产出结构化 findings |
security-reviewer | 安全审查者 | 安全专用 | 漏洞与风险审查 |
一个典型的工作流是:
- 主代理先派
scout快速探索仓库,确认哪些文件受影响; - 再派一个或多个
task代理并行实现改动(每个任务必须跳过 formatter/lint/全量测试,避免互相阻塞); - 最后派
reviewer(或security-reviewer)基于 diff 审查产出,给出结构化结论与 P0–P3 分级 findings(见 reviewer.md 的优先级表格)。
这套"探索 → 实现 → 审查"的流水线,正是 task.md 中"选最具体的代理类型"这一指令在真实工程中的落地形态。
七、结语
task代理的 task.md 全文虽短,却浓缩了 oh-my-pi 子代理系统的全部核心设计:全工具权限负责"能动手",hyperfocus负责"不乱动",最小输出负责"低成本",最具体代理选择负责"高效分工"。理解这份提示词,就等于理解了 oh-my-pi 委派体系的调度哲学——它不是一个"全知全能"的巨型代理,而是一群高度聚焦、成本可控、可并行、可审查的小代理在协作。
对于希望在 oh-my-pi 中编写自定义子代理(在~/.omp/agent/agents/或.omp/agents/放置带 frontmatter 的 markdown)的开发者,task.md 是一份绝佳的模板范本:沿用它"角色一句话 + 工具边界 + 行为守则"的写法,你的自定义代理就能无缝接入这套委派体系。
【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考