
核心论点前面的文章全在讲怎么喂上下文给 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, ttl600) - 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_idconv_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 “不要这样” …/core/experiment_service.py 加 experiment 的关闭逻辑。 ❌ 不要 - 新建 ExperimentManager 类 - 直接调 Redis 做状态管理 - 在 router 里加 close 端点 ✅ 要 - 在 experiment_service.py 里加 close() 方法 - 状态用已有的 experiment_storeMySQL - 关闭后分流一律返回 control 组反面约束比正面约束更有效——因为 AI 的默认行为往往是写一个新类、调一个新依赖。不要比要更精准地拦截了默认行为。从差到好三个常见 prompt 的进化缓存功能Bad 加个缓存 → AI 自己写 class Cache内存 dict Good …/redis_cache_service.py 在 order_query() 里加缓存 用已有的 redis_cache_serviceTTL600 Better …/redis_cache_service.py …/routers/order.py 在 order_query() 里加 Redis 缓存 1. 查前 get(order_key)命中直接返回 2. 未命中查 DB 后 set(order_key, data, ttl600) 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() 返回 UTC0 而非 UTC8。用 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。# .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 本身是废的三层漏斗也救不回来。