news 2026/9/12 2:44:28

仓库内编程助手的系统提示词设计:HelloAgents Code Agent CLI 的角色边界、安全准则与补丁协议全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
仓库内编程助手的系统提示词设计:HelloAgents Code Agent CLI 的角色边界、安全准则与补丁协议全解析

仓库内编程助手的系统提示词设计:HelloAgents Code Agent CLI 的角色边界、安全准则与补丁协议全解析

【免费下载链接】hello-agents📚 《从零开始构建智能体》——从零开始的智能体原理与实践教程项目地址: https://gitcode.com/GitHub_Trending/he/hello-agents

导读

本文以 HelloAgents Code Agent CLI 的全局系统提示词 system.md 为主线,逐条拆解这个类似 Claude Code/Codex 的仓库内编程助手如何通过提示词定义「角色定位、路径安全边界、按需探索策略、补丁写盘协议与对话历史隔离规则」,并结合 code_agent.py、hello_code_cli.py 与 apply_patch_executor.py 的源码实现,说明这些「纸面规则」如何在运行时被真正执行。读完本文,你将理解如何为一个在真实代码仓库中自主工作的 Agent 设计系统提示词,并掌握一套可复制的安全落盘(patch-only write)协议。

一、system.md 在 Code Agent CLI 中的角色定位

HelloAgents Code Agent CLI 是一个基于 HelloAgents 框架组件(HelloAgentsLLM/ContextBuilder/ReActAgent/TerminalTool/NoteTool/MemoryTool)搭建的命令行智能体,目标体验对标 Claude Code/Codex:支持多轮对话、按需探索代码库、生成补丁并在用户确认后落盘(见 code_agent/README.md)。

提示词统一存放在 prompts 目录 下,各文件分工明确:

文件职责
system.md全局行为与安全边界(按需探索 / 敏感操作确认 / 补丁格式)
react.mdReAct 回合格式(Thought/Action)与工具输入约定
plan.md规划工具plan[...]专用提示词
summarize_observation.md工具输出摘要提示词
tools.md六个内置工具的详细使用指南

其中system.md是「总纲」:它定义了 Agent 是谁、能在哪里活动、能做什么、不能做什么、以什么格式产出修改。在源码中,它由 code_agent.py 在初始化时读取并作为system_prompt注入上下文构建器:

base_system = (self.paths.prompts_dir / "system.md").read_text(encoding="utf-8") self.tools_reference_path = self.paths.prompts_dir / "tools.md" self.system_prompt = base_system

也就是说,每次run_turn构建上下文时,这份提示词都会与对话历史、上次工具摘要一起拼入最终 Prompt(code_agent.py)。因此,它本质上是一份「持续生效的宪法」——不随单轮对话消失。

二、角色定位:仓库内工作的 CLI 编程助手,而非闲聊机器人

system.md 的第一句话就划定了身份:

你是一个"在仓库内工作的 CLI 编程助手"(类似 Claude Code/Codex),不是闲聊机器人。

这一定位直接决定了后续所有行为约束的取向:Agent 的所有动作都以「在指定仓库内完成任务」为唯一目标,回复追求简短直接。提示词末尾进一步规定了输出风格:

  • 非代码/非工具回复尽量 ≤4 行,直接给结论;
  • 避免 "Here is..." 等冗余开场;
  • 除非用户要求,不使用 emoji;
  • 事实性问题直接给结果。

这一「轻量输出」策略在源码层有配套的闲聊兜底:CodeAgent._is_chitchat会识别hi/hello/你好/在吗等问候词,直接返回固定引导语而不进入 ReAct 循环(code_agent.py),避免无谓的工具调用与解析失败。

三、工作区与路径安全边界:杜绝路径逃逸

system.md 规定「工作区固定为仓库根目录.」,并给出核心准则第一条:

边界:所有路径必须在 repo_root 内,resolve 后校验前缀,拒绝逃逸。

这条规则并非停留在提示词层面。在初始化时,CodeAgent.__init__会对repo_root执行resolve()(code_agent.py),把所有状态目录(notes / memory / sessions / logs)都收敛到<repo>/.helloagents/之下(由 CodeAgentPaths 统一管理)。

真正的硬校验在补丁执行器ApplyPatchExecutor._safe_path中(apply_patch_executor.py):

  1. 拒绝绝对路径(以/~开头);
  2. (repo_root / rel_path).resolve()解析出最终路径;
  3. 校验解析结果必须以repo_root前缀开头,否则抛出Path escapes repo_root
  4. 拒绝修改符号链接(symlink)。

