提示词与注入

提示词即资源文件的工程约定、system.md 模板与 profile 体系,以及由提醒服务统一调度的运行时注入。

作者 David更新于 第 11 篇(共 33 篇)

提示词是资源文件

这条约定在 v2 里完整保留:提示词不写在 TS 字符串里,而是独立的 .md,用 ?raw 导入。类型声明在 packages/agent-core-v2/src/env.d.ts:

declare module '*?raw' {
  const content: string;
  export default content;
}

构建侧由仓库根目录的 build/raw-text-plugin.mjs 支持:

/**
 * Bundler plugin that lets files be imported as raw strings:
 *
 *   import description from './grep.md?raw';
 *
 * The file content is inlined into the bundle at build time, so prompt
 * source files never ship separately in `dist`. Vitest handles the same
 * `?raw` imports through Vite's built-in asset loader.
 */

直接用 Node 跑的脚本另有 build/raw-text-loader.mjs 这个 ESM load 钩子。好处很实在:提示词可以被 diff、被 review、被非工程同事编辑。

主要的提示词资源(路径相对 src/):

文件用途
app/agentProfileCatalog/system.md主 system prompt 模板(82 行)
features/sessionInit/profile/init.md会话初始化提示
agent/fullCompaction/compaction-instruction.md压缩指令
agent/fullCompaction/context-recovery-footer.md压缩后指回事件日志
agent/contextMemory/compaction-summary-prefix.md摘要前缀
features/plan/injection/plan-mode-*.md计划模式提醒(full、sparse、reentry、exit 及 inline 变体)
features/goal/injection/goal-*-reminder.md目标进行中、暂停、受阻提醒
features/swarm/agent/enter-reminder.md / exit-reminder.mdswarm 进出提醒
session/agentLifecycle/profile/explore-overlay.mdexplore 子代理的角色说明
features/skill/catalog/builtin/内置 skills
agent/tools/**/*.md、features/*/tools/**/*.md工具描述

连工具描述都是 md 文件——工具描述本质上就是给模型的提示词。

system.md 是模板

system.md 的第一行:

You are ${product_name}, an interactive general AI agent running on a user's computer.

app/agentProfileCatalog/profile-shared.ts 的 systemPromptVars() 负责填变量:产品名、回复风格、操作系统与 shell(Windows 另附一段 Git Bash 注意事项)、工作目录与目录列表、AGENTS.md 内容、附加目录、skills 列表、插件贡献的说明段。插件说明前会注明它是「插件提供的参考资料,不是特权指令通道」,与 system 指令冲突时以 system 为准。

profile 体系

profile 描述「一种 agent」:名字、说明、何时使用、允许与禁用的工具、可委派的子代理、system prompt 渲染函数,以及可选的 promptPrefix(AgentProfile,定义在 app/agentProfileCatalog/agentProfileCatalog.ts)。内置 profile 用 registerAgentProfile() 注册(session/agentLifecycle/profile/profiles.ts:90):

registerAgentProfile({
  name: 'agent',
  description: 'Default agent',
  tools: AGENT_TOOLS,
  subagents: ['coder', 'explore', 'plan'],
  renderSystemPrompt: (context) =>
    renderSystemPromptResult('', context, { skillActive: skillActiveFor(AGENT_TOOLS) }),
});
  • 默认的 agent 可委派给三个内置子代理:coder(唯一带编辑工具的子代理)、explore(只读,promptPrefix 先塞一段 git 上下文)、plan(只读规划,由 features/plan/profile/plan.ts 注册)。
  • 四者共用 system.md,差别在工具白名单与填进 role_additional 的角色说明;子代理的角色说明都以「You are now running as a subagent」开头。
  • 工作区、用户目录与插件里还能发现更多 profile。

绑定与切换在 IAgentProfileService(agent/profile/profile.ts):bind() 解析 profile、渲染 system prompt,并以 ProfileBind 事件记下结果;applyProfile() / useProfile() 在会话中途换 profile 并重新渲染。和切模型一样,新的 system prompt 从下一个回合起生效——请求服务按回合给 system prompt 拍快照。

