深度解析:子任务 Prompt 的构建机制——从源码到执行

admin · 2026-05-14 · architecture · prompt · sub-agent · 深度解析 · Tool · Skill

深度解析:子任务 Prompt 的构建机制

深度解析:子任务 Prompt 的构建机制

从源码到执行——主/子智能体 Prompt 的对比与 Tool/Skill 注入时机

作者: admin 2026-05-14 buddyMe v0.1.35

01 引言:为什么需要理解 Prompt 构建

在 buddyMe 这样的多智能体系统中,Prompt 不只是"给 AI 的一段话"——它是整个系统的控制平面。Prompt 的构建方式决定了:

理解 Prompt 的构建机制,就是理解这个系统的"灵魂"是如何被注入的。

02 整体架构概览

buddyMe 采用主-子智能体(Orchestrator-Worker)架构:

①
用户请求 — "帮我写一篇关于 Prompt 构建的技术博客"
│
▼
②
主智能体 Main Agent
理解用户意图 → 拆解子任务 → 分发调度 → 汇总结果
拥有全局视野、完整记忆、全量工具/技能
│ 为每个子任务构建独立 Prompt
▼
子任务 ① SEARCH
搜索源码中的 Prompt 构建逻辑
子任务 ② CREATE
创建博客骨架
子任务 ③ EDIT
填充代码片段与解析
子任务 ④ VERIFY
校验完整性

关键设计理念:主智能体是"指挥官",子智能体是"特种兵"。指挥官拥有全局视野,特种兵只聚焦单一任务。

03 主智能体 Prompt 的构建

主智能体的 Prompt 由以下几个层次组成:

3.1 基础系统提示词

3.2 记忆系统注入

# 伪代码示意
system_content = base_system_prompt
system_content += format_memory(we_md_content)       # 循环记忆
system_content += format_recent_summary(recent_logs)  # 近期摘要

3.3 任务规划能力

# 主智能体内部逻辑(伪代码)
def plan_subtasks(user_request):
    steps = decompose(user_request)
    # 每个 step 包含:
    #   - 动作类型:SEARCH / CREATE / EDIT / VERIFY
    #   - 可选的 SKILL 标记
    #   - 依赖关系(前序步骤)
    return steps

3.4 主智能体 Prompt 的特征总结

特征说明
上下文范围全局:完整对话历史、所有记忆
工具访问全量:所有 Tools + 所有 Skills
生命周期长驻:贯穿整个对话会话
自主性高:可规划、调度、决策
Token 预算充裕:无严格上限

04 子任务 Prompt 的构建

子任务的 Prompt 构建是本文的核心。它并非主智能体 Prompt 的简单子集,而是一次精心设计的重构。

4.1 SUB_AGENT.md —— 子任务的行为宪法

子任务 Prompt 的核心是 SUB_AGENT.md 文件,它定义了子任务执行者的完整行为规范。注意文件头部的关键注释:

由 agent.py 读取并注入子任务的 system_content,用 11 和 97500 填参。

这两个数字是核心参数:11 是单个子任务最多调用工具的轮次上限,97500 是输出字符数的上限。它们并非硬编码在模板中,而是由 PromptBuilder.load_sub_agent_prompt(max_steps=11, max_output=97500) 在运行时通过 .format() 填入,保持模板通用性。

4.2 子任务 Prompt 的十层组装

子任务的 system_content 由以下十层按顺序拼接:

L1
SUB_AGENT.md — 身份定位 + 安全规则 + 执行规范
│
L2
技能优先规则 + 可用技能列表(第一次注入)
│
L3
当前子任务描述(由主智能体规划生成)
│
L4
已生成文件列表(前置步骤的产出)
│
L5
验证任务说明(仅 VERIFY 类型的子任务)
│
L6
环境信息(工作空间路径、输出目录)
│
L7
文件输出规则
│
L8
禁止事项(严禁修改 subtask_results.json)
│
L9
可用技能列表(二次注入,确保注意力覆盖)
│
L10
近期摘要(历史上下文)

4.3 逐层解析

第一层:SUB_AGENT.md(行为宪法)

这是子任务 Prompt 的"地基",确立了身份定位("你是子任务执行者")、6 条安全红线和 4 条执行纪律。

第二层 & 第九层:技能列表的双重注入

技能匹配规则在 Prompt 中出现了两次——一次在 SUB_AGENT.md 之后,一次在文件输出规则之后。这种"双重注入"确保无论 LLM 的注意力如何分布,都能看到技能匹配规则。

