news 2026/9/28 2:42:19

ForgeCode 自定义 Agent 系统提示模板解析:从 Handlebars 模板到运行时系统上下文的完整实现指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ForgeCode 自定义 Agent 系统提示模板解析:从 Handlebars 模板到运行时系统上下文的完整实现指南
  • 人工智能
  • AI Agent
  • 代码智能体
  • AI 应用
  • CLI
  • 开发工具

【免费下载链接】forgecode

AI enabled pair programmer for Claude, GPT, O Series, Grok, Deepseek, Gemini and 300+ models

项目地址:https://gitcode.com/gh_mirrors/forge39/forgecode
点击查看免费下载

ForgeCode(本仓库项目)支持通过 Markdown + YAML Frontmatter 定义自定义 Agent,而templates/forge-custom-agent-template.md正是所有自定义 Agent 在运行时被渲染进系统提示(system prompt)的公共骨架模板。它负责注入环境信息、工具说明、项目规范与不可协商规则,是整个 Agent 行为约束体系的“第二块拼图”。读完本文,你将掌握该模板的每一段结构、全部 Handlebars 条件变量与 partial 引用、它与SystemContext的对应关系,以及如何基于它编写可被正确渲染的自定义 Agent 定义文件。

模板的定位:自定义 Agent 的非静态系统提示块

在 ForgeCode 中,Agent 的系统提示由两部分组成:Agent 定义文件中 Frontmatter 之后的正文(静态模板)与公共模板forge-custom-agent-template.md(非静态块)。两者的拼接发生在 system_prompt.rs:

let static_block = TemplateEngine::default() .render_template(Template::new(&system_prompt.template), &ctx)?; let non_static_block = TemplateEngine::default() .render_template(Template::new("{{> forge-custom-agent-template.md }}"), &ctx)?; context.set_system_messages(vec![static_block, non_static_block])

也就是说:只要 Agent 定义中带有system_prompt字段,系统就会先渲染 Agent 自身的正文模板,再渲染本公共模板,两者共同构成送入模型的系统消息。{{> forge-custom-agent-template.md }}是 Handlebars 的 partial 引用语法,模板引擎在初始化时通过include_dir!将整个templates/目录嵌入二进制(见 template_engine.rs),因此渲染发生在本地、无需读取文件系统。

模板全文结构总览

forge-custom-agent-template.md的核心由六个顶层区块组成,每个区块都用尖括号 XML 风格标签包裹,便于模型识别结构化指令:

区块标签渲染条件内容来源
<system_information>始终渲染partialforge-partial-system-info.md
<available_tools>仅当模型不支持工具时上下文tool_information
<tool_usage_example>仅当模型不支持工具时partialforge-partial-tool-use-example.md
<tool_usage_instructions>始终渲染固定文本 + 条件分支
<project_guidelines>仅当存在custom_rules上下文custom_rules
<non_negotiable_rules>始终渲染固定文本 + 条件分支

这种“条件区块 + 常量区块”的组合设计,使同一套模板能同时适配支持原生工具调用的模型(如 Claude、GPT 系列)与仅支持文本输出的模型(通过tool_supported开关动态注入 JSON 工具调用示例)。

环境信息注入:<system_information>与 partial

模板第一段通过 partial 引用 forge-partial-system-info.md,向模型注入当前运行环境:

<system_information> {{> forge-partial-system-info.md }} </system_information>

该 partial 渲染出的内容包括:

  • <operating_system>、<current_working_directory>、<default_shell>、<home_directory>:分别来自上下文的env.os、env.cwd、env.shell、env.home;
  • <file_list>:当上下文存在files时,逐个列出工作区相关文件/目录路径;
  • <workspace_extensions>:当上下文存在extensions时,展示git ls-files统计的扩展名分布(files属性记录 git 跟踪文件总数,extensions属性记录去重后的扩展名总数),并标注“仅显示前 N 个扩展名,其余占比 X%”。

