跨 harness 对比:Prompt 设计(系统提示结构、动态组装)

系统提示(system prompt)是 harness 把”通用模型”塑形成”特定 agent”的第一现场。这一维度看似人人都有一段”You are …”,但落到源码,61 个 harness 在四个正交问题上分化出清晰的谱系:

  1. 提示是静态字符串还是动态组装的? 从一段硬编码常量(TraeAutoGenAssistantAgent)到几十个带条件守卫的具名分区在每轮重新拼装(OpenHandsClaude CodeGemini CLI),跨度极大。
  2. 用不用模板引擎? 一派把提示外置为 Jinja2/Handlebars/nunjucks 模板文件(smolagentsGPT-PilotZedKimi Code),一派纯字符串拼接(Roo CodeAgno)。
  3. 提示随模型变不变? 一大批 coding CLI 走”按模型家族分文件选基础提示”(OpenCodeMiMo CodeKilo CodeCodex CLIbrowser-use),另一批则模型无关、只在 wire schema 层做适配。
  4. prompt-cache 是不是一等设计约束? 越来越多 harness 把”静态可缓存前缀 + 末尾临时注入”当成同时优化质量与成本的架构原则(Replit Agent 给出 90% 成本降幅、Hermes 把”system prompt 不中途变”写进设计不变量、OpenHandsCacheTier 分组)。

一个贯穿全谱系的收敛点:AGENTS.md / CLAUDE.md 系记忆文件 + SKILL.md 渐进式披露 已成为事实标准的两条动态注入通道,无论开源闭源、中美厂商,几乎人手一份。


对比表格(仅列该维度有实质内容者)