第三层:当前子任务描述

由主智能体在任务规划阶段生成,直接告诉子任务执行者"你要做什么",例如:

当前子任务: [EDIT] 搜索并提取主/子智能体源码,填充 Prompt 构建差异及 Tool/Skill 注入时机的代码片段与文字解析

第四层:已生成文件列表

让子任务执行者知道前置步骤已经产出了什么,避免重复工作。随着子任务逐个完成,这个列表不断更新。

第五层:验证任务说明(仅 VERIFY 类型)

【验证任务】
1. 用 read_file 读取已生成的文件
2. 检查结构完整性
3. 发现问题用 edit_file 修复
4. 无问题则输出文件路径和功能说明
5. 禁止重新搜索

第六~八层:环境 + 规则 + 禁止事项

环境信息(工作空间路径)、文件输出规则、以及最关键的禁止事项:严禁修改 subtask_results.json。

第十层:近期摘要

提供历史上下文,帮助子任务执行者理解项目的整体背景。

05 核心差异对比

维度主智能体子任务执行者
身份全能助手、任务规划者单一任务执行者
Prompt 来源动态构建(对话历史 + 记忆 + 系统提示)模板化构建(SUB_AGENT.md + 任务描述 + 上下文注入)
上下文完整对话历史精选摘要 + 当前任务描述
工具访问全量按类型筛选(research/build/verify)
技能访问全量全量(但受任务范围限制)
自主性可规划、调度、决策只执行分配的任务
轮次限制无严格限制最多 11 轮工具调用
输出限制无严格限制不超过 97500 字符
生命周期贯穿会话单次任务
安全约束通用安全规则更严格:禁止修改 subtask_results.json 等

设计哲学差异

主智能体 — 追求"广度"
需要理解任意用户意图
需要维护全局状态
需要协调多个子任务
子任务 — 追求"深度"
只需理解单一任务
只需关注当前上下文
在严格约束下高效执行

Prompt 模板化 vs 动态化

主智能体的 Prompt 是高度动态的——随着对话进行,上下文不断增长,记忆不断累积。

子任务的 Prompt 是半模板化的——SUB_AGENT.md 是固定模板,但以下部分是动态注入的:

# 子任务 Prompt 构建伪代码
def build_subagent_prompt(task_description, generated_files, recent_summary):
    prompt = read_file("SUB_AGENT.md")           # 固定模板
    prompt += format_skill_rules()                # 固定规则
    prompt += f"当前子任务: {task_description}"    # ← 动态注入
    prompt += format_generated_files(generated_files)  # ← 动态注入
    prompt += format_env_info()                   # 固定环境
    prompt += format_output_rules()               # 固定规则
    prompt += format_prohibitions()               # 固定禁止项
    prompt += format_skill_list()                 # 固定列表(二次注入)
    prompt += format_recent_summary(recent_summary)   # ← 动态注入
    return prompt

06 Tool 与 Skill 的注入时机

这是理解整个系统运作的关键。Tool 和 Skill 的注入发生在不同阶段,服务于不同目的。

6.1 Tool 的注入时机

Tools(基础工具)如 read_file、write_file、edit_file 是在 API 调用层面注入的:

关键区分
Tool 定义不在 Prompt 文本中,而是在 API 请求的 tools 参数中。
这意味着 LLM 在理解工具时,依赖的是 API 层面的结构化定义,而非 Prompt 中的自然语言描述。
api_request = {
    "model": "deepseek-v4-pro",
    "system": system_content,          # Prompt 文本
    "tools": [                         # Tool 定义(独立于 Prompt)
        { "name": "read_file", "description": "...", "input_schema": {...} },
        { "name": "write_file", "description": "...", "input_schema": {...} },
        { "name": "edit_file", "description": "...", "input_schema": {...} },
        { "name": "invoke_skill", "description": "...", "input_schema": {...} },
    ],
    "messages": [...]
}

6.2 Skill 的注入时机

Skills(技能)的注入更为复杂,分为两个阶段:

P1
阶段一:Prompt 文本中的声明(构建时)
Skills 以自然语言列表写入 system_content,告诉 LLM "你有这些技能可用,匹配时调用 invoke_skill 激活"
│
▼ LLM 判断是否需要 Skill
P2
阶段二:工具调用时的激活(运行时)
LLM 调用 invoke_skill → 系统返回该 Skill 的完整执行指令 → LLM 按指令执行