扩展名统计的实际生成逻辑在 system_prompt.rs 与 system_prompt.rs:运行时通过git ls-files拉取全部跟踪文件,按扩展名计数、降序排序后截断到max_extensions个,剩余扩展名统一汇总为remaining_percentage。仓库自带的测试用例(如test_parse_extensions_sorts_git_output、test_parse_extensions_truncates_to_max)验证了排序、截断与百分比计算的正确性。这些统计信息让模型在开始编码前就能感知项目的语言构成与规模。

工具能力适配:<available_tools>与<tool_usage_example>

模板核心的设计智慧在于按模型能力动态渲染工具相关内容:

{{#if (not tool_supported)}} <available_tools> {{tool_information}}</available_tools> <tool_usage_example> {{> forge-partial-tool-use-example.md }} </tool_usage_example> {{/if}}
  • 当上下文tool_supported为false(模型不支持原生工具调用)时,模板会额外注入两个区块:<available_tools>输出ToolUsagePrompt序列化的工具清单,<tool_usage_example>则通过 partial forge-partial-tool-use-example.md 给出<forge_tool_call>包裹的 JSON 调用示例,告诉模型“每条消息只能调用一个工具、工具调用必须遵循{"name": ..., "arguments": {...}}结构”;
  • 当tool_supported为true时,这两个区块整体省略,避免向原生支持工具调用的模型灌输文本协议噪音。

tool_supported的判定逻辑见 system_prompt.rs:优先读取 Agent 定义中的tool_supported字段,未设置时回退到当前模型(model.tools_supported)的声明,再回退为false。

工具使用总则:<tool_usage_instructions>

该区块始终渲染,内容根据模型是否支持工具调用产生两个分支:

<tool_usage_instructions> {{#if (not tool_supported)}} - You have access to set of tools as described in the <available_tools> tag. - You can use one tool per message, and will receive the result of that tool use in the user's response. - You use tools step-by-step to accomplish a given task, with each tool use informed by the result of the previous tool use. {{else}} - For maximum efficiency, whenever you need to perform multiple independent operations, invoke all relevant tools (for eg: `patch`, `read`) simultaneously rather than sequentially. {{/if}} - NEVER ever refer to tool names when speaking to the USER even when user has asked for it. For example, instead of saying 'I need to use the edit_file tool to edit your file', just say 'I will edit your file'. - If you need to read a file, prefer to read larger sections of the file at once over multiple smaller calls. </tool_usage_instructions>

两个分支分别规定“串行单工具调用”与“并行多工具调用”策略,由tool_supported与supports_parallel_tool_calls共同决定(后者在 system_prompt.rs 中依据模型能力查询)。公共部分则约束:对用户绝不提工具名、读文件时优先整段读取。上下文中的supports_parallel_tool_calls字段(见 system_context.rs)专门为 Handlebars 分支提供布尔值。

项目规范注入:<project_guidelines>与 custom_rules

模板为“每个 Agent 可携带自定义规则”预留了插槽:

{{#if custom_rules}} <project_guidelines> {{custom_rules}} </project_guidelines> {{/if}}

custom_rules是上下文字符串,其来源在 system_prompt.rs:将 Agent 定义中的custom_rules与应用层注入的custom_instructions收集后用\n\n拼接。只有当该字符串非空时<project_guidelines>才会被渲染,避免空标签浪费上下文。同时,模板末尾的不可协商规则中还有一句条件追加:

{{#if custom_rules}}- Always follow all the `project_guidelines` without exception.{{/if}}

即:存在项目规范时,强制模型无条件遵守。

行为底线:<non_negotiable_rules>逐条拆解

这是模板中信息密度最高的常量区块,定义了所有自定义 Agent 必须遵守的通用行为底线:

  1. 结构化输出:每项任务结束时,必须用 Markdown 语法向用户整齐呈现工作成果;
  2. 不多做不少做:只做被要求的事;
  3. 禁止无谓建文件:除非达成目标绝对必要,绝不创建文件;
  4. 优先编辑现有文件:编辑已有文件永远优于新建文件;
  5. 严禁擅自创建文档:绝不创建*.md、*.txt、README、CHANGELOG、CONTRIBUTING 等文档文件(包括摘要/概览、架构文档、迁移指南/HOWTO 等说明性文件),除非用户明确要求;说明内容应放在最终回复或代码注释中。custom_rules部分还补充了“Always follow all theproject_guidelineswithout exception”;
  6. 代码引用格式强制统一:引用代码必须使用filepath:startLine-endLine(区间)或filepath:startLine(单行)的精确格式,并给出正反示例(如src/main.rs:10为正确,"see src/main.rs lines 25-30"为错误);
  7. 无限上下文:对话通过自动摘要获得无限上下文,目标未完全达成前不得停止;
  8. 文件标签协议:用户可用@[<file name>]格式标记文件随消息发送,模型不得重读这些文件;
  9. 禁用 emoji:除非用户明确要求,所有沟通中避免使用 emoji;
  10. 规范联动:存在custom_rules时无条件遵守project_guidelines。

这些规则与模板中引用的其他 partial(如 forge-partial-tool-error-reflection.md、forge-pending-todos-reminder.md 等)共同构成 Agent 的完整行为约束体系。

模板背后的运行时上下文:SystemContext 全景

模板中出现的全部变量都来自SystemContext(见 system_context.rs),字段与模板用法的对应关系如下:

SystemContext 字段模板中的引用方式说明
env{{env.os}}等(经 partial)操作系统、工作目录、shell、home
filespartial 中{{#each files}}工作区相关文件列表
extensionspartial 中扩展名统计git ls-files派生
tool_supported{{#if (not tool_supported)}}模型是否支持工具
tool_information<available_tools>正文工具清单(不支持工具时)
supports_parallel_tool_calls{{#if ...}}分支是否支持并行工具调用
custom_rules<project_guidelines>Agent + 应用层自定义规则
skillspartialforge-partial-skill-instructions.md可用技能列表
tool_names{{tool_names.read}}等当前 Agent 实际拥有的工具名映射
model可选当前模型信息
agents可选可委派任务的子 Agent 列表
config可选工具描述模板配置(如读取行数上限)

特别值得注意的是tool_names:在 system_prompt.rs 中,它会过滤为“当前 Agent 实际拥有的工具集合”,因此模板与 Agent 正文中可以用{{#if tool_names.task}}之类的条件渲染“是否启用某工具对应章节”,实现工具能力感知的提示词裁剪。

渲染引擎:Handlebars 实例的配置细节

所有模板都由 template_engine.rs 中配置的 Handlebars 实例渲染,关键设置:

  • strict mode 开启:模板中引用了上下文中不存在的变量会直接报错,防止静默渲染出空内容;
  • no_escape注册:关闭默认 HTML 转义,保证提示词中 XML 标签、JSON 与代码原样输出;
  • 自定义 helper:inc(自增,用于 1 起始编号)、json(将值序列化为 JSON 字符串)、contains(判断数组是否包含某值,配合{{#if (contains array "value")}}使用,测试覆盖见同文件test_contains_helper_*系列);
  • 嵌入式模板注册:通过forge_embed::register_templates将templates/目录整体嵌入,{{> partial}}引用无需外部文件。

编写自定义 Agent:Frontmatter 字段全集与加载机制

自定义 Agent 本质上是“YAML Frontmatter + Handlebars 正文”的 Markdown 文件。解析由 gray_matter 完成(见 agent.rs),Frontmatter 反序列化为AgentDefinition(见 agent_definition.rs),支持的字段如下:

字段类型默认/范围说明
id必填—唯一标识,用于冲突消解与切换
title/description可选—人类可读的标题与用途描述
provider/model可选回退到会话默认指定该 Agent 使用的提供商与模型
system_prompt可选—正文作为静态系统提示模板
user_prompt可选—用户侧提示模板(可含事件上下文)
tools可选—允许使用的工具列表,如["read","write","patch","shell","mcp_*"]
tool_supported可选回退到模型是否支持工具调用
custom_rules可选—注入<project_guidelines>的规则文本
temperature可选0.0–2.0随机性;未设置用提供商默认
top_p可选0.0–1.0核采样阈值
top_k可选1–1000保留的高概率 token 数
max_tokens可选1–100000单次响应长度上限
max_turns可选—Agent 最大轮数
max_tool_failure_per_turn可选—单轮工具连续失败次数上限
max_requests_per_turn可选—单轮请求次数上限
reasoning可选—推理配置(enabled、effort、max_tokens)
compact可选—上下文自动压缩配置

字段取值范围均有源码级验证:temperature、top_p、top_k、max_tokens的反序列化校验测试见 agent_definition.rs,越界值(如temperature: 2.1、top_k: 1001、max_tokens: 100001)会直接解析失败。

Agent 的加载源与优先级见 agent.rs:

  1. 内置 Agent:forge、muse、sage(编译期嵌入);
  2. 全局自定义:全局 Agent 目录下的*.md(如~/.forge/agents/);
  3. 项目内自定义:当前工作目录下.forge/agents/中的*.md。

三者按CWD 项目内 > 全局自定义 > 内置的优先级以 ID 消解冲突(resolve_agent_conflicts保留最后一次出现的定义)。内置forgeAgent 的完整定义见 forge.md,其中演示了{{tool_names.todo_write}}、{{#if tool_names.sem_search}}条件分支、{{> forge-partial-skill-instructions.md}}partial 引用等模板语法在真实 Agent 中的组合用法。

实战:最小可用自定义 Agent 与完整配置示例

仓库测试夹具提供了两个可直接参考的示例。最简形式见 basic.md:

--- id: "test-basic" title: "Basic Test Agent" description: "A simple test agent for basic functionality" system_prompt: "You are a helpful assistant for basic tasks." --- This is a basic test agent used for testing fundamental functionality.

只需id加正文即可生效——正文会作为静态块渲染,公共模板会自动补齐环境信息与行为规则。

完整配置形态见 advanced.md:

--- id: "test-advanced" title: "Advanced Test Agent" description: "An advanced test agent with full configuration" model: "claude-3-5-sonnet-20241022" tool_supported: true tools: ["fs_read", "fs_write", "shell"] temperature: 0.7 top_p: 0.9 max_tokens: 2000 max_turns: 10 reasoning: enabled: true effort: "high" max_tokens: 1000 --- # Advanced Test Agent This is an advanced test agent that demonstrates all configuration options available for agent definition.

将它保存为.forge/agents/xxx.md(项目内)或全局 Agent 目录(全局生效)后,运行时即可被 agent.rs 发现并加载。若需在正文中引用工具名或做条件渲染,直接使用{{tool_names.xxx}}与{{#if tool_names.xxx}},例如内置forge.md中“语义搜索可用时优先用sem_search,否则退回fs_search”的写法。

小结:模板如何统一并约束所有自定义 Agent

forge-custom-agent-template.md的存在,让用户自定义 Agent 无需重复编写环境注入、工具协议、输出规范与不可协商规则——只需提供id与核心指令,其余由公共模板在运行时自动补齐。它通过 Handlebars 条件分支实现对“支持/不支持工具模型”“有无自定义规则”“是否并行调用”等场景的自适应,再配合SystemContext的运行时数据注入,最终形成一份结构清晰、信息完备、行为约束明确的系统提示。理解这份模板,是深入定制 ForgeCode Agent 行为、编写高质量自定义 Agent 的第一步。

  • 人工智能
  • AI Agent
  • 代码智能体
  • AI 应用
  • CLI
  • 开发工具

【免费下载链接】forgecode

AI enabled pair programmer for Claude, GPT, O Series, Grok, Deepseek, Gemini and 300+ models

项目地址:https://gitcode.com/gh_mirrors/forge39/forgecode
点击查看免费下载

相关推荐

上一篇:IT-Tools 加密解密实战:HMAC 生成、JWT 解析与 RSA 密钥三个场景讲明白
下一篇:AGENTS.md完整指南:为AI编码助手创建标准化配置文件

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

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

树莓派+Pixhawk:无人机自主巡航与视觉精准降落实战

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

作者头像 李华
网站建设 2026/9/28 2:37:26

Hi3516CV610平台YOLOv8全流程部署实战:从训练到板端优化

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

作者头像 李华
网站建设 2026/9/28 2:37:19

嵌入式OTA服务实战:从固件交付到商业化落地

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

作者头像 李华