harness基础提示形态组装方式模型/家族适配cache / 运行时注入特点
OpenHands~20 个具名 PromptSection,各带 guard(ctx)分区注册表 → (static, dynamic) 一对ModelSpecificSection 逐家族CacheTier 分组,STATIC 可跨会话缓存
Claude Codesection-builder 函数群,按会话状态装配getSystemPrompt() 动态拼getFunctionResultClearingSection(model)fetchSystemPromptParts() 冻结缓存三元组
Gemini CLI选项对象 + isSectionEnabled(key) 门控snippets.getCoreSystemPrompt()isModernModel 门控 legacy 片段GEMINI_SYSTEM_MD 整体覆盖
Roo Code11 个区块固定顺序字符串拼接generatePrompt()isStealthModel 变体渲染工具目录留空(走原生 function-calling)
deepagentsprefix→base→suffix 有序流水线middleware wrap_model_call 注入片段harness profiles 逐家族后缀部分片段为 SystemMessage 保 cache 断点
Google ADKrequest processor 管线逐段 appendsingle_flow.py 固定顺序static_instruction 前置利于 context caching
Agno固定顺序 XML tag 段落get_system_message() 声明式拼接模型自带 instructions 段无 few-shot、无自动优化
Agent Zero{{include}} 模块化 + extension 链system_prompt hook 每段 appendprofile 目录就近覆盖
Letta多套静态骨架 + memory compilecompile_system_message_async骨架按模式选注入”上次重编译时间/recall 数”元数据块
smolagentsJinja2 化 YAML(含 6 个 few-shot)populate_template() StrictUndefined代码块分隔符可重参数化
GPT-Pilot每 agent 一套 Jinja2 文件 + partialsAgentConvo 渲染 system.prompt状态感知 + OS 感知变量
Zed单一 Handlebars 模板 system_prompt.hbs条件化 {{#if}} 组装模型名注入另存 experimental 模板做 A/B
Kimi Codenunjucks 模板 system.mdrenderPrompt() throwOnUndefined{{ROLE_ADDITIONAL}} profile 覆盖边界节奏注入(GoalInjector 等)护 cache
gooseJinja2 system.mdrender_templatetiny_model_system.md 面向小模型子目录 hints 中途重载
Qwen CodegetCoreSystemPrompt() 分支拼接按沙箱/git/模型分支逐模型工具调用示例QWEN_SYSTEM_MD 覆盖
Hermesstable/context/volatile 三层 \n\nsystem_prompt.py + builder逐 provider schema 消毒提示不变量为明确设计原则
OpenCode按家族选 .txt(8 种)每轮拼环境+AGENTS+MCP+skill 数组provider(model) 子串匹配reminders 走合成 user 轮
MiMo Code按家族分文件(9+1 变体)environment() 锚定会话创建时刻provider() 子串匹配环境块字节级一致保 cache
Kilo Codemodel.prompt 字段选 .txtsystem.ts + soul() 叠加anthropic/beast/codex/gemini/ling…skill verbose/精简有意倒置
Codex CLI按模型 .md(gpt_5_2/codex 等)ContextualUserFragment trait 注入-codex 变体明显更短build_prompt() 组装
Open Interpreter逐目标 CLI 复刻 prompt 资源harness 层重写 + harness_guidance逐 harness 一套Kimi 专属 guidance 块
browser-use9 个变体 md_load_prompt_template 条件选is_anthropic/微调模型/flashsystem+user 均 cache=True
UI-TARS逐模型 GUI prompt 各一套getSystemPromptForModel 派发UITARS_1_0/1_5/Doubao_15/20Baction space 随模型绑定
OpenManus两段极简(system + next_step)think() 每步追加 user 提示browser 场景动态换 next_step
Pydantic-AIsystem_prompt + instructions 双通道_get_instructions 合并排序instructions 每轮重发、system 仅首轮
OpenAI Agents SDKinstructions = str/callableget_system_prompt 解析sandbox agent = Codex 逐字普通 agent 无内建默认提示
AgentScope用户 base + skill/workspace 拼_get_system_prompt + 中间件on_system_prompt transformer 链
Semantic Kernel指令即模板(三引擎可选)format_instructions() 每次渲染声明式 AgentSpec YAML
AutoGen单静态串(agent);orchestrator 模板化.format() 串接 6 个 ledger 模板orchestrator system message 为空串
CrewAIslice 拼接 + i18n JSONtask_execution()skill 入 system 保 cache 前缀;显式 breakpoint
MetaGPTSYSTEM_PROMPT 逐轮拼 role/schema/examplerole_zero 组装QuickThink 快路径经验池 example 检索注入
AutoGPTone-shot 多段 + JSON RESPONSE FORMATbuild_system_prompt非 Anthropic 用 prefill<user_context> 标签抗注入
LangGraph无固定模板prompt 参数(str/callable/Runnable)callable 可读 context 换模型组装全交用户
CAMEL用户/上层给角色 promptrole-playing 模板 format非 strict 模型走 schema+正则输出语言约束后缀
Plandex分阶段多 part 系统消息getTellSysPrompt()不支持则剥 cache controlAnthropic 式 CacheControl 断点
DeerFlow单一大 XML 模板apply_prompt_template静态 + DynamicContextMiddleware 注入 reminder
GPT-Researcher无固定系统提示,动态生成 personaPromptFamily 按族分派Granite 系专属族choose_agent 生成 role_prompt
Continue<env>+<context> baseconstructSystemMessage() 每轮兼容 CLAUDE/CODEX memory 文件
Anthropic 多 agent命名 XML 分区(cookbook 三份)Go 模板 {{.CurrentDate}} 渲染「right altitude」原则
Claude FlowQueen/hive 静态模板 + 槽位guidance 编译器(gates/anchors)非模型自适应108 个 markdown agent 定义注入
QwenPawAGENTS/SOUL/PROFILE 三文件拼PromptBuilder HTML 注释区段heartbeat/memory 块条件剥离
Aider各编辑格式独立 prompt 类format_chat_chunks() 分桶ModelSettings reminder 位置fence 自动选择避冲突
SWE-agentJinja2 模板(system/instance/next_step)_get_format_dict() 注入多 parser 适配弱模型系统提示极简,指导在 instance 模板
Cline两个硬编码模板(DEFAULT/YOLO)buildClineSystemPrompt() 填占位isClineProvider 门控元数据新 SDK 默认提示显著变短
Cursorrules 注入 context 最前系统提示+rules+skills+MCP 各计预算rules 4 种触发模式
FactoryAGENTS.md 声明式注入hooks additionalContext 分层subagent md 正文即提示--append-system-prompt
Warp服务端组装(客户端不含)分层规则 + 热重载逐 harness 原生注入机制--append-system-prompt-file
Augment服务端组装 + 客户端片段systemPrompt/Append/Replacements5 个 subagent 逐字可提取replaceSystemPrompt 标志
Amazon QAgent.prompt 用户/组织自定义format_user_context_message()压缩提示措辞专调
Kirosteering/skills/powers 分层always/fileMatch/manual 条件拼<system-reminder> 自纠正注入
Replit Agent稳定核心 + decision-time 注入轻量分类器每轮选微指令快模型跑分类器核心永不变,成本降 90%
v0三阶段(静态+窗口+RAG)检索式动态组装Instructions 可挂载片段
DevinAGENTS.md + Skills + Playbooksskill 正文系统级中途注入!`cmd` 实时 shell 插值
JunieAGENTS.md 每任务注入渐进式披露 skillsuse_structured_prompt XML 开关
Amp服务端;客户端只见输入工具+AGENTS+环境数据deep/smart/rush 模式变体agent.start 插件注入
Copilot Agent后端四段式query+工作区摘要+机器+工具Skills 急切全文预加载
Trae单一硬编码常量(53 行)无模板引擎,字符串拼 user无 provider 变体7 步方法论内嵌
Comate闭源,N 套内置 agent 提示(推断)role/skills/rules/tools schema版本化迭代(changelog 佐证)
CodeGeeX9 个任务专属提示 + ChatGLM token固定模板 + Task 后缀拼接ChatGLM 特殊 token 格式任务模式不跨轮自动携带

QoderAutoClaw 核心提示未公开,仅有 subagent md / SOUL.md 间接信号,未单列。)


分组讨论

一、静态单串派:最小组装,把智能外包给模型或上层

最简单的一档是一段几乎不变的系统提示Trae 是纯粹样本——TRAE_AGENT_SYSTEM_PROMPT 是 53 行硬编码常量,无模板引擎、无 provider 分支,动态部分仅是 new_task() 把项目根路径和 issue 拼进 user 消息。AutoGenAssistantAgent 同理,system_message 就是构造时传入的单个字符串逐字前置;真正的动态组装被上移到 orchestrator 层(见第六组)。

框架类 SDK 干脆不提供默认系统提示,把它彻底交给用户:LangGraphprompt 参数接受 str/callable/Runnable,“没有固定的多段式模板”;OpenAI Agents SDKAgent.instructions 就是系统提示本体,SDK 唯一的大块内建提示是 sandbox agent 那份”逐字复制 Codex CLI”的 192 行;CAMELSemantic Kernel 也都属”角色 prompt 由上层给定”。这类设计的共性是:harness 只负责机制(注入点、模板引擎、渲染时机),不预置人格。

二、分区/section-builder 动态组装派:Claude Code 立的范式

这是当前最主流、也最被模仿的一派:系统提示由许多小的具名分区按会话状态条件式装配,而非静态模板。Claude Code 是范式源头——getSystemPrompt()getSimpleIntroSection/getUsingYourToolsSection(enabledTools)/getAgentToolSection/computeEnvInfo 等几十个 builder 组成,每个按”本会话实际启用的工具/子 agent/MCP”条件纳入,还内嵌了硬编码的对抗式验证契约与 tick 心跳机制。

沿这条路走的一大批:OpenHands 做得最系统——约 20 个 PromptSection 各带 guard(ctx) 布尔守卫,且显式按 CacheTier 分成 STATIC/DYNAMIC 两半以命中 Anthropic prompt cache,这是把”分区”与”缓存”两个关注点正交化的最干净实现。Gemini CLIisSectionEnabled(key) + isModernModel 门控,Roo Code 的 11 区块固定顺序拼接,Google ADK 的 request processor 管线(basic→auth→instructions→identity→… 十余段),Agno 的固定顺序 XML tag 段落,都是同一思路的不同工程化。

其中两个把”分区”推到框架级的值得单独点名:Agent Zero 把”prompt 即框架”做到极致——get_system_prompt() 本身只返回空 list,靠 _10_main_prompt→_11_tools_prompt→_12_mcp_prompt→… 一条 extension 链每段 append,插件也能注册自己的 system_prompt extension;deepagents 则让每个 middleware 通过 wrap_model_call 动态注入自己那段(FILESYSTEM_SYSTEM_PROMPT 随启用的 FS 工具变化、EXECUTION_SYSTEM_PROMPT 仅沙箱可用时),是真正意义上的条件组合而非固定模板。

三、按模型家族分文件派:coding CLI 的集体选择,且互相高度趋同

一个极其密集的趋同簇:大量终端 coding agent 走”按当前模型 id 子串匹配、选一个 .txt/.md 基础提示文件”的路子。OpenCodeprovider(model) 分派(beast.txt/codex.txt/gpt.txt/gemini.txt/anthropic.txt/kimi.txt/default.txt)几乎是这一簇的模板;MiMo Code(小米,9+1 变体,连 beast.txt/codex.txt 命名都一致)、Kilo Code(按 model.prompt 字段选,anthropic/beast/codex/gemini/ling/trinity)三者的文件命名与 provider()/session/system.ts 结构高度同构,是明显的同源/相互借鉴关系(三者都出自 opencode 谱系)。dossier 中 OpenCode 的 default.txt 被记录为”结构上高度接近、部分措辞近乎逐字复制 Claude Code 系统提示”——但明确标注为观察性相似而非确凿抄袭。

Codex CLI 也按模型分文件(gpt_5_2_prompt.md/gpt-5.2-codex_prompt.md),并观察到”-codex 后缀变体明显更短”,佐证 codex 系模型把 harness 行为内化进了权重。Qwen Code 的内置子 agent 提示被记录为”与 Claude Code 内置 Task 子 agent 提示几乎逐字相同”(“Do what has been asked; nothing more, nothing less” 等原话),是本轮最直接的借鉴证据之一。Open Interpreter 把这一思路推到极端——它为每个”目标 harness”(Claude Code / Kimi CLI / Qwen Code / OpenCode…)各自维护一整套逐字复刻的 prompt 资源,本质是”harness 模仿器”。

这一簇在多模态方向的两个变体值得注意:browser-use 的 9 个 system prompt 变体按 is_anthropic/微调模型/flash_mode/use_thinking 条件选,且 <browser_state> 段定义了 [index]<tag/> 的索引化 DOM 表示 + 截图作为 ground truth 的 computer-use 动作空间;UI-TARS 则是”逐模型 GUI prompt 各一套”(getSystemPromptUITARS_1_0/1_5Doubao_15_15B/20B),且 action space 与坐标编码随模型不同assembleSystemPrompt(template, operator.getSupportedActions()) 把 operator 实际支持的动作填进模板——prompt 与 GUI 操作能力硬绑定。OpenManus 的 browser system prompt 被记录为”风格明显借鉴 browser-use 库”,是 GUI agent 提示互相借鉴的又一例。

四、模板引擎外置派:把 prompt 当代码管理

与”字符串拼接”相对的是把提示外置为模板文件、用引擎渲染smolagents 最彻底——提示是 Jinja2 化的 YAML(code_agent.yaml 含 6 个完整 few-shot、工具桩 {% for tool %}、11 条硬规则、<end_plan> 停止序列),用 StrictUndefined 保证缺变量即报错,连代码块分隔符都能按 agent 配置重参数化。GPT-Pilot 每个 agent 一套 Jinja2 文件 + partials/ 共享片段({% include %} 拉入 coding_rules),注入 state/os 变量做状态与 OS 感知。Zed 用单一 Handlebars 模板 system_prompt.hbs{{#if (gt (len available_tools) 0)}} 条件化),Kimi Code 用 nunjucks(throwOnUndefined 同 StrictUndefined 哲学),goose 用 Jinja2 system.mdSemantic Kernel 甚至提供三套可互换引擎(自有 DSL/Handlebars/Jinja2)且”指令即模板、每次调用重渲染”。这一派的共同价值观:提示应能像代码一样被版本管理、静态校验(缺变量报错)、与逻辑分离。

五、prompt-cache 驱动的 static/dynamic 分割:从质量关注升级为成本约束

一个正在快速固化的设计原则:把系统提示切成”永不变的可缓存前缀”和”末尾的临时注入”,同时优化指令遵循与推理成本Replit Agent 把这件事讲得最透——它批判静态前置提示(“习得先验覆盖书面规则""指令遵循随上下文增长退化”,引 Lost-in-the-Middle),改用”跑在快模型上的 decision-time 分类器每轮选相关微指令”,并给出两个硬数字:把”鼓励并行工具调用”从系统提示移到 trace 末尾使每轮多执行 15% 工具调用;核心 prompt 永不变换来的 cache 命中”相比动态改系统提示成本降低 90%”。

同一约束在多家有独立实现:Hermes 把”System prompt doesn’t change mid-conversation. No cache-breaking mutations except explicit user actions”写进官方设计不变量;Kimi CodeInjectionManager 刻意把 GoalInjector/ToolsDiffInjector 排除在每 step 循环外、只在”边界节奏”(turn 开始/续接/压缩后)追加,注释明确说逐 step 注入是 O(n²) 且破坏 caching;CrewAI 把 skill 块放进 system prompt 而非 task prompt(注释:“Skills are agent-scoped … live in the system prompt where prompt-cache prefixes can survive”),并显式在 system/user 末尾 mark_cache_breakpoint()Plandex 用有序的 ExtendedChatMessagePart 列表 + Anthropic 式 CacheControl ephemeral 断点;MiMo Code 让环境块锚定”会话创建时刻”而非请求时刻以求字节级一致;DeerFlow 把 system prompt 做成完全静态(跨用户一致),日期/记忆/上传等每轮变化项交给 DynamicContextMiddleware 注入首条 HumanMessage 的 <system-reminder>。这是本维度过去两年最清晰的一条演进曲线:cache 从”顺带的优化”变成”决定提示架构的一等约束”。

六、编排层的模板化 prompt:动态组装发生在 orchestrator 而非 agent

多 agent 系统里,最讲究的 prompt 组装常常不在单个 agent 而在协调者AutoGen 的单 agent 是静态串,但 Magentic-One orchestrator 有 6 个 .format() 模板(facts ledger、plan、progress-ledger 强制 JSON schema、stall 重规划、final answer),且刻意让 ORCHESTRATOR_SYSTEM_MESSAGE=""——全部引导走 user-role 模板。Semantic Kernel 的 Magentic prompt 同构(progress-ledger 明令”DO NOT OUTPUT ANYTHING OTHER THAN JSON”,靠 prompt 工程而非 API 特性实现结构化输出)。Anthropic 多 agent 编排 的 cookbook 三份提示(research_lead_agent.md/research_subagent.md)示范了命名 XML 分区 + {{.CurrentDate}} 模板渲染,并把”teach the orchestrator how to delegate""scale effort to query complexity”这类元原则直接写进 <subagent_count_guidelines> 等分区。MetaGPTrole_zero 每轮拼 role/schema/example 且从经验池检索 example 注入,也属这一类”编排者提示逐轮重建”。Claude Flow 的 Queen/hive prompt 是静态模板 + 槽位插值,另有独立的 @claude-flow/guidance 编译器(gates/truth-anchors/adversarial)+ 108 个 markdown agent 定义按需注入,是把”提示治理”单独抽成一个包的少见做法。

七、记忆自编辑与类型化通道:几个结构性异类

新增的 19 个里,有几个在 prompt 结构上提供了别处没有的东西:

  • Letta(MemGPT 谱系)把分层可自编辑记忆直接编译进系统提示:compile_system_message_async = 静态骨架 + in_context_memory.compile()(渲染 <memory_blocks>/<directories>/<available_skills>)+ 一个”元数据块”(注入”系统提示上次重编译时间 / recall 消息数 / 归档条数 / 可用 tags”)——即提示里显式告诉模型它的记忆系统当前状态,让”自编辑记忆”成为提示可感知的一等对象。这是 memory 维度的设计,但落点在 prompt 组装上。
  • Pydantic-AI 提供 system_prompt 与 instructions 双通道:前者只在首个 request 生成(history 非空即假设已含),后者是官方推荐方式(每轮重发、不进 history 持久部分,天然 cache 友好);_get_instructions 把 agent 与各 capability/toolset 的 get_instructions() 合并、按 InstructionPart.sorted 排序 join——是把”谁贡献哪段提示”类型化、可排序化的少见设计,契合其”类型化工具”的整体气质。
  • AgentScopeQwenPaw 的底座框架)的 _get_system_prompt 只拼当前激活组的 skill 说明(toolkit.get_skill_instructions(activated_groups)),并通过 on_system_prompt 中间件链(transformer 模式,字符串进出)注入长期记忆 MEMORY.md;DEFAULT_SKILL_INSTRUCTION 明确告诉模型”skill 不是 tool,要用 SkillViewer 读全文再照做”。QwenPaw 在其上再叠 AGENTS.md→SOUL.md→PROFILE.md 三文件拼装 + HTML 注释区段(<!-- heartbeat:start -->)条件剥离,其中 PROFILE.md 自动生成、供其他 agent 判断是否委派——把提示组装复用成了多 agent 的能力发现机制。
  • GPT-Researcher 干脆没有固定系统提示choose_agent 用 few-shot 让 LLM 为每个 query 现场生成 {server, agent_role_prompt}(“You are a seasoned finance analyst…“),再把该 role 作为后续调用的 system content——运行时生成 persona,与所有”预置人格”路线相反。
  • DeerFlowprompt-injection 防御做成一等结构:用户输入包在 --- BEGIN/END USER INPUT --- 当不可信数据,有 “System-Context Confidentiality” 段禁止复述框架注入内容;SystemMessageCoalescingMiddleware 还把多条 SystemMessage 合并成单条 leading 以兼容 vLLM/SGLang/Qwen 等严格后端——这类”面向开源推理后端的提示兼容层”在闭源 harness 里见不到。

八、记忆文件 + skills 渐进披露:横贯全谱系的两条事实标准通道

无论上面属哪一派,两条动态注入通道几乎人手一份,值得单独收束:

(a)AGENTS.md/CLAUDE.md 系记忆文件。 Factory 明确把它定位为”跨工具通用约定”(Cursor/Aider/Gemini CLI/Codex/Zed 共读同一文件),Continue 按序找 AGENTS.md/AGENT.md/CLAUDE.md/CODEX.mdgoose 合并 .goosehints+AGENTS.md+CLAUDE.mdDevin 甚至读竞品配置(CoderabbitAI 的 .coderabbit.yaml、Greptile 的 greptile.json、Cursor rule 文件)。Kimi CodeOpenHands 都把这类文件明确降级为”非特权/不可信指令通道”并写了优先级顺序(用户 > 系统规则 > 越具体的 AGENTS.md 越优先),是把”记忆文件可能含 prompt injection”这一风险显式建模的成熟做法。

(b)Skills 渐进式披露。 由 Anthropic Agent Skills 规范定型:启动只加载 name+description(每个几十 token),完整 SKILL.md 正文仅在判定相关时才进上下文。KiroJunieWarpReadSkill 独立工具调用)、ReplitRoo CodeAgentScope 都实现了这一两阶段组装。反例是 Copilot Agent——它对 opt-in 的 skill 采用”急切全文预加载”,是刻意的相反取舍。多家(MiMoKilo)还记录了一个反直觉细节:skill 在 system prompt 里放 verbose 版、在工具描述里放精简版,实测更优——与工具通常的”schema 精简”直觉相反。


最值得借鉴的设计

1. 分区注册表 + CacheTier 显式分层(OpenHands,参照 Claude Code 的 section-builder + Replit 的 decision-time 注入)。 把系统提示拆成带 guard(ctx) 的具名分区、再按”是否可缓存”正交地分成 STATIC/DYNAMIC 两半,一举解决了三个长期纠缠的问题:提示可按会话状态精确裁剪(不给没启用的工具写指导)、静态前缀能稳定命中 prompt cache(成本可低至 1/10)、动态内容集中在末尾避免打爆缓存又占据近因位置(指令遵循更好)。这套结构把”提示质量”与”推理成本”从互相牵制变成可以同时优化,是本维度最具复制价值的骨架。理由:它不依赖任何特定模型或闭源基建,纯工程手段,且已被多家独立收敛验证。

2. instructions/system_prompt 双通道 + 类型化可排序注入(Pydantic-AI)。 把”只需说一次、可进 history 的”和”每轮都该重发、不进持久 history 的”两类提示拆成独立通道,并让每个 capability/toolset 各自贡献带排序键的 InstructionPart——这为”多来源提示如何合并、谁在前谁在后、哪段该缓存”提供了一个类型系统级的答案,而不是靠字符串拼接的隐式约定。理由:随着 harness 的提示来源越来越多(base + rules + skills + memory + tool guidance + mode),“谁注入什么、按什么顺序、是否可缓存”的组合复杂度正在爆炸,Pydantic-AI 的类型化通道是少数把这件事结构化而非靠注释和惯例约束的设计,最适合被框架层借鉴。