6.3 注入时机完整时序图

时间轴 ─────────────────────────────────────────────────────────► [构建阶段] │ ├─ 1. 读取 SUB_AGENT.md ──────► 写入 system_content │ ├─ 2. 注入技能列表文本 ────────► 写入 system_content │ (LLM 此时只知道"有哪些技能",不知道技能的具体内容) │ ├─ 3. 注入任务描述 ───────────► 写入 system_content │ ├─ 4. 注入上下文(已生成文件、近期摘要)► 写入 system_content │ ├─ 5. 注入 Tool 定义 ─────────► 写入 API 请求的 tools 参数 │ (read_file, write_file, edit_file, invoke_skill) │ ▼ [执行阶段] │ ├─ 6. LLM 分析任务,判断是否需要 Skill │ │ │ ├── 不需要 ──► 直接使用基础 Tool 执行 │ │ │ └── 需要 ────► 调用 invoke_skill 工具 │ │ │ ▼ │ 7. 系统返回 Skill 完整指令 │ │ │ ▼ │ 8. LLM 按指令执行(调用基础 Tool) │ ▼ [返回阶段] │ └─ 9. 子任务完成,结果写入 subtask_results.json

6.4 为什么 Tool 和 Skill 分开注入?

Tool 是"手" — 基础能力,始终可用
读文件、写文件、编辑文件
类比:给工人发工具箱
Skill 是"脑" — 专业知识,按需加载
文章写作、前端设计、API 设计
类比:给工人发专业培训教材

分开注入的好处:

  1. Token 效率:不需要一开始就加载所有 Skill 的完整指令
  2. 按需加载:只有匹配的 Skill 才会被激活,减少噪音
  3. 灵活性:可以动态添加新 Skill 而不改变基础架构

07 完整生命周期时序图

以下是一个子任务从创建到完成的完整生命周期:

👤
用户: "帮我写一篇关于 Prompt 构建的技术博客"
│
▼
⚙️
主智能体 Main Agent
1. 理解需求   2. 规划子任务   3. 记录到 subtask_results.json
Step 1: SEARCH   Step 2: CREATE   Step 3: EDIT   Step 4: VERIFY
│ 逐个执行子任务
▼
①
Step 1: SEARCH — 搜索 Prompt 构建逻辑
SUB_AGENT.md 技能列表 任务描述 环境信息 近期摘要
│ 结果写入 subtask_results.json
▼
②
Step 2: CREATE — 创建博客骨架
SUB_AGENT.md 技能列表 任务描述 已生成文件(Step①) 环境信息
│
▼ ... 后续步骤类似 ...
④
Step 4: VERIFY — 校验完整性
SUB_AGENT.md 技能列表 任务描述 已生成文件(全部) 验证任务说明 禁止搜索

08 总结与思考

核心设计原则

1. 模板化 + 动态注入
SUB_AGENT.md 提供稳定的行为框架,动态部分(任务描述、上下文)按需填充
2. 分层约束
身份层(你是谁)→ 安全层(不能做什么)→ 执行层(怎么做)
3. Tool/Skill 分离
基础能力始终可用(API 层注入),专业知识按需激活(Prompt 声明 + 运行时加载)
4. 双重注入
关键规则(如技能匹配)在 Prompt 中重复出现,确保注意力覆盖

参数化设计的精妙

SUB_AGENT.md 通过 .format(max_steps=11, max_output=97500) 实现参数化,这意味着:

从"我"的视角看

作为子任务执行者,我看不到主智能体的完整对话历史,但我有:清晰的 task goal、严格的安全边界、必要的上下文(近期摘要、已生成文件)、完整的工具和技能访问能力。

这种设计让我能够专注而高效地完成单一任务,而不被全局复杂性所干扰。

潜在改进方向

  1. 上下文传递优化:当前前置步骤的结果以简短文本传递,可能丢失细节。可以考虑结构化的结果传递机制。
  2. Skill 懒加载:当前所有 Skill 的描述都写入 Prompt,占用 Token。可以只注入与当前任务相关的 Skill 子集。
  3. 自适应轮次限制:不同复杂度的任务可能需要不同的工具调用上限,可以根据任务类型动态调整。
一句话引用:从 SUB_AGENT.md 的十层组装、Tool 与 Skill 的注入时机,到主/子智能体 Prompt 的核心差异对比。以树状分支结构流程图直观展示子任务从创建到验证的完整生命周期。