03:Prompt System:Claude Code 如何让 Agent 按协议行动

📅 2026/7/6 14:23:32
03:Prompt System:Claude Code 如何让 Agent 按协议行动
03Prompt SystemClaude Code 如何让 Agent 按协议行动上一篇把工具系统当成 Claude Code 的执行层来看。工具让 agent 有了行动能力它可以读文件、搜代码、改内容、跑命令、拿到验证结果。但工具一旦能接触真实项目新的问题马上出现模型为什么知道自己该怎样使用这些工具、遵守哪些项目规则、用什么方式和用户协作这篇就接着看 Prompt System。我现在更愿意把它叫作“行为协议层”。它把系统提示、项目规则、工具描述、用户指令和运行时补充信息装配在一起让 agent 每一轮行动前都有一套默认规则自己是谁能做什么先看什么怎样使用工具哪些边界交给权限和运行时。这篇文章要拆的主线Agent 的行为协议从哪里来这一篇回答的问题是Claude Code 如何把系统提示、项目规则、工具描述、用户指令和运行时注入组织成 agent 每轮行动前看到的行为协议这个问题容易被压缩成“prompt 怎么写”。但 Claude Code 这类 coding agent 面对的是更大的工程问题。普通聊天里prompt 主要影响回答方式。Coding agent 里prompt 会影响整个任务推进方式它会决定 agent 是先解释还是先观察项目。它会决定 agent 什么时候读文件什么时候搜索什么时候跑验证。它会决定 agent 怎样理解工具描述、项目规则和用户当前目标。它会决定 agent 遇到风险时先说明、先请求确认还是换一条低风险路径。所以提示词系统的重点已经从“让模型答得更好”升级成“让 agent 行为更稳定”。用一句话概括Prompt System 是 coding agent 的行为协议装配层。它给工具系统套上行动规则也给后面的记忆、上下文、计划、权限、hook 和 subagent 留出接口。记忆系统会在第 04 篇展开上下文管理放到第 05 篇权限第 07 篇讲hook 和扩展第 10 篇讲subagent 第 11 篇讲。提示词系统解决的工程问题让 agent 行为稳定LLM 会顺着当前上下文调整行为这正是它好用的地方。用户说“解释这段代码”它可以像讲解者用户说“帮我修构建错误”它可以像开发者用户说“审一下这段 diff”它可以像 reviewer。放到 agent 里这种适配能力需要一套稳定边界托住。没有稳定的行为协议容易出现几类问题身份漂移。同一个 agent 一会儿像教程老师一会儿像命令执行器一会儿像产品助手。用户很难形成稳定预期。工具误用。模型知道有工具还需要知道工具适合什么场景、参数怎么填、结果回来后怎样理解。项目规则被冲淡。真实仓库里有测试命令、目录约定、生成文件禁区、代码风格和团队习惯。这些规则靠用户每轮重复任务会很快变散。软规则盖过硬边界。“避免读取密钥文件”写进 prompt 可以提醒模型但敏感路径、危险命令和审批策略更适合交给权限系统。协作方式忽左忽右。同样是修 bug有时需要先列计划有时可以直接最小修改有时要先问用户业务选择。协议层要把这些分歧变成可判断的入口。提示词系统要做的就是把这些默认行为收束起来基础身份由系统提示承载项目约定由CLAUDE.md和 rules 承载工具使用由工具描述承载当前任务由用户输入承载硬边界由运行时机制承载。这样后面要调整行为时才知道该改哪里。提示词不是一段话而是一组可组合 section几篇源码分析文章都提到一个共同点Claude Code 的系统提示更像一条组装管线而非一段静态长文本。[1][2][3]这对我理解 Prompt System 很关键。如果 system prompt 只是一段手写文本那维护方式很简单改文字、调措辞、加规则。但 Claude Code 这种工具要面对不同项目、不同工具集合、不同 output style、不同 MCP 状态、不同用户任务。它需要按当前运行环境装配出一轮可用的提示上下文。可以把它想成几类 sectionsection 类型主要放什么变化频率基础身份agent 是软件工程任务助手怎样和用户沟通低行为规则读文件、最小改动、验证、输出方式低工具说明可用工具、参数、使用边界中项目规则CLAUDE.md、目录规则、项目命令中动态环境当前目录、shell、git 状态、日期、MCP 状态高当前任务用户本轮目标、临时限制、工具结果反馈高Siddhant Khare 的分析里提到Claude Code 有稳定区和动态区的边界也有用于构造 section 的内部接口其中有一类显眼命名的动态 section会提示开发者它会破坏缓存需要给出理由。[1] 这类函数名本身不是本文重点真正值得学的是背后的工程原则每一段提示都应该知道自己的来源、作用域、稳定性和成本。这让 prompt 从“一锅文本”变成了可维护的配置系统。稳定前缀和动态注入哪些规则适合长期存在提示词系统里有一条很重要的边界哪些内容适合长期稳定哪些内容应该按需注入。稳定内容适合放在前面例如基础身份、通用行为规则、常驻工具说明和输出约定。它们变化少模型每轮都需要看到适合形成稳定前缀。动态内容更适合放在后面例如当前目录、git 状态、临时 MCP 信息、用户本轮目标、工具结果和会话反馈。它们变化快放进稳定前缀会增加缓存成本也会让行为边界跟着环境频繁抖动。David Breunig 的文章把 Claude Code 的 system prompt 拆成很多组件有些始终进入有些按条件进入有些随 output style 或工具集合变化。[2]Piebald-AI 的提示词仓库也能看到类似现象Claude Code 相关提示并非只有一份工具描述、subagent 提示、utility prompts、compact prompt 等都会随版本演进。[5]所以 prompt system 的工程问题可以这样理解稳定规则要稳定动态事实要动态临时信息要有明确注入位置。这条边界后面会在上下文管理里继续展开。这里先记住一件事提示词系统既影响行为也影响成本和缓存命中。多来源提示system、CLAUDE.md、output style、command、skill、hookAgiflow 通过抓取 API payload把 Claude Code 里几类提示增强机制分成了不同注入点output style 改系统层CLAUDE.md、slash command、skill 进入消息层hook 作用在工具生命周期subagent 开新会话。[4]这张地图很有价值因为它说明这些入口是分工关系。它们各自适合解决不同问题。来源注入位置适合放什么后文展开system prompt系统层基础身份、通用行为、工具使用总规则本篇output style系统层补充表达风格、解释深度、角色口吻本篇CLAUDE.md/ rules消息层或项目上下文项目约定、命令、架构说明、目录规则第 05 篇连到上下文slash command单轮消息注入可复用流程、检查清单、固定任务模板第 10 篇skill按需注入专门领域流程、复杂能力说明第 10 篇hook工具生命周期工具前后补充、拦截、审计、自动化第 10 篇subagent独立会话大范围探索、专业任务、上下文隔离第 11 篇这张表也解释了为什么CLAUDE.md很重要但它不适合承载所有规则。项目级规则适合写进CLAUDE.md测试命令、目录结构、代码风格、生成文件说明、常见坑。临时任务指令适合放在用户当前 prompt。持续表达偏好适合 output style。需要自动执行或拦截的规则更适合 hook。需要隔离大块上下文的任务更适合 subagent。这样分开以后prompt system 就像一个带作用域的配置系统。每类规则都有自己的入口行为异常时也更容易排查。工具描述也是行为协议02 里已经讲过工具系统是一条从工具请求到结果回流的执行链。到了 Prompt System 这里要换个角度看工具工具描述本身也是提示词。模型会根据工具说明判断该不该用工具根据参数 schema 判断怎么填输入根据输出格式理解结果。工具描述写得清楚agent 更容易选对工具工具描述含糊agent 就会靠猜。比如搜索工具的描述如果只说“搜索文件”模型很难判断它和 shell 里的 grep 有什么区别。更好的说明应该让模型知道这个工具适合找路径、函数名、错误文本和调用点。返回值包含路径、行号和命中片段。命中很多时先缩小关键词再读关键文件。搜索结果只是候选证据最终判断要回到文件内容。命令工具也是一样。它需要说明工作目录、超时、退出码、stdout/stderr、可能副作用和失败格式。这样主循环拿到结果以后才知道下一轮该继续定位、重新验证还是停止总结。所以工具协议和提示词系统之间有一条很直接的连接工具描述决定模型如何理解行动选项。这也是为什么工具越多提示词系统越需要治理。工具说明本身会占上下文工具集合变化也会影响稳定前缀。工具膨胀和延迟加载在第 02 篇已经点到后面第 05 篇会从上下文成本继续讲。Prompt 和 runtime 的边界软规则与硬边界提示词系统很容易被写成万能开关把规则写进去模型就会照做。工程上更稳的划分是Prompt 负责表达意图和协作方式runtime 负责动作许可和硬边界。有些规则天然适合 prompt回答要简洁。修改前先读相关文件。尽量做最小改动。总结时说明验证结果。遇到不确定业务选择时询问用户。这些规则影响行为风格和工作方式属于软约束。另一些规则适合 runtime禁止读取.env、密钥、证书。删除文件前需要确认。危险 shell 命令需要审批。每次工具调用要记录审计。某些 hook 必须在编辑前后运行。这些规则涉及副作用、安全和组织策略需要硬边界。Prompt 可以提醒 agent 如何解释这些规则但最终放行、拒绝、拦截和记录应该交给权限、settings、hook 或工具层。Agiflow 对 hook 的观察也能支撑这个边界hook 发生在工具生命周期里可以确定性地注入信息、拦截动作或补充结果。[4]这类能力适合做运行时控制第 10 篇再展开。冲突和优先级多条规则同时出现时怎么办提示词系统真正麻烦的地方是多来源规则会同时出现。用户当前要求可能是“直接修掉”。项目CLAUDE.md可能要求“涉及多文件先列计划”。output style 可能偏向详细讲解。工具描述可能建议先搜索再读文件。权限系统又可能拦住某个写入或命令。这时需要一套简单的分层判断。冲突类型更稳的处理方式软偏好冲突让更具体、更近期的指令优先项目规则冲突在项目规则里写清覆盖关系工具使用冲突按工具描述和当前证据选择低成本路径安全边界冲突交给权限、hook、managed policy输出风格冲突当前任务需要优先例如修 bug 总结可以短教学场景可以长比如用户说“直接改”而项目规则说“多文件改动先列计划”。如果只改一个 Markdown frontmatteragent 可以直接做最小修改如果牵涉多个模块就应该先说明修改范围。再比如用户让 agent “顺手清理一下所有旧文件”这属于高风险范围扩张。Prompt 可以让 agent 解释风险权限系统决定实际动作能否执行。这个分层能减少模型猜测也能让用户更容易理解 agent 为什么这样做。案例分析构建失败时行为协议如何生效继续沿用前两篇的例子用户说“博客页面构建失败了帮我修一下”。工具系统会负责读package.json、跑构建、搜索报错、读文件、编辑和验证。提示词系统负责约束这些动作怎样发生。可以把这次任务里的行为协议写成一条事件流用户目标修复博客构建失败 - 基础行为先观察项目再做最小范围修改 - 项目规则遵守博客目录、frontmatter 和写作约定 - 工具契约先用搜索和读取定位证据再编辑目标文件 - 运行时边界写文件看 diff高风险命令交给权限 - 验收方式重新运行构建返回错误原因、改动和验证结果这个例子里用户只给了一个目标。真正让 agent 稳定行动的是多层协议一起生效系统提示让它保持软件工程任务助手的身份。项目规则告诉它博客文章和构建约定。工具描述告诉它怎样读文件、搜索、编辑、运行命令。用户当前指令给出任务目标和完成方向。权限与运行时边界控制有副作用的动作。这样一来“帮我修一下”就不再是一个模糊请求而是被组织成一条可执行、可验证、可解释的行动路径。对我写 Agent 的启发把 prompt 当成可维护配置如果以后自己写一个 coding agent我会先把 prompt system 当成配置系统来设计而不是当成一段长字符串。我会拆出几个区域区域放什么谁维护base promptagent 身份、协作方式、默认工程原则产品或平台tool contracts工具说明、参数、返回格式、错误含义工具开发者project rules项目命令、目录约定、代码风格项目团队user preferences长期表达偏好、协作偏好用户task prompt当前目标、限制、验收标准当前用户runtime guardrails权限、hook、敏感路径、审批策略平台或管理员feedback context工具结果、测试失败、用户纠正agent loop每条规则进入系统前都要问五个问题它的作用域是什么全局、项目、目录、任务还是单次工具调用它的 owner 是谁平台、项目、用户还是工具作者它的稳定性如何适合长期前缀还是适合动态注入它是软偏好还是硬边界它有没有验证方式能否通过日志、测试、权限结果或 hook 复盘这样做的好处是agent 行为变差时可以定位原因。是 output style 太啰嗦还是工具描述让模型误解还是CLAUDE.md写了过期命令还是 runtime guardrail 没有兜住风险。我也会让提示词版本可追踪。Piebald-AI 的仓库把 Claude Code 的提示片段、工具描述、subagent prompt 和 utility prompt 按版本整理出来这一点很有启发。[5] 对自己的 agent 来说prompt 变化也应该像代码变化一样能 diff、能回滚、能解释。最后是规则写法。“请谨慎”这类空泛表达帮助有限。更好的规则应该能落到行为修改前先读目标文件和相邻测试。多文件改动先列范围。写入后运行最小相关验证。验证失败时保留失败摘要和下一步假设。涉及删除、迁移、批量替换时先说明风险。这种规则才能真正改变 agent loop。参考资料Claude Code 源码与提示词分析[1] The plumbing behind Claude Code - Siddhant Khare本文主要参考它关于 system prompt 分段组装、稳定区和动态区边界、动态 section 影响缓存的分析。[2] How Claude Code Builds a System Prompt - David Breunig本文主要参考它对 Claude Code system prompt 组件化装配方式的可视化拆解。[3] Inside the Claude Code source - Haseeb Qureshi本文主要参考它关于可组合 prompt function、缓存边界和权限反馈链路的整理。[4] Claude Code Internals: Reverse Engineering Prompt Augmentation Mechanisms - Agiflow本文主要参考它关于CLAUDE.md、output style、slash command、skill、hook、subagent 不同注入位置的分析。[5] Piebald-AI/claude-code-system-prompts本文主要参考它对 Claude Code 多类提示片段、工具描述、subagent prompt 和 utility prompt 的版本化整理。下一篇Memory System这一篇先把提示词系统理解成 Claude Code 的行为协议装配层。核心结论是工具让 agent 能行动提示词系统决定 agent 按什么身份、项目规则、工具契约和协作方式行动。但行为协议解决的是“本轮怎么行动”。任务一旦跨越多轮、多天、多个项目agent 还需要沉淀长期偏好、项目经验和反复出现的用户要求。所以下一篇继续追的问题是Claude Code 如何把一次任务里的经验变成后续任务可以召回的记忆