精准输入——@ 引用与搜索后生成的实战技巧

精准输入——@ 引用与搜索后生成的实战技巧

核心论点:Rules 解决了"AI 自动知道什么",但 Rules 有延迟、有遗漏。真正让 AI 不重造轮子的关键是每次对话前完成两件事——喂对文件、搜对代码。


Rules 的盲区

回顾上一篇,禁止清单和组件清单能拦截绝大部分"默认行为→不兼容"的路径。但有三类场景 Rules 覆盖不了:

场景 A:组件加了,清单还没更新
你昨天刚写的a2a_webhook_service.py,自动化脚本要下周一才跑。今天让 AI 加个 webhook 回调功能——AI 不知道有现成的,写了一套新的。

场景 B:规则描述不了"用哪个"
组件清单写着tool_registry.py → ToolService.dispatch()。但这次的需求是加一个新的工具注册方式——是扩展dispatch()还是调用ToolService.register()?规则精准度不够,AI 可能用错接口。

场景 C:跨层调用,规则难以穷举
需求涉及三个文件:routers.pyllm_service.pyconfig.py。规则里每个组件都有描述,但 AI 可能从 router 直接调 config,跳过中间层——因为规则没描述"调用链"。

这三类的共同解法:在每次对话开始时,精准喂入 AI 需要知道的文件。


@ 引用:四个有效模式

模式 1:入口 + 下游

最基础的模式。把改动入口文件和它调用的下游文件一起 @:本文以 Shop-Agent 项目为例,项目目录结构为src/modules/chat/(下同,省略前缀)。

@ routers/chat.py @ …/core/llm_service.py @ …/core/chat_agent.py 我要给对话接口加一个新参数 temperature,透传到 LLM 调用。

AI 读到这三个文件后,能看到完整调用链:router 接收参数 → 传给 chat_agent → chat_agent 调 llm_service。改两行代码就行,不会在中间层额外包装。

模式 2:相似功能参照

让 AI 参考已有实现来写新功能:

@ …/core/mcp_server.py @ …/core/mcp_client.py 参考 MCP Server 的实现模式,我要加一个 WebSocket 推送服务。 用一样的连接管理、重连、心跳机制。

AI 读到 MCP 的实现后,会自动复用它的连接管理、心跳、重连模式——不需要你在 prompt 里描述一遍架构。

模式 3:上层定义 + 下层实现

带约束的接口设计:

@ …/schemas.py @ …/models.py 基于已有的这些 Pydantic schema 和 SQLAlchemy model, 我要加一个"实验配置"模块。新增的表必须和现有 model 保持一致的命名和关系定义风格。

AI 先读 schema 和 model,然后写出的新模型会自动对齐字段命名、关系定义、索引设计——风格一致,不会出现created_atvscreate_time这种混搭。

模式 4:配置文件 + 消费方

改动影响多个消费方时,把配置和所有消费方一起 @:

@ …/core/config.py @ …/core/llm_service.py @ …/core/chat_agent.py config 里加了一个 LLM_TIMEOUT,帮我改造 llm_service 和 chat_agent 都读取这个配置。

AI 同时看到配置定义和两个消费方,会一次性改完三个文件——不会漏掉某个消费方还在用硬编码超时。


搜索后生成:编码前必须做的事

@ 引用解决"精准喂入",但前提是你知道要喂什么。如果 AI 要改的功能涉及一个你不熟悉的模块,你不知道关联文件有哪些——这时候需要搜索后生成

实际操作流程

假设要加一个"对话摘要"功能,不知道从哪里下手:

第一步:搜索"summary"或"摘要" → 没搜到。说明这是新功能,没有现成实现。 第二步:搜索对话写入的入口 → 搜 "conversation" → 找到 conversation_service.py → save_message() → 这是对话数据写入的唯一入口 第三步:搜索对话读取的入口 → 搜 "get_conversation" → 找到同样的 service → get_messages() → 对话数据读取也在这里 第四步:搜索 LLM 调用方式 → 搜 "llm_service" → 找到所有调用点,看清 chat() 的签名 第五步:确定方案 → 在 conversation_service.py 里加 summarize() 方法 → 调用 llm_service.chat() 生成摘要 → 在 save_message() 后触发摘要更新

整个过程 2 分钟,AI 做完前就知道:

  • 不是什么新模块,扩展现有conversation_service
  • 用已有的llm_service.chat(),不用新建 LLM 客户端
  • 在已有的save_message()里加钩子,不用改 router

如果跳过搜索直接让 AI 写,大概率输出一个独立的summary_service.py+ 一个新 router 端点 + 一套新的 LLM 调用封装。


三层协作的实战案例

回到开头的缓存场景,完整展示三层如何配合:

Round 1:不做任何准备(对照组)

用户:给订单查询加缓存 AI: 写了一个 class OrderCache,内存 dict → 返工:项目已有 redis_cache_service

Round 2:只靠禁止清单

用户:给订单查询加缓存 AI:(读到禁止清单"禁止新建 cache 类") → 搜索 redis_cache_service,找到 get/set/delete → 在 order_query() 里加了缓存调用 → 基本正确,但没用 TTL 参数(Redis 里没设置过期时间) → 小返工:加 TTL

Round 3:禁止清单 + @ 引用

用户:给订单查询加缓存 @ …/core/redis_cache_service.py @ routers/order.py AI:(读到禁止清单 + cache_service 源码 + order router) → 看到 cache_service.set() 有 ttl 参数 → 看到 order_query() 的返回数据结构 → 正确用 TTL,正确处理序列化 → 一次通过

Round 4:禁止清单 + @ 引用 + Plan 模式

用户:给订单查询加缓存 @ …/core/redis_cache_service.py @ routers/order.py (用 Plan 模式) AI:先出计划: 1. order_query() 查询前先 `await cache.get(order_key)` 2. 命中直接返回,未命中查 DB 后 `await cache.set(order_key, data, ttl=600)` 3. order_update() 里加 `await cache.delete(order_key)`(防脏缓存) → 你确认计划 → 实施 → 一次通过,且处理了缓存失效

四轮递增的核心不是模型变强了,是每次增加一层认知输入,AI 对项目的理解深了一层


实操检查清单

每次开始一个编码任务前,花 30 秒过一遍:

□ 我要改哪个文件?——这是入口 □ 这个文件调用了哪些其他模块?——这是下游(@ 它们) □ 项目里有没有类似功能的实现?——搜索一下 □ 这个改动影响哪些配置?——@ config.py □ 有没有相关的 model/schema 要同步改?——@ models.py / schemas.py

这套流程养成习惯后,AI 写出不兼容代码的概率会急剧下降——因为每次对话前,你相当于手动做了一遍"项目认知注入"。


核心要点

  1. Rules 是自动挡,@ 引用是手动挡——两者结合才能覆盖所有场景。Rules 覆盖常态,@ 引用处理特例。
  2. @ 引用的核心不是"多",是"对"——不是把所有文件都拖进去,而是拖入口 + 下游 + 约束文件。
  3. 搜索后生成是安全网——你不知道关联文件有哪些时,让 AI 先搜再写,而不是先写再修。
  4. 三层投入递增,效果递增:禁止清单(10 分钟)→ 组件清单(1 小时+脚本)→ @ 引用习惯(养成)→ 搜索后生成习惯(养成)。从立即可做的开始。