提示词与注入
提示词即资源文件的工程约定、system.md 模板与 profile 体系,以及由提醒服务统一调度的运行时注入。
提示词是资源文件
这条约定在 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.md | swarm 进出提醒 |
session/agentLifecycle/profile/explore-overlay.md | explore 子代理的角色说明 |
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 | 位置 | 解决什么 |
|---|---|---|
goal | features/goal/injection/ | 长程目标每个回合都要可见 |
plan_mode | features/plan/injection/ | 计划模式下「只许计划不许动手」 |
permission_mode | agent/permissionMode/injection/ | 进出 auto 权限模式(KIMI_CODE_PERMISSION_MODE_REMINDER=0 可关) |
todo_list_reminder | features/todo/ | 待办状态同步给模型 |
loadable-tools | agent/toolSelect/ | 可加载工具的增减公告 |
plugin_session_start / plugin_change | agent/plugin/ | 插件的会话开始提醒与变更 |
agents_md / agents_md_change | agent/agentsMdReminder/ | 发现或改动了 AGENTS.md |
date_change | features/dateChange/ | 日期变了(排在最前) |
swarm_mode / tower_mode | features/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 部分结束。下一篇进入工具契约与注册。