这意味着即使模型在补丁中写出../../etc/passwd这类路径,执行器也会在落盘前拦截,形成「提示词约束 + 代码硬校验」的双保险。

四、按需探索:先证据后结论,避免无端全库扫描

system.md 第二条准则强调:

按需探索:只有确实需要证据时才调用终端;优先小范围命令(ls/rg --files/rg <pat> <path>/sed -n <range>p <file>/cat <file>);避免无端全库扫描。

这是 Code Agent 与「一次把整个仓库塞进上下文」的传统 RAG 方案的关键区别。配合源码中的lazy_fetch=True模式(code_agent.py),上下文构建只注入保底内容:

  • 系统提示 + 最近对话(max_history_turns=10)+ 上次工具摘要(最近 3 条);
  • 上下文预算控制:max_tokens=8000reserve_ratio=0.15enable_compression=True
  • 扩展上下文不再自动注入,而是由模型通过context_fetch[...]工具按需获取。

为了进一步控制上下文膨胀,工具输出会经过 LLM 摘要:_summarize_observation会先截断超过 8000 字符的输出,再用summarize_observation.md提示词压缩成 120~200 字左右的摘要(code_agent.py),并在输出超过 1800 字符时触发摘要(summarize_threshold_chars=1800)。这套「先推理 → 证据不足再取证 → 取证即摘要」的节奏,正是 system.md 与 react.md 中反复强调的「避免过度收集」。

五、写盘唯一通道:补丁协议

system.md 中最具实操价值的一条是:

写盘唯一通道:补丁 + apply_patch。严禁cat >/tee/ Here-Doc / 重定向等终端写法。

也就是说,模型想要修改任何文件,都不能借助 shell 的重定向技巧,只能输出结构化的补丁文本,由 CLI 侧解析并执行。这条规则从提示词到执行层形成了完整的闭环,我们分三层来看。

5.1 提示词层:补丁格式规范(system.md 原文)

产出补丁时必须严格遵守以下格式:

*** Begin Patch *** Add File: path/to/new_file.py 文件内容... 可以多行... *** Update File: path/to/existing_file.py 更新后的完整文件内容... *** Delete File: path/to/old_file.py *** End Patch

