package reverse_think import ( "errors" "strings" ) // Prompt carries the variables the Chinese reverse-thinking template // renders. Field names align with the markdown SKILL.md template at // ~/.claude/skills/reverse-think/SKILL.md. // // Prompt 携带渲染中文反向思维模板需要的变量. 字段名对齐 // ~/.claude/skills/reverse-think/SKILL.md 模板. type Prompt struct { // Scenario describes the concrete context: language, files, fields, // current state. Required. // // Scenario 描述具体场景: 语言 / 文件 / 字段 / 当前状态. 必填. Scenario string // OptionA is the recommendation in one line. // // OptionA 是倾向选项 (一句话). OptionA string // OptionB is the alternative in one line. // // OptionB 是替代选项 (一句话). OptionB string // Recommendation is "A" or "B" -- which option the producer leans // toward before the reverse pass. // // Recommendation 是 "A" 或 "B" -- 反向思维前生产方倾向哪个. Recommendation string // RecommendationReason is two to three reasons backing Recommendation. // // RecommendationReason 是支持 Recommendation 的 2-3 个理由. RecommendationReason string } // ErrPromptIncomplete is returned by Render when any required field of // Prompt is empty. Required = Scenario, OptionA, OptionB, Recommendation, // RecommendationReason. The reverse pass cannot meaningfully challenge // a recommendation that was never spelled out. // // ErrPromptIncomplete 在 Prompt 任一必填字段为空时由 Render 返回. 必填 = // Scenario / OptionA / OptionB / Recommendation / RecommendationReason. // 反向思维无法挑战一个没说清楚的方案. var ErrPromptIncomplete = errors.New("reverse_think: prompt missing required field") // Render produces the Chinese prompt string sent to the LLM. Output // matches the SKILL.md template byte-for-byte under identical inputs so // regression in prompt drift is catchable by golden test (see template_test). // // Render 产出发给 LLM 的中文 prompt 字符串. 输入相同时输出与 SKILL.md // 模板字节对齐, prompt 漂移可由 golden test 锁住 (见 template_test). func Render(p Prompt) (string, error) { if strings.TrimSpace(p.Scenario) == "" || strings.TrimSpace(p.OptionA) == "" || strings.TrimSpace(p.OptionB) == "" || strings.TrimSpace(p.Recommendation) == "" || strings.TrimSpace(p.RecommendationReason) == "" { return "", ErrPromptIncomplete } var b strings.Builder b.WriteString("你做反向思维分析, 直接给最终 JSON, 不要前后文.\n\n") b.WriteString("场景: ") b.WriteString(p.Scenario) b.WriteString("\n\n") b.WriteString("选项 A: ") b.WriteString(p.OptionA) b.WriteString("\n") b.WriteString("选项 B: ") b.WriteString(p.OptionB) b.WriteString("\n") b.WriteString("我的建议: ") b.WriteString(p.Recommendation) b.WriteString(" -- 理由 = ") b.WriteString(p.RecommendationReason) b.WriteString("\n\n") b.WriteString("你的任务: 反向思考 -- 如果我的建议是错的, 可能错在哪里?\n") b.WriteString("注意: 你的输出会进入主进程上下文, 长度有意义但请不要为了凑数列假问题.\n") b.WriteString("直接输出 JSON, 不要任何额外文字:\n") b.WriteString("{\n") b.WriteString(` "hidden_assumptions": ["..."],` + "\n") b.WriteString(` "failure_scenarios": ["..."],` + "\n") b.WriteString(` "verdict": "A_holds | B_wins | depends_on_X",` + "\n") b.WriteString(` "verdict_reason": "一两句话总结"` + "\n") b.WriteString("}\n") return b.String(), nil }