人工智能改代码前,先把项目入口写对
早期的工程记录里,有一份看起来已经够用的工作区入口。它列出了项目导航,告诉人工智能去哪里查接口、收到需求后使用什么流程,修改代码前还要确认方案。
问题是,里面保留着另一套项目的名称、入口和流程引用。后来的需求讨论流程已经有多轮澄清和人工确认,同一份说明里的默认文档目录却仍然前后不一致。
这些记录不能证明人工智能因此改错过哪个文件,但足以指出一个容易被忽略的问题:上下文里有现成答案,答案却未必属于当前项目。后面的调查和计划越依赖这份入口,错误导航就越有机会被继续沿用。
上一篇讲了谁来确认需求与方案。到这里,还要检查确认时使用的项目事实:人工智能说“应该改这个工程”,它是查到了依据,还是只是认出了一个眼熟的目录名?
工程拆开以后,定位信息还要有人管
原先,工作区通过版本指针关联多个项目仓库,父层的状态会受到项目仓当前提交的影响。为了拆开这层关系,设计改为让各工程独立管理自己的仓库,工作区只保存协作资料与工具。同时,设计也明确排除了集中项目清单,操作哪个工程、使用什么分支,都由调用方传入。
这个取舍有清楚的边界:工作区不用再接管各工程的版本与检出过程。只要调用方每次都能提供完整、准确的目标信息,工作流就可以继续。
后续变更记录明确指出了缺口:有哪些工程、位于哪里、使用什么基线分支,没有统一的查询位置。工具只能依赖任务显式传参,或者把工程映射写死在自己的说明和脚本里。随后增加了集中项目清单,若干流程也开始从清单读取这些信息。
仓库之间解除关联,并没有让跨仓查找的需要消失。几种工具如果各自记着一份“工程对应哪个目录、应该使用什么分支”,改动一次工程约定,就需要找到并同步每一份。漏掉的那份还会继续提供旧答案。
这也是清单的用途:给共享的定位信息一个固定位置。它可以描述项目在哪里,而不替项目管理提交、分支切换或检出。清单里有记录,也不意味着这个工程已经在当前机器上存在。
不过,清单引入时,部分脚本仍保留了扫描目录和使用默认值的后备逻辑。定位信息虽然有了固定位置,缺少信息时继续猜的路径却还在。写最小安全规则时,还得回头检查这些执行路径。
五类信息,各自只维护一份
最小项目上下文可以分成五类。每一类只负责一个问题,其他地方需要时引用它。
| 类型 | 回答的问题 |
|---|---|
| 工作区入口 | 开始任务先读哪里? |
| 项目清单 | 目标工程是谁、在哪里? |
| 代码地图 | 进入工程后,先查哪些文件? |
| 最小安全规则 | 哪些动作允许做,什么情况必须停止? |
| 信息来源优先级表 | 这个问题应该依据什么判断? |
下面所有工程、路径和模板均为教学虚构,与前面的工程记录无关。文件名是本文的约定,不依赖某个工具自动读取。使用时,把工作区入口接到现有工具的项目说明中,或者在会话开始时明确要求它先读这份入口。模板中的占位内容需要按实际项目填写。
工作区入口只安排阅读顺序
入口很容易被写成一本不断加页的手册:工程位置、测试命令、接口约定、安全规则,全塞进来。后来其他文档也需要同样的内容,副本就出现了。
可以先把入口收窄成下面这样。
context.md:
# 工作区入口
范围:本工作区组织多个独立工程的协作。
本文档中的路径均相对工作区根目录。
1. 先读 safety.md,确定本次调查与修改的边界。
2. 按任务到 projects.md 确认目标工程;目标不明时先澄清。
3. 核对目标仓库的实际身份、当前分支与已有改动。
4. 读取清单登记的项目说明;有代码地图时先查相关位置,再读取实际文件。
5. 按 sources.md 核对依据,列出已知事实、冲突与未决事项。
本入口不保存工程枚举、编码规范或安全规则副本。
项目专属约束沿项目说明和代码地图中的引用继续读取。阅读顺序固定下来,任务才有稳定的起点。入口不用提前知道每个功能的实现,只需要把人工智能送到能够查证的位置。
项目清单保存约定,现场状态另查
下面是供人阅读的最小清单。工具需要结构化输入时,可以用结构化格式承载同样的信息;人工维护的正文仍只保留一份。
projects.md:
# 项目清单
本文件与路径均以工作区根目录为基准。
维护责任:工作区维护者;工程身份或位置变化时更新本表。
| 标识 | 职责 | 本地路径 | 仓库身份 | 集成基线 | 项目说明 | 代码地图 |
|---|---|---|---|---|---|---|
| backend | 设置接口与持久化 | backend/ | <填写后端仓库规范标识> | main | backend/README.md | backend/code-map.md |
| web | 设置页面与请求适配 | web/ | <填写网页端仓库规范标识> | main | web/README.md | web/code-map.md |
仓库身份应能与本地 Git 远端核对,不包含凭据。
main 仅为示例,必须替换为团队确认的真实基线。
集成基线不等于本次工作分支;本次工作分支按已确认任务确定。
代码地图填“未设置”表示暂无地图,改从本表登记的项目说明定位。
登记了地图路径则必须有效;异常处理见 safety.md。
清单不记录当前提交、当前分支或本机是否已检出。现场状态会随着每个人的工作变化,写进共享清单只会很快过期。需要修改时,重新检查目标是否真是预期仓库、当前分支是否符合任务、有没有已有改动。当前在工作分支,并不自动表示偏离流程;把集成基线误当成唯一允许工作的分支,也会制造错误限制。
代码地图把人带到文件,不替文件回答问题
地图应当帮助读者缩小查找范围。例如,一个“设置”功能可能分别涉及请求契约、服务端处理、网页请求适配和测试。把这些入口连起来,比罗列整个目录树更有用。
后端的 backend/code-map.md:
# 后端代码地图
本文件中的路径相对本项目根目录。
维护责任:后端维护者;入口迁移时同步本表。
工程约束:docs/engineering.md。
| 查什么 | 先读哪里 |
|---|---|
| 设置接口契约 | contracts/settings.yaml |
| 读取、保存与校验 | src/settings/handler.ts |
| 持久化处理 | src/settings/store.ts |
| 设置行为测试 | tests/settings.test.ts |
实际字段、行为与限制以读取到的文件为依据,不在此复制。
表中没有任务条目时,可在已确认项目内继续查找。
已登记路径失效或发现事实冲突时,按 ../safety.md 处理。网页端的 web/code-map.md:
# 网页端代码地图
本文件中的路径相对本项目根目录。
维护责任:网页端维护者;入口迁移时同步本表。
工程约束:docs/engineering.md。
| 查什么 | 先读哪里 |
|---|---|
| 设置页面 | src/settings/page.tsx |
| 请求与响应适配 | src/settings/api.ts |
| 请求适配测试 | tests/settings-api.test.ts |
| 接口契约 | 按 ../projects.md 定位 backend,再读其地图的契约入口 |
本项目不维护接口契约副本。
表中没有任务条目时,可在已确认项目内继续查找。
引用异常与事实冲突按 ../safety.md 处理。两份地图都只给线索。测试文件存在,不能证明当前检查通过;表格写着“保存与校验”,也不能证明某项输入确实被校验过。这些结论仍然要通过读取和验证得到。
地图可以从常改的一小块开始。没有设置地图的小项目,从明确的项目说明进入并做有限搜索即可。已经登记的地图或文件找不到,则是失效引用,应当报出来。不要为了绕过坏链接,再去旁边找一个名字相似的工程。
最小安全规则写出失败时的动作
“小心修改”“不要乱猜”很难检查。有效规则应当指出触发条件、停止范围和下一步。
safety.md:
# 最小安全规则
适用范围:本工作区全部任务。
- 只在任务授权的工程和范围内调查或修改;已确认工程内可以搜索代码。
- 不扫描陌生目录猜目标仓库,不从目录名推断分支。
- 目标身份不明、登记路径失效、仓库身份不符,停止对应工程操作。
报告预期目标和实际发现;不自动克隆、创建替代工程或改写清单。
- 修改前核对当前分支和已有改动。任务约定冲突,或已有改动归属不明,
停止相关修改;不自行重置、清理、切换分支或覆盖他人工作。
- 必须的引用失效、关键依据冲突或事实缺口会改变方案时,停止受影响实现。
按 sources.md 整理依据与缺口,可继续授权范围内的只读核验。
- 人工智能提出的业务方案与取舍,需要人确认后才能进入实现。
- 超出已有授权的破坏性操作、外部写入和发布,先明确目标与影响,再请人授权。
- 完成后说明检查结果与未验证部分;不把计划中的检查写成已经通过。这里没有技术栈规范,也没有整套研发流程。项目自己的编码约束放在项目说明引用的位置,遇到任务再读取。最小规则先管住所有任务都会遇到的边界。
信息优先级要按问题来排
直接写“代码高于文档”并不够。代码能证明现在实现了什么,但本次任务可能恰恰要修改这个行为。反过来,已经确认的方案也不能证明代码已经按方案实现。
sources.md:
# 信息来源优先级
本文件只规定核验方式;具体项目位置查 projects.md,文件位置查项目地图。
| 问题 | 首查依据 | 交叉核验 |
|---|---|---|
| 本次要改什么、哪些取舍已确定 | 人确认的任务与决定 | 区分已确认范围、建议和未决问题 |
| 目标工程是谁、约定在哪里 | projects.md 对应记录 | 核对本地仓库根与远端身份 |
| 当前实现怎样工作 | 任务相关代码与配置 | 检查相关测试及本次实际验证结果 |
| 两端应遵守什么接口约定 | 指定的接口契约 | 对照提供端、调用端与相关验证 |
| 应遵守哪些工程约束 | safety.md 与项目专属说明 | 核对适用范围,发现矛盾交维护者处理 |
地图、旧文档、历史对话可提供查找线索;不能单独证明当前状态。
新决定改变旧行为时,应明确变更范围,而不是把两者混成同一个事实。
资料冲突时保留两侧依据,标明影响,按 safety.md 停止相关实现。
不要自行选择较新、较长或看起来更合理的一份继续。这个表没有要求人工智能读完整个项目。它要求每个影响实现的关键结论有出处,查到矛盾时不要用一句“应该是这样”把它盖过去。
用一个虚构任务走完整条查找路径
继续使用上面的虚构工程。假设一个设置页面要支持显示和修改时区,人已确认输入采用时区标识,允许范围和保存失败时的页面行为也已写明。
人工智能先从入口读到清单,确定任务涉及后端与网页端。它核对两个本地目录确实是对应仓库,查看当前分支和已有改动,再分别沿地图定位文件。
网页端需要读页面和请求适配,后端需要读契约、处理与存储逻辑。因为网页地图把契约指回后端的唯一位置,两端不需要各自保存一份“看起来差不多”的字段说明。相关测试提供已有行为的线索,是否符合本次要求还要另外核对。
如果这些依据能够对上,调查结果就可以列出本次受影响的位置,以及后续需要验证的行为。找到文件不等于获准开始实现,仍应接着完成任务需要的设计确认。
现在给这个示例增加一个冲突:契约写的是时区标识,请求适配却只接受数字偏移。人工智能不能因为网页端现有代码更容易复用,就把需求解释成“其实只要偏移量”。它可以留下这样的调查记录:
范围:设置页面的时区读取与保存。
任务决定:使用时区标识;其余行为按已确认任务记录。
契约依据:backend/contracts/settings.yaml,请求约定为时区标识。
冲突依据:web/src/settings/api.ts,仅接受数字偏移,与契约不一致。
影响:请求表示方式尚未对齐,不能直接继续跨端实现。
继续调查:读取调用方及相关测试,检查现有依赖。
需要确认:兼容范围;确认后再确定两端修改方案。在这个虚构情形里,两侧依据都留了下来,维护者能够沿具体路径复查;人工智能也有明确的后续调查范围,不用靠补全一个“合理答案”来结束任务。
如果连后端目录都不存在,就更早停止后端操作。清单中的记录不能代替本机检出,也不能授权人工智能创建一个新后端来填空。
停止猜测,也要说清停在哪里
要求停止,很容易又变成“缺一个信息,整件事全部交还给人”。这也不合适。
某个接口的兼容范围尚未确认,不妨碍人工智能继续读取相关调用方、整理现有测试和列出备选方案。只是这些调查不能悄悄变成实现,更不能替人确认兼容取舍。
能从已知工程查到的事实,先查。只有信息缺失会改变需求、设计或执行边界,而且现有依据无法回答时,才需要人补充。报告中写清影响范围,维护者才能判断该补哪一项。
还要检查工具本身。文档要求“没有目标就停”,脚本却在缺字段时补一个默认分支继续跑,这条规则就没有真正约束到执行。只核对入口里有没有写禁令,会漏掉这种情况。
可以在不执行真实写操作的检查中,向工具提供一个不存在的工程标识,观察它是报告缺口,还是换个目录继续寻找。对会修改文件或外部状态的工具,先在隔离的验证环境检查失败路径。不要拿正在工作的仓库试探一个未知脚本是否会停。
个人单仓可以少建文件,事实来源仍要保留
五类职责不要求每个人都维护五个文件。
个人只有一个仓库时,可以把本仓身份、事实位置和最小约束放在同一份入口里,省去独立清单。地图也可以只是几行导航。一个可裁剪的起点是:
本仓身份:<可核对的仓库标识>;工作范围:<任务允许的目录>。
项目说明:<现有说明路径>;关键实现:<路径或符号>;验证位置:<路径>。
任务目标与取舍以人的确认为准;当前行为查代码、配置与实际验证。
修改前检查分支与已有改动,不覆盖归属不明的工作。
目标不明、引用失效或关键依据冲突,停下相关实现并报告。小团队开始共享入口后,应当指定维护责任。工程位置或身份变了,更新清单;实现入口搬了,更新地图;接口字段改了,更新契约。相互引用的好处在这里:同一个字段不需要在入口、地图和流程说明里各改一次。
更多工具开始消费这些资料时,再增加字段检查、失效引用检查和结构化清单。它们解决已经出现的维护问题,无须为了采用人工智能先建立完整平台。如果以后工作区缩成单仓,也可以把身份记录收进入口,移除不再使用的清单及引用。
任何清单和地图都会过期。它们的维护应当跟随对应结构的变化,不能靠某个人偶尔想起“该更新文档了”。也不必追求收录每个文件:人工智能能沿入口找到任务相关依据,发现缺口时能够准确报告,就已经有了可以检查的起点。
写完入口后,开一个新会话,请人工智能先不改代码,只回答三件事:这次应该进入哪个工程,关键判断依据在哪里,还有什么尚未核实。再在示例副本中放入一个失效引用,看它能否指出具体缺口。
如果它只复述了目录,却说不出依据;或者引用已经失效,仍然给出一份完整修改计划,这份入口就还需要继续改。