关键规则六条:

  1. 第一行必须是*** Begin Patch(前面不要有任何文字);
  2. 最后一行必须是*** End Patch
  3. 操作行格式:*** Add File: <path>/*** Update File: <path>/*** Delete File: <path>
  4. Add/Update 后面跟完整文件内容,Delete 后面不需要内容;
  5. 不要在补丁外包裹 markdown 代码块(不要用 ```);
  6. 路径相对于仓库根目录。

提示词还专门给出了错误与正确示例,防止模型把说明文字和补丁挤在同一行——例如*** Begin Patch前出现「这是一个补丁:」即视为错误。在 react.md 中,补丁必须放在Finish[...]内、与说明文字之间用空行分隔、*** Begin Patch独占一行,否则会因解析失败而无法落盘。

5.2 CLI 层:补丁提取、规范化与人工确认

hello_code_cli.py 负责从 LLM 回复中把补丁「抠」出来并决定是否需要人工确认:

  • 提取_extract_patch先用正则优先匹配代码围栏```patch/```diff/```text内的补丁,再退回宽松的*** Begin Patch ... *** End Patch全局匹配(hello_code_cli.py),对模型偶尔用围栏包裹补丁的行为做了容错;
  • 规范化_normalize_patch会把缺失***前缀的操作行(如Update File: xxx)自动补全为规范格式(hello_code_cli.py);
  • 确认策略_patch_requires_confirmation规定三类高风险补丁必须征求用户y/n(hello_code_cli.py)——包含*** Delete File:操作、涉及文件操作数 ≥ 6、变更行数(+/-开头行)≥ 400。

这与 system.md 中「高风险(删除/覆盖大量/危险命令 rm/chmod/git reset --hard)必须说明风险并征求确认;最终执行由 CLI 裁决」的表述完全对应——「裁决权」在 CLI,而不是模型。

5.3 执行器层:原子写、备份、冲突检测与规模限制

最终落盘由ApplyPatchExecutor完成(apply_patch_executor.py),它实现了 system.md 规则背后的全部安全工程细节:

  • 规模限制:单个补丁最多修改max_files=10个文件、max_total_changed_lines=800行,超出即拒绝;
  • 后缀白名单:默认只允许.py/.md/.toml/.json/.yml/.yaml/.txt/.html/.htm/.css/.js等文本文件,防止误改二进制或敏感文件(_enforce_suffix,apply_patch_executor.py);
  • 自动备份:每次应用前把将被修改的文件备份到<repo>/.helloagents/backups/<timestamp>/_backup_file,apply_patch_executor.py);
  • 原子写入:先写临时文件并fsync,再用os.replace原子替换目标,避免写盘中断导致文件损坏(_atomic_write,apply_patch_executor.py);
  • 冲突检测:Update 操作按 hunk 在原文中做精确子序列匹配,找不到上下文时抛出PatchApplyError并给出path:search:'关键字'形式的复查提示;同时提供「整文件替换」与「宽松匹配(忽略行尾空白)」两级容错(_apply_update_payload/_find_subsequence,apply_patch_executor.py);
  • 宽容解析_parse_patch会跳过前置/结尾的空行与代码围栏,容忍模型常见的格式漂移(apply_patch_executor.py)。

此外,补丁应用成功或失败后,CLI 都会通过NoteTool写入结构化笔记(note_type分别为actionblocker),把「发生过什么」沉淀下来,供后续轮次检索(hello_code_cli.py)。

六、对话历史边界:系统规则不是对话内容

system.md 专门用一段说明「对话历史的重要边界」:

  • [Role & Policies]是系统角色定义和工作规则,不是用户对话内容
  • 当用户询问「我们之前聊了什么/说了什么/总结对话」时,只总结[Context]区块中的[user]/[assistant]交互记录;
  • 不要把系统规则、工具定义、角色描述当作「对话内容」来总结
  • 总结对话时直接根据[Context]回答,不需要调用 memory 或 note 工具。

这条规则防止了两种典型事故:一是模型把「系统提示词」当成用户说过的话复述出来造成信息泄漏,二是为了回答「刚才聊了什么」这类元问题却去触发无谓的工具调用。源码层提供了双重保障:_is_history_query识别「说了什么 / 之前说了什么 / what did i say / recap」等模式(code_agent.py),命中后直接由_reply_with_recent_history从内存中的history取出最近用户/助手消息生成回顾(code_agent.py),完全绕过 ReAct 循环与工具系统。

七、工具体系:context_fetch 优先,其余按需

system.md 列出了六种 ReAct Action 可用的工具,并特别强调「优先使用聚合搜索工具」:

7.1 context_fetch[...](优先推荐)

按需获取扩展上下文,单次可查多源,自动控制预算(约 800 tokens/源):

{"sources": ["files","notes","memory","tests"], "query": "关键词", "paths": "src/**/*.py"}

使用策略:先用保底上下文(对话历史 + 上次工具结果)推理,证据不足再调用。它优于单独调用 note/memory search——一次调用可搜索多个数据源,避免多次工具调用导致上下文爆炸。在 prompts/tools.md 中,context_fetch的使用场景被进一步明确:搜索类名/函数名/错误栈、需要相关笔记/记忆时用;已经拿到足够证据、或用户仅问对话历史时不用。

7.2 其他工具

工具用途关键约束
terminal[...]只读检索(ls/rg/cat/sed/head/tail/grep/git status/diff)支持管道;重定向/子命令替换/危险命令需确认;写文件一律用补丁
note[...]记录关键结论/阻塞/行动,Markdown 持久化补丁成功/失败总结、阶段小结时使用
memory[...]跨会话情景记忆(SQLite)需显式 add,默认不自动写入
plan[...]多步/模糊任务生成计划5~12 条步骤,含 Risks 与 Validation 段落(见 plan.md)
todo[...]多步骤任务跟踪状态 pending/in_progress/completed,同时仅允许 1 个 in_progress

这些工具在CodeAgent.__init__中被逐一注册到ToolRegistry(code_agent.py),其中TerminalToolconfirm_dangerous=Truedefault_shell_mode=True初始化,与提示词「默认允许 shell 语义、危险操作需确认」一致。tools.md 还给出了每个工具的 JSON 调用示例,例如:

terminal[{"command":"rg -n \"foo\" context/**/*.py","allow_dangerous":false}] note[{"action":"create","title":"Patch applied","content":"...","note_type":"action","tags":["patch"]}] memory[{"action":"add","memory_type":"episodic","content":"完成 hello.html 样式改造","importance":0.7}] todo[{"action":"add","title":"设计简介页布局","desc":"头部/简介/技能","status":"pending"}]

八、复杂任务的执行节奏:计划 → 取证 → 补丁 → 确认 → 落盘 → 验证

system.md 将复杂任务总结为一条工作流:

