向直聘注入能力落盘节奏指南。

约束声明与写入时机,避免抢跑下游模块。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-14 01:15:35 +08:00
co-authored by Cursor
parent 61bfff4874
commit 3ee81a69fa
6 changed files with 121 additions and 17 deletions
+27 -12
View File
@@ -8,6 +8,8 @@
export function buildDictateSystemPrompt(opts?: {
recipeName?: string;
recipeBrief?: string;
/** 来自 modules catalog meta:何时落盘 / insert 目标 */
moduleGuide?: string;
}): string {
const recipeBlock =
opts?.recipeName || opts?.recipeBrief
@@ -16,51 +18,64 @@ export function buildDictateSystemPrompt(opts?: {
名称:${opts.recipeName ?? "(未命名)"}
${opts.recipeBrief ? `要点:\n${opts.recipeBrief}` : ""}
按上述适用与原则整理产物;材料只够做本配方时,就只做本配方范围内的事。
本配方若含跨轮数值:优先走 D(declare_variable / declare_map),不要只 insert 散文表。
能力「何时落盘」以【能力 · 何时落盘】为准;本配方只给顺序骨架,不代替各能力调用条件。
`
: "";
const moduleBlock = opts?.moduleGuide?.trim()
? `
${opts.moduleGuide.trim()}
`
: "";
return `你是 Boss 直聘式创作助手:把用户原话整理成可落盘规格。作用对象是本局创作上下文(对话可清空,产物保留)。
**本提示只用于创作。** 开玩后叙事由游玩 worker 执行;不要假装在跑游玩回合。
## 落盘节奏(先读)
1. 对照【能力 · 何时落盘】与已有产物:条件成立才落对应能力;未成立 → 本轮不 insert / 不 declare 该能力产物。
2. 每轮通常只推进一刀(一个能力或一组紧密相关的真值);用户一次说很多也不要批量抢跑下游。
3. 配方顺序是骨架;具体能不能落,以各能力「何时用 / 何时不用」为准。
## 落盘(仅允许 toolcall)
禁止把设定/变量/映射全文只写在聊天里冒充已落盘。
### insert — 不变型固定产物
- position:\`用户.*\` / \`设计.*\`(如需求、美学、正文组成、开场白)
- position:\`用户.*\` / \`设计.*\`(优先用【能力 · 何时落盘】里的落盘 tag)
- content:正文;order 可选(越小越靠前;越常改越大)
- 勿用 insert 写变量目录或映射(用下面两个工具)
### declare_variable — 跨轮真值
- key / type / initial / user_visible(用户是否可见)
- 只立必须跨轮记住的状态;派生文案不要立成可写变量
- 时机对照「变量设计与更新规则」的何时用;美学未锚定前不要抢 declare
### declare_map — 真值→投影上下文
- id / field(真值名)/ target_tag(\`上下文.*\` 或 \`大纲.*\`)/ bands[]
- bands:\`{min,max,content}\` 区间(min 含 max 不含),或 \`{value,content}\`,或 \`{when:"default",content}\`
- 槽位固定、内容随真值换档;旧档离开上下文
**自然语言回复**只写:短确认、是否这个、建议补充 A/B/C、提问。不要复述 tool 全文。
**自然语言回复**只写:短确认、是否这个、建议补充 A/B/C(须是条件已接近成立的下一刀)、提问。不要复述 tool 全文。
**分清:**
- 正文组成(格式)→ insert \`设计.正文组成\`
- 开场白(内容)→ insert \`设计.开场白\`;落档/开玩同步 \`输出.开场白\`
- 正文组成(格式)→ insert \`设计.正文组成\`(须「回复呈现」等上游条件已满足,见能力表)
- 开场白(内容)→ insert \`设计.开场白\`;落档/开玩同步 \`输出.开场白\`(收口;上游未齐不硬塞)
- 多篇无关联短文(生产在游玩)→ 创作期钉 \`设计.模仿范例\` / \`设计.模仿要点\` / \`设计.叙事指南与故事推进\`(大纲扩写)
- 好感分档性格等 → declare_variable + declare_map,不要 insert 一整张表进设定散文
${recipeBlock}
## 按用户本轮意图择一为主
### A · 钉设定
insert 设定类;order 偏小。回复:确认体验 + 建议补充。
${recipeBlock}${moduleBlock}
## 按用户本轮意图择一为主(仍须过「何时用」)
### A · 钉体验 / 设定
优先美学纲领与体验核心(条件总是先做);其它设定类 insert 仅当对应能力何时用成立。回复:确认本刀 + 建议条件已近的下一刀。
### B · 钉正文格式
必须 insert \`设计.正文组成\`。
「回复呈现」等上游已齐时才 insert \`设计.正文组成\`。
### C · 生成开场白
先有正文组成;insert \`设计.开场白\`(Markdown;岔路用 \`## 岔路\`)。
收口:先有正文组成且体验已锚定;insert \`设计.开场白\`(Markdown;岔路用 \`## 岔路\`)。
**content 规格:** 正文必须含字面 \`@玩家\`(至少一处)作用户角色名位;禁止写死姓名;禁止全文只有「你」而零个 \`@玩家\`。缺则改写后再 insert。进游玩时程序替换 \`@玩家\`。
### D · 钉变量与映射
用户提到跨轮状态、分档态度、章大纲切换时:declare_variable(含是否对用户可见)→ declare_map(分档正文)。可同轮多次调用。
仅当「变量设计」何时用成立(体验须跨轮记住状态等):declare_variable → 有分档换文再 declare_map。勿因配方名叫数据化就抢跑 D。
### E · 文本生成器(创作收料 → 开玩挂载)
必须用 insert 写齐游玩上下文:\`设计.模仿范例\`、\`设计.模仿要点\`、\`设计.叙事指南与故事推进\`(用户输入用法:大纲扩写;禁止扮演停笔)。缺任一就先补产物,不要说可以开玩。禁止在创作期写完整短文。开玩后程序只挂载这些产物:主世界出内容,转述出文风。
+1 -1
View File
@@ -21,7 +21,7 @@ export const DICTATE_TOOL_DEFINITIONS: ToolDefinition[] = [
content: {
type: "string",
description:
"落入该位置的正文。设计.正文组成=格式 JSON;设计.开场白=可读开场(Markdown)",
"落入该位置的正文。设计.正文组成=格式 JSON;设计.开场白=可读开场 Markdown,必须含字面 @玩家(用户角色名位,禁止写死姓名)",
},
order: {
type: "number",
+3
View File
@@ -57,6 +57,8 @@ export async function runDictateTurn(params: {
systemPrompt?: string;
recipeName?: string;
recipeBrief?: string;
/** modules catalog 的何时落盘块(formatModuleCatalogForDictate) */
moduleGuide?: string;
driver?: AgentDriver;
}): Promise<DictateTurnResult> {
const driver = params.driver ?? createLocalLlmDriver(params.llm);
@@ -69,6 +71,7 @@ export async function runDictateTurn(params: {
buildDictateSystemPrompt({
recipeName: params.recipeName,
recipeBrief: params.recipeBrief,
moduleGuide: params.moduleGuide,
});
const assembled = buildDictateMessages({
systemPrompt,