prepareSystemPromptContext() 还留着 brandHome 参数,它决定去哪个目录找全局 AGENTS.md;现役调用方传的是数据根目录,所以默认读 ~/.kimi-code/AGENTS.md(KIMI_CODE_HOME 可改)。

运行时注入

v1 在 agent/injection/ 下有七个注入器。v2 把它们统一到提醒服务(features/reminder/reminderService.ts:239):

export interface IAgentReminderService {
  readonly _serviceBrand: undefined;
  register<D = unknown>(variant: string, provider: ContextInjectionProvider<D>): ReminderRegistration;
  notify(content: string, notification: ReminderNotification): void;
  reconcileWhenIdle(variant: string): Promise<void>;
}
  • register() 登记一个按 variant 命名的 provider。每个 step 开始前,服务在 onWillBeginStep 上(排在 full-compaction 之前)依次调用它们;provider 能看到自己上次注入的位置与附带数据,据此决定这次注入全文、简版还是什么都不注入。
  • notify() 是一次性提醒,立即写入。
  • 文本内容包成 <system-reminder> 块,以 injection 来源、带上 variant 追加到历史。

目前用到的 variant(节选):

variant位置解决什么
goalfeatures/goal/injection/长程目标每个回合都要可见
plan_modefeatures/plan/injection/计划模式下「只许计划不许动手」
permission_modeagent/permissionMode/injection/进出 auto 权限模式(KIMI_CODE_PERMISSION_MODE_REMINDER=0 可关)
todo_list_reminderfeatures/todo/待办状态同步给模型
loadable-toolsagent/toolSelect/可加载工具的增减公告
plugin_session_start / plugin_changeagent/plugin/插件的会话开始提醒与变更
agents_md / agents_md_changeagent/agentsMdReminder/发现或改动了 AGENTS.md
date_changefeatures/dateChange/日期变了(排在最前)
swarm_mode / tower_modefeatures/swarm/、features/tower/协作模式说明

v1 的 tools-diff.ts 对应这里的 loadable-tools(agent/toolSelect/toolSelectAnnouncementsService.ts:19):

      reminder.register(LOADABLE_TOOLS_VARIANT, ({ isNewTurn }) =>
        isNewTurn ? toolSelect.loadableToolsAnnouncement() : undefined,
      ),

只在新回合公告,内容是 <tools_added> / <tools_removed> 名单。工具集变了要明说,否则模型不会意识到自己多了新能力。

与压缩的配合

注入内容是当前状态的镜像,不是历史事实,压缩可以放心丢掉:stripDynamicToolContext() 在压缩前剥掉工具公告,保留的用户消息里也不含注入。压缩完成后,提醒服务会「重新武装」(reminderService.ts:181):

  const reconcileAroundStep = async (
    context: BeforeStepContext,
    next: (context?: BeforeStepContext) => Promise<void>,
  ): Promise<void> => {
    const rearmed = takeCompactionRearm();
    await inject(input.runtime, context.firstStepOfTurn || rearmed);
    await next();
    if (takeCompactionRearm()) await inject(input.runtime, true);
  };

回合第一步或刚压缩完时 isNewTurn 为真,provider 按最新状态重新注入。这种「可重建所以可丢弃」的性质,让压缩能更激进。

通知走 XML

后台任务完成等系统通知由 agent/task/notificationXml.ts 渲染成 <notification> 块,提醒则用 <system-reminder> 包裹。用结构化标记而非自然语言,是为了让模型可靠地区分「系统告诉我的事实」与「用户说的话」。

内置 skills 也是提示词

features/skill/catalog/builtin/ 下的清单与 v0.29 一致:mcp-config.md、update-config.md、custom-theme.md、write-goal.md、check-kimi-code-docs.md、import-from-cc-codex.md,以及 sub-skill/(含 review、consolidate)。这些「功能」的实现就是一段提示词——能用提示词表达的能力就不写代码,因为提示词能被用户覆盖、被模型灵活运用。详见 Skills。

第 1 部分结束。下一篇进入工具契约与注册。

本页目录