复杂任务遵循"计划 → 取证 → 补丁 → 确认 → 落盘 → 验证"节奏,最小改动满足需求。

在 react.md 中,这一节奏被细化为可执行规则:

  • 每次回复必须同时包含ThoughtAction,缺一不可;
  • 已有足够信息时必须用Finish[答案]结束,不要为了「更全面」反复调用工具;
  • 一旦证据足够(rg 命中、关键文件片段、错误栈、配置项),必须Finish
  • 如果发现自己准备重复执行相同工具调用,说明没有新信息,应立即Finish给出结论 + 最小化下一步建议;
  • 多步骤任务(≥2 个子步骤、需用户确认、跨回合)先todo add再行动,结尾todo list汇总。

CodeAgent.run_turn还在用户输入命中「分步/步骤/计划/改造/完成后/多步」等词汇时,向系统提示追加一行轻量提示,引导模型先用 todo 跟踪(code_agent.py)。该提示不强制,只提高倾向。

九、实际运行:环境配置与 CLI 命令

要让上述全部规则生效,需要按 code_agent/README.md 的快速开始配置并启动:

  1. 安装依赖(根目录requirements-mvp.txt),并在仓库根目录创建.env(可参考.env.example),至少包含:

    • DEEPSEEK_API_KEY=...(或其他 OpenAI 兼容 provider 的 key)
    • 可选:LLM_MODEL_ID=deepseek-chatLLM_BASE_URL=https://api.deepseek.com
  2. 启动 CLI(工作区默认.):

python3 -m code_agent.hello_code_cli --repo .
  1. 内置命令:
    • :quit退出;
    • :plan <目标>强制生成计划(平时由模型按需调用plan[...]工具,见 hello_code_cli.py)。

启动时 CLI 会打印 workspace、LLM provider/model/base_url 与 state 目录,并做一次ping预检,提前暴露 API key / base_url / model 配置问题(hello_code_cli.py)。

可调环境变量:

变量默认值作用
HELLOAGENTS_DIR.helloagents状态目录(notes/memory/sessions/logs)根路径
CODE_AGENT_MAX_STEPS8ReAct 最大推理步数

十、小结:一份「提示词 + 代码」双闭环的 Agent 安全范式

回顾 system.md,它的设计价值可以归纳为四个层次:

  1. 身份层:明确「仓库内编程助手」而非闲聊机器人,输出风格极简;
  2. 边界层:路径必须留在 repo_root 内,写盘只能走补丁通道,危险操作必须确认;
  3. 效率层:按需探索、先保底上下文后取证、工具输出即时摘要,控制上下文预算;
  4. 可审计层:补丁应用有备份、有冲突检测、有成功/失败笔记,每一次修改都可追溯。

更重要的是,这些提示词规则并非「纸上谈兵」——ApplyPatchExecutor的路径校验与原子写、hello_code_cli.py的补丁提取与确认策略、CodeAgent的闲聊/历史查询拦截,共同保证了提示词约束在代码层的强制执行。对于任何想构建「在真实仓库里安全自主工作」的 Agent 的开发者,这份 system.md 连同 react.md、tools.md 与执行器源码,是一套可以直接对照复用的完整参考实现。

【免费下载链接】hello-agents📚 《从零开始构建智能体》——从零开始的智能体原理与实践教程项目地址: https://gitcode.com/GitHub_Trending/he/hello-agents

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 2:44:24

Experiment Design: [Product/Feature Area]

Experiment Design: [Product/Feature Area] 【免费下载链接】pm-skills PM Skills Marketplace: 100 agentic skills, commands, and plugins — from discovery to strategy, execution, launch, and growth. 项目地址: https://gitcode.com/GitHub_Trending/pm/pm-skills …

作者头像 李华
网站建设 2026/9/12 2:43:43

UC3843AC反激电源方案设计实战:从原理到调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 2:42:58

微服务架构转型:从单体到可扩展系统的实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 2:42:56

二维CT图像重建原理与FBP实战指南

简介&#xff1a;本资源是一套面向医学影像处理初学者与MATLAB编程学习者的CT二维图像重建实践程序&#xff0c;聚焦傅里叶变换法与滤波反投影法&#xff08;FBP&#xff09;两大核心算法的代码实现与原理验证。资源包共3个文件&#xff08;2个MATLAB源码文件.m 1个说明文档.t…

作者头像 李华
网站建设 2026/9/12 2:42:52

DeepSeek Harness 从零搭建 AI Agent:文档自动读取与总结实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华