ai自学笔记 (2.prompt 踩坑与优化)

用 Claude API 做结构化 JSON 输出(10 个 hook) 记录问题原因、修复,和复用的 prompt 模板。


踩坑记录

坑 1:模型不输出纯 JSON,而是包裹中文前言

现象 :即使设置了 output_config.format (json_schema),Claude 仍然返回:

复制代码
好的,姐妹!以下是为您生成的 10 个 hook...
{"hooks": [...]}

原因

  • Claude 4.7 在中文场景下倾向于"礼貌回复",即使有结构化输出约束也会附上前言
  • output_config.format 是约束而非强制------不能 100% 依赖它
  • 中文 system prompt + 中文 user message 时,模型更容易"聊天化"

修复(双层防护)

第一层------Prompt 加强,在 system prompt 末尾加:

复制代码
## 输出格式(极其重要)

你必须只输出一个合法的 JSON 对象,不要加任何前缀说明、后缀总结、markdown 代码块标记。
正确示例:{"hooks":[{"text":"...","style":"悬念式","score":8,"reason":"..."}]}
错误示例:好的,以下是为您生成的...\`\`\`json...\`\`\`
不要输出 "以下是"、"好的"、"为您生成" 这类废话,直接输出 JSON。
  • 用"正确示例"和"错误示例"对比,比单纯说"不要"有效得多
  • 明确列出常见废话("以下是"、"好的"、"为您生成")
  • 放在 prompt 末尾(模型的 recency bias 会让它更重视末尾指令)

第二层------代码容错,在 JSON.parse 前加提取逻辑:

typescript 复制代码
let rawText = textBlock.text.trim();

// 1. 如果被包裹在 markdown 代码块中,提取出来
const codeBlockMatch = rawText.match(/\`\`\`(?:json)?\s*([\s\S]*?)\`\`\`/);
if (codeBlockMatch) {
  rawText = codeBlockMatch[1].trim();
}

// 2. 尝试找到 JSON 对象的起始位置
const jsonStart = rawText.indexOf('{"hooks"');
if (jsonStart > 0) {
  rawText = rawText.slice(jsonStart);
}

// 3. 解析
const data = JSON.parse(rawText);

三层防护(markdown 代码块 → 文本中挖 JSON → 报错)保证健壮。

坑 2:prompt 过长导致模型"浏览"而非"精读"

现象:10 种风格 + 5 个平台规则 + 评分标准,prompt 接近 2000 字,模型可能跳读某些约束。

建议

  • 关键约束放末尾(recency bias)
  • 用明确的分隔线和层级标题帮助模型定位
  • 不要用"请"、"如果可以的话"这类弱化词------用"必须"、"只能"

坑 3:结构化输出 ≠ 100% 保证

经验output_config.format (json_schema) 是概率性约束,不是硬保证。永远要:

  1. Prompt 层面强调格式
  2. 代码层面做 JSON 提取容错
  3. 两个路由(generate + regenerate)都要加同样的容错

可复用的 Prompt 模板

结构化 JSON 输出的通用 System Prompt 模板

复制代码
你是一个[角色描述]。

## 你的任务
[任务描述]

## 规则
[业务规则 1-N]

## 输出格式(最重要)

你必须只输出一个合法的 JSON 对象。
- 不要加任何前缀说明或后缀总结
- 不要用 markdown 代码块包裹
- 不要输出"好的"、"以下是"、"为您生成"等人机对话用语

正确格式示例:
{"key": "value"}

错误格式示例(禁止):
好的,以下是结果... {"key": "value"}
```json
{"key": "value"}


### 关键原则

1. **末尾强调**:格式约束放 prompt 最后一段
2. **正反示例**:同时给出正确和错误的输出示例
3. **明确禁止词**:列出"以下是"、"好的"、"为您生成"、"当然"等常见废话
4. **简短有力**:用"必须"、"禁止"、"只能",不要用"请"、"如果可以的话"
5. **代码兜底**:永远在 `JSON.parse` 前加提取/容错逻辑

---

## 生成类 Prompt 的通用 Checklist

- [ ] 角色定位是否清晰?(一句话,不要多)
- [ ] 输出数量是否明确?("恰好 10 个",不是"10 个左右")
- [ ] 格式约束是否在末尾且醒目?
- [ ] 是否有正反示例对比?
- [ ] 评分/评价标准是否量化?("好奇心缺口 30% + 情感冲击 30%",不是"综合判断")
- [ ] 是否避免了弱化词("请"、"尽量"、"如果可以")?
- [ ] 代码端是否做了 JSON 解析容错?

---

## 编码侧的通用 JSON 提取函数

```typescript
function extractJson<T>(text: string): T {
  let raw = text.trim();

  // 去掉 markdown 代码块
  const codeMatch = raw.match(/```(?:json)?\s*([\s\S]*?)```/);
  if (codeMatch) raw = codeMatch[1].trim();

  // 找到 JSON 起始
  const start = raw.indexOf("{");
  const end = raw.lastIndexOf("}");
  if (start > -1 && end > start) {
    raw = raw.slice(start, end + 1);
  }

  return JSON.parse(raw) as T;
}

这个函数可以复用到任何需要从 AI 响应中提取 JSON 的项目。

相关推荐
谙弆悕博士5 小时前
系统集成项目管理工程师教程(第3版)笔记——第4章:信息系统架构
笔记·系统架构·项目管理·创业创新·学习方法·业界资讯·物理
CIO_Alliance5 小时前
企业AI化转型如何用AI+iPaaS实现降本增效?
人工智能·低代码·机器学习·ai·ipaas·系统集成·企业级ai化转型
小阿鑫6 小时前
一个 AI 应用开发程序员的一天,都在屏幕前忙些什么?
ai·程序员·agent·rd270q·明基rd270q
茯苓gao6 小时前
嵌入式开发笔记:Qt信号槽机制深度解析——从原理到实战的全方位指南
开发语言·笔记·嵌入式硬件·qt·学习
猿的天空7 小时前
机器人双手迎来全栈训练系统:灵初智能EgoSteer让灵巧手无所不能
网络·人工智能·计算机·ai·程序员·机器人·编程
A.零点8 小时前
【期末复习,408 考研计组全程笔记 】— 第4章 :指令系统
笔记·考研·408·计算机组成原理
imbackneverdie8 小时前
知网官宣:禁止 AI 列为论文署名作者,标注 Gemini、DeepSeek 等 AI 为作者的稿件统一下架
大数据·人工智能·ai·职场和发展·aigc·科研·高校
早茶cc8 小时前
sqli1-5 9报错注入 笔记
笔记
摇滚侠8 小时前
Java 全栈开发实战教程 课程笔记 34-36
java·笔记
洵有兮8 小时前
sql注入通关笔记
数据库·笔记·sql·sql注入