核心论点:前七篇全在讲"怎么喂上下文给 AI"------Rules、@ 引用、搜索、Plan 模式。但如果 prompt 本身写得模糊,喂再多上下文也没用。这一篇回到源头:Prompt 本身怎么写。
一个被忽略的事实
整个系列的核心哲学是"AI 编码的瓶颈在项目认知输入"。但这有一个前提:prompt 本身的质量是合格的。
对比:
Prompt A(模糊):
给订单模块加个缓存
Prompt B(清晰):
@ .../redis_cache_service.py @ .../routers/order.py
在 order_query() 里加 Redis 缓存:
- 查询前先 await cache.get(order_key),命中直接返回
- 未命中查 DB 后 await cache.set(order_key, data, ttl=600)
- order_update() 里加 await cache.delete(order_key) 防脏缓存
Prompt B 比 A 多了两样东西:上下文(@ 了文件)和具体指令(查哪里、怎么查、ttl 多少、哪里需要清缓存)。同样的需求,prompt 写法不同,结果天差地别。
四类编码 prompt 的实战模式
三段式 prompt(最高频)
[上下文] @ 涉及的文件
[约束] 要遵守的规则
[动作] 要做什么 + 验收标准
示例:
@ .../llm_service.py @ .../config.py
- 不新建类,扩展现有方法
- 遵循 async/await 规范
给 chat() 加 temperature 参数,默认值从 config 读,透传到 openai 调用。
格式:上下文 + 约束 + 动作
为什么三段式比混乱叙述有效:AI 按顺序处理信息。先看上下文(这是项目),再看约束(这是边界),最后看动作(这是任务)。顺序对了,输出质量明显提升。
少样本示例(教 AI 你想要的输出格式)
当你要的是一类重复操作时,给一个例子比描述 10 句更有效:
@ tests/test_conversation_service.py
参考 test_summarize_normal 的写法,给 get_messages() 写测试:
# 参考例子
@pytest.mark.asyncio
async def test_summarize_normal(mock_llm_response):
"""正常生成摘要"""
service = ConversationService()
result = await service.summarize(conversation_id="conv_1")
assert result is not None
assert len(result) > 0
assert "摘要" in result
# 任务
给 get_messages() 写同样风格的测试,覆盖:
- 正常获取消息列表
- 空对话返回空列表
- 分页参数的正确性
少样本示例的价值:AI 不需要猜"你要的测试长什么样"------你给了一个例子,格式、命名、断言风格都明确了。
思维链(让 AI 展示推理过程)
涉及复杂决策时,要求 AI 先输出推理过程:
@ .../tool_registry.py @ .../mcp_server.py @ .../a2a_routers.py
重构工具调度逻辑。不要直接写代码------先分析:
1. 当前 tool_registry 的调度流程(dispatch 的调用链)
2. MCP Server 和 A2A 分别怎么调用 tool_registry
3. 现有设计的问题在哪里
4. 重构方案(3 个选项 + 推荐)
5. 确认后,按推荐方案实施
思维链解决什么问题:复杂任务中,直接要代码 → AI 可能在错误方向上狂奔。先要求推理 → AI 自己理顺了逻辑 → 再写代码,方向正确率大幅提升。
反面约束(告诉 AI "不要这样")
markdown
@ .../core/experiment_service.py
加 experiment 的关闭逻辑。
❌ 不要:
- 新建 ExperimentManager 类
- 直接调 Redis 做状态管理
- 在 router 里加 close 端点
✅ 要:
- 在 experiment_service.py 里加 close() 方法
- 状态用已有的 experiment_store(MySQL)
- 关闭后分流一律返回 control 组
反面约束比正面约束更有效------因为 AI 的"默认行为"往往是写一个新类、调一个新依赖。"不要"比"要"更精准地拦截了默认行为。
从差到好:三个常见 prompt 的进化
缓存功能
Bad "加个缓存"
→ AI 自己写 class Cache,内存 dict
Good "@ .../redis_cache_service.py 在 order_query() 里加缓存,
用已有的 redis_cache_service,TTL=600"
Better "@ .../redis_cache_service.py @ .../routers/order.py
在 order_query() 里加 Redis 缓存:
1. 查前 get(order_key),命中直接返回
2. 未命中查 DB 后 set(order_key, data, ttl=600)
3. order_update() 加 delete(order_key) 防脏缓存
❌ 不新建 cache 类"
进化路径:模糊描述 → 指定组件 → 指定步骤 + 边界处理 + 禁止项
重构
Bad "重构 tool_registry,太乱了"
→ AI 可能重写整个文件,改动远超预期
Good "重构 tool_registry.py 的 dispatch() 方法:
保持对外接口不变,只重构内部实现。
先输出当前 dispatch() 的问题分析,再出重构方案。"
Better "重构 tool_registry.py 的 dispatch() 方法。
约束:保持所有 public 方法签名不变。
步骤:
1. 先列出所有调用 dispatch() 的地方(搜索引用)
2. 分析 dispatch() 当前的问题
3. 出两个方案(轻量重构 vs 深度重构)
4. 确认后实施
❌ 不改 public 接口签名
❌ 不改 config 和 router"
进化路径:情绪化描述 → 加边界约束 → 加步骤 + 二选一方案 + 禁止项
Bug 修复
Bad "fix the bug"
→ AI 猜你要修什么 bug,改错地方
Good "format_time() 返回的时间比实际早 8 小时。
看 datetime_utils.py line 42,应该是 UTC 和 CST 的问题。"
Better "@ .../datetime_utils.py @ .../tests/test_datetime_utils.py
format_time() 返回 UTC+0 而非 UTC+8。用 pytz 修复。
修复后更新 test_format_time_utc8 的期望值。
同时检查项目里还有没有其他用 datetime.utcnow() 的地方。"
进化路径:无信息 → 定位问题 → 定位 + 解决方案 + 影响范围 + 测试
什么时候应该用 Ask 而不是直接写 prompt
这篇讲的是 prompt 技巧,但要记住第四篇的核心:方案不确定时,先用 Ask 讨论。
错误做法(在 Craft 里写长 prompt):
给订单模块加个缓存。可以用 Redis 也可以用内存。
如果并发不高就内存,高就 Redis。你看看哪个合适。
→ AI 需要自己做决策,结果不确定
正确做法(先用 Ask 讨论):
Ask: "订单模块要加缓存,项目里已经有 redis_cache_service。
直接用它会不会太重?有没有更轻量方案?"
AI: [分析]
你: "好,用 Redis。在 order_query() 里加。"
然后切 Craft:
"@ .../redis_cache_service.py @ .../routers/order.py
在 order_query() 里加 Redis 缓存... [三段式]"
原则:如果 prompt 里有"或者"、"你看看"、"你觉得哪个"------说明方案不确定,应该先 Ask。
团队级 prompt 规范:把好 prompt 编码成 Rules
个人 prompt 技巧 → 团队规范的方式:把高频的好 prompt 模式写进 Rules。
markdown
# .codebuddy/rules/prompt-template/RULE.mdc
## 新功能开发
使用 `/new-feature` skill 启动标准流程。
## Bug 修复
Bug 报告必须包含:
- 问题现象(预期 vs 实际)
- 出错文件 + 行号
- 复现步骤或测试用例
## 重构
重构请求必须包含:
- 约束:哪些接口不能变
- 范围:哪些文件在改动范围内
- 验证方式:用什么测试确认行为不变
把 prompt 规范写进 Rules 后,每个团队成员和 AI 交互时都能看到------相当于团队共享了 prompt 最佳实践。
核心要点
- "三段式"是最小的有效 prompt 结构:上下文(@ 文件) + 约束(规则/禁止项) + 动作(步骤 + 验收标准)。一旦习惯这个结构,AI 输出质量稳定提升。
- 少样本示例 > 描述------给一个例子比写十句说明更有效。特别是在测试、文档、重复性操作中。
- 复杂任务用思维链------先让 AI 分析、推理、出方案,确认后再写代码。不要一步到位要代码。
- "反面约束"比"正面约束"拦截力更强------"不要" > "要"。因为 AI 的默认行为是写通用代码,反面约束直接拦截了默认路径。
- 好的 prompt 是三层漏斗的"源动力"------Rules 建立项目认知底线(AI 自动知道有什么/不能做什么)、@ 引用提供精准上下文(每次对话喂什么)、Plan 模式控制流程(什么时候做什么)。但如果 prompt 本身是废的,三层漏斗也救不回来。