你有没有这种感觉——同一个AI编程助手,在别人手里像干了十年的老兵,到了你手里,连你上礼拜刚拆分的模块都记不住。每次它都很客气地说“你好,有什么可以帮你”,然后你只能再花十分钟去解释:我们的项目分层是这样的,我们用 Java 17 加 Spring Boot,错误处理必须走错误码……第一天你还有耐心,第十天你已经开始怀疑人生了。这大概是每个重度使用AI编程助手的人都会撞上的墙:模型能力很强,但记忆窗口很短。它不是智商不够,是你从来就没给它准备过一本“操作手册”。我最近折腾的一套小方案,就是为了解决这个事。思路不玄乎:把项目的各种约定、经验、偏好写进几个叫 steering files 的文件里,再配一组叫 kiro hooks 的自动钩子,在合适的时机把对应的内容精准地喂给AI助手。做到后面,你会发现它不是越用越懂你,而是你越来越会教它——结果就是它写出来的东西越来越像你们团队自己人写的。这个方案不依赖任何特定的IDE或者云平台,纯本地文件加几个脚本,人人都能照着搭。下面我把文件格式、钩子触发、迭代方法、踩过的坑全部交代清楚。1. 先别急着写代码,先确认痛点在哪儿1.1 我实际遇到的三种“AI失忆”现场我实际见过比较典型的三种失忆现场。第一种是架构失忆。项目做到中期,模块拆分、依赖方向都已经有明确约束。你让AI助手在某个模块里加一个功能,它可能会顺着当前文件乱引用,甚至跨层调用,因为没有文件告诉它“你只能依赖service层的接口”。它对项目架构的了解,完全建立在当前打开的十几个文件上,只要其中一个文件里有个旧写法,它就会照着旧写法扩散。第二种是约定失忆。你们团队的错误处理方式、命名规范、commit信息格式,都在代码评审里反复强调过,但AI助手每次都是第一次听说。我见过有人为了统一风格,往每个新文件开头都贴一段注释,最后代码里全是噪音,维护成本直线上升。第三种是踩坑失忆。某个接口的用法定死了,换一种写法在特定版本下有bug;某个配置项不能改,改了线上会出问题。这些经验你不可能每次都写进prompt里,但不写,它就还会踩同样的坑。这三种情况往深了说,本质是一件事:AI助手的每次对话都是冷启动,它对你的项目没有长时记忆。市面上的AI编程产品普遍提供了类似自定义指令、规则文件之类的功能,但在一个复杂项目里,固定文本根本不够用,而且更新成本很高。所以我开始想,能不能把它做成一套项目内可积累、可自动化加载的记忆系统。1.2 换个思路:把上下文工程变成项目基建关键转变在于:不要指望AI记住你,而是把“你希望它知道的东西”沉淀成文件,再设计一套自动注入机制。这其实是把软件开发里的一个老思路搬到了AI交互领域——把易变的知识从代码里拿出来,放到配置文件里,让程序在运行时加载。这里的“程序”就是AI助手工作流,“配置文件”就是steering files。这个思路有个额外的好处:文件和Git天然亲和。谁改了什么、哪条经验是哪次事故沉淀下来的,都有历史记录,可以回滚、可以评审。它不像对话历史那样是个黑盒,而是一等公民,可以review,可以测试,可以随着项目一起演进。于是就有了这套方案的架构雏形。2. kiro hooks 和 steering files:两个关键概念拆解2.1 steering files:给AI看的“项目操作手册”我习惯把steering files比喻成新员工入职手册。它不负责教AI怎么编程(那是它本来就懂的),而是告诉它:这个项目的世界长什么样,我们怎么做事,遇到过什么坑。在实际项目里,我推荐按下面的结构存放这三份文件:.kiro/steering/base.md:个人或团队通用的编码偏好。比如注释语言、命名风格、commit粒度、禁止使用的反模式。这部分可以跨项目复用。.kiro/steering/project.md:当前项目的架构地图。比如目录职责、模块边界、技术栈版本、核心数据流、部署环境等。是给AI的第一份地图。.kiro/steering/history.md:经验日志。按时间追加,每条记录包含“场景-现象-原因-结论”。遇到类似问题,AI可以在这里搜到旧方案。这个文件系统可以直接拿一个pull request来维护。每次有新知识,就提交一次变更;每次发现文件里有过期内容,就开issue修掉。我给文件里每条规则定了一个标准格式,方便AI解析也方便人写:字段说明例子范围这条规则作用于哪个模块/场景支付模块规则期望的行为或约束严禁直接操作数据库表,必须走仓储接口理由为什么要有这条规则表结构可能重构,避免散落的SQL反例它阻止了什么错误做法不推荐写原生SQL加上“理由”这一栏是我觉得很重要的点。AI很擅长模式匹配,但如果你只告诉它“不能这样”,它容易在别的场景继续犯类似的错误;如果告诉它为什么,它就能迁移到相似问题上,这个在实践里效果非常明显。2.2 hooks:在正确的时间递上手册文件放在那儿,AI不会主动去看。你需要一个机制,在“该知道的时候”把“该知道的内容”送进模型上下文。这就是hooks的职责。我实现了一套很轻量的钩子机制,核心触发点有这些:session_start:新建对话时,注入base.md和project.md。file_open:打开某个源文件时,注入该模块的职责说明和历史风险。触发频率高,所以内容要精简。pre_generate:准备生成代码前,注入目标文件涉及的相关接口、风格约束。post_edit:每次AI改完文件,自动追加一条变更摘要到history.md里。这一步是整个方案能越用越聪明的关键。task_done:一次任务完成后,提取本次对话里产生的关键决策,人工确认后写入steering files。你没看错,这个方案不是单向地喂给AI知识,更关键的是让AI在使用过程中不断把新经验写回文件。这就形成一个循环:读文件→应用到任务→记录新经验→下次读文件时包含这些经验。循环跑起来,它就一直在长。2.3 两者结合后的整体工作流我来描述一下这套闭环的实际运行方式:你启动一个AI辅助任务,shell wrapper先检查有没有.kiro目录,有就按顺序读入steering files的核心区块,拼进系统提示词;任务进行中,每当AI写入文件,watcher会捕获变更事件,自动生成一条结构化的提交记录;等到任务结束,你再花半分钟review一下history里的新增条目,把有价值的经验提炼进project.md或base.md。换句话说,hooks是“输入与输出的调度器”,steering files是“记忆的存储层”。没有hooks的文件是死文档,没有文件的hooks是空转的定时器。两者配合,才能形成一套有生命的项目知识体系。3. 手把手搭一套可复用的引导体系3.1 目录结构与初始化脚本先假设你手上有一个真实项目,路径是~/work/demo-service。第一步是在项目根目录建一个.kiro目录。我直接贴一下初始化时的目录结构:.kiro/ ├── steering/ │ ├── base.md │ ├── project.md │ └── history.md ├── hooks/ │ ├── pre_task.sh │ ├── post_edit.sh │ ├── session_start.sh │ └── task_done.sh └── bin/ └── kiro不需要任何第三方依赖,纯shell和Python就能跑起来。如果你们团队有统一的脚手架,也可以直接把.kiro模板放进脚手架里,新项目自动带出来。初始化脚本做的事情很简单:生成目录、创建三份空的steering文件、填充文件用途注释头。我一般在project.md里预填当前判定得到的技术栈和目录结构,这些信息越早给AI,越能避免它在一开始就放飞自我。3.2 第一版引导文件怎么写:三个文件的样例别想着一次写完美。第一版只做一件事:把项目里那些只要问一个老员工就立刻能答上来的信息写进去。我拿一个模拟项目举例。base.md的第一版大概长这样:# 通用编码偏好 ## 语言与注释 - 代码注释使用中文,但公共API的docstring使用英文 - 禁止在注释里写“这段代码是做什么的”这废话,要写“为什么这样做” ## 命名 - 函数/变量名使用camelCase,类型使用PascalCase - 数据库表名使用snake_case,且必须带模块前缀 ## 命令 - 所有CLI工具必须提供--help - 脚本失败时返回非零退出码,并在stderr打印原因project.md的重点是“地图”:# 项目:模拟订单服务 ## 技术栈 - 语言: Go 1.22 - 存储: Postgres 15 + Redis 7 - 队列: RabbitMQ 3.12 ## 架构 - 四层分层:handler → service → repository → storage - 禁止跨层调用,handler不能直接碰storage - 模块间通信走内部事件,禁止直接实例化其他模块 ## 风险区域 - 支付回调接口:必须做幂等处理,参考standby/idempotent.go - 库存扣减:使用乐观锁,禁止先查后扣history.md一开始是空的,我先写一条示例:# 经验日志 ## 2024-11-02 库存超卖问题 - 场景: 并发下单时库存扣减出现负数 - 原因: 使用先查后改而非原子条件更新 - 结论: 库存扣减必须用 UPDATE ... WHERE stock >= ? 的方式这三份文件加起来不超过60行。你会发现它内容很少,但AI拿到它以后,生成的代码立刻就不会再犯那些基础架构错误了。很多时候不用贪多,几条精准规则胜过一大段泛泛而谈。3.3 钩子实现:一个几十行的调度脚本我实际用的hook引擎非常简单,逻辑都写在一个Python脚本里。核心代码大概长这样:#!/usr/bin/env python3 import sys, subprocess from pathlib import Path ROOT = Path(__file__).resolve().parent.parent HOOK_DIR = ROOT / "hooks" def run_trigger(trigger: str) -> None: file = HOOK_DIR / f"{trigger}.sh" if file.is_file(): print(f"[kiro] run {file.name}") subprocess.run(["bash", str(file)], check=False) if __name__ == "__main__": run_trigger(sys.argv[1])调用方式就是:.kiro/bin/kiro pre_task每个钩子脚本只负责一件事。例如pre_task.sh负责把steering files里任意任务都需要的信息拼起来:#!/usr/bin/env bash STEERING_DIR="$(dirname "$0")/../steering" cat <<EOF ===== PROJECT CONTEXT ===== $(cat "$STEERING_DIR/project.md") ===== CODING STYLE ===== $(cat "$STEERING_DIR/base.md") ===== END CONTEXT ===== EOF你甚至不需要写代码,直接把这些脚本的输出复制粘贴到AI助手的对话里也行。我最初就是这么干的,复制了几次以后才决定做成自动注入。post_edit.sh我用来捕获变更摘要,原理是先用git diff统计变更,再把摘要追加到history.md:#!/usr/bin/env bash CHANGE_LOG=".kiro/steering/history.md" { echo "" echo "## $(date +%Y-%m-%d) 变更摘要" echo "- 文件: $(git diff --name-only | tr '\n' ' ')" echo "- 说明: 待人工补充" } >> "$CHANGE_LOG"这只是一个原型脚本。实际生产环境里,我还会加上文件分类和去重逻辑,避免AI每改一个文件就堆一条完全没信息量的日志。人工确认的好处也在于此:避免把AI的胡言乱语也沉淀成经验。这套机制里,永远是人来做最终裁判,AI只负责草拟。3.4 接入日常工作的三种姿势第一种,把钩子接到命令行工具里。比如你有一个内部CLI,原本跑测试是task run test,现在把它包装成先执行kiro pre_task再执行原命令,AI拿到的上下文就是最新的。第二种,直接粘贴。不想动工具链,就在开始一次复杂对话前,手动跑一下.kiro/bin/kiro pre_task,把输出的上下文粘贴进对话。虽然笨,但对没有CLI的纯IDE用户来说最省事。第三种,用编辑器插件或任务宏。如果你的编辑器支持任务或宏,可以在打开项目事件里自动执行session_start脚本。现在主流IDE基本都支持,配置一次能用很久。3.5 快速验证闭环是否跑通搭好以后,我建议用三个测试用例验证一下。问AI“这个项目用什么语言和数据库”,看它是否能直接从project.md里回答,而不是猜。故意写一段跨层调用代码,看它会不会警告你不符合架构。在history.md里加一条新踩坑记录,然后在一个新对话里问“我要做类似的事情,有什么要小心”,看它是否引用那条记录。如果三个都能通过,说明这套体系从读取到注入到回写的闭环已经建立起来了。4. 怎么能让它越用越聪明:反馈循环的三个关键细节4.1 经验沉淀的流程:AI草拟,人确认,文件固化我要强调一个原则:不要直接让AI往steering files里写历史经验。我见过有人把post_edit做成全自动,结果三天后文件里躺着一堆互相矛盾的结论,AI照着做反而出错。全自动写入的问题在于,AI自己也是概率模型,它对自己刚产出的代码判断不一定可靠,有时候会把临时方案误记成长期约定。我推荐的流程是:AI先写到一个inbox.md,你每天花两三分钟把它归并进正式的history.md。归并时做两个筛选:这条经验是否已被旧条目覆盖?它是否只适用于一个临时场景?两个条件都满足才能进正式文件。这个人工闸门是保证文件可信度的基础。4.2 定期“知识压缩”:从日志变成规则随着项目推进,history.md会越来越长。这时候如果不整理,AI的上下文窗口会被大量历史细节占满,反而降低精度。我一般每两周做一次压缩:把已经稳定执行的结论,从history.md提升到project.md或base.md的正式规则里把被反例验证过的旧方案,从history里标成“已废弃”把重复出现的相似记录合并成一条这个过程很像代码重构。压缩之后,steering files保持精简,但每一条都更有分量。半小时的整理,能省下后面几周反复解释的时间。4.3 跨项目复用:把base.md做成团队资产base.md里的内容是通用的,比如命名风格、注释规范、commit规范,值得沉淀成团队资产。我们团队用了一个简单办法:把base.md模板放在一个公共仓库里,新项目初始化时自动拷一份,遇到全团队共识的变化,改模板而不是挨个项目改。project.md则是完全个性化的,复制意义不大。history.md如果要跨项目复用,通常是高度抽象后的结论,比如“缓存失效要用版本号而不是时间戳”这种,可以转移到base.md里。4.4 多人协作时的注意事项steering files放进Git以后,就会面临合并冲突。不过因为它是文本文件,冲突解决起来很容易。更重要的是约定review规则:任何修改steering files的PR,必须附上说明项目管理员合并前,确认这条修改不会让文件长度膨胀使用git blame查看某条规则的来源,回滚错误决策很方便多人同时维护时,最容易出现的是规则互相覆盖。我们现在的做法是,每条规则都带一个owner字段,谁提的规则谁负责后续维护。遇到意见不合,拿历史记录说话,而不是拍脑袋。5. 踩过的坑和排查方法5.1 上下文爆炸:注入太多导致AI丢了西瓜一开始我贪心,把history.md全文都塞进每一次对话。结果AI遇到具体问题的时候,反而被大量无关历史带偏,回答质量明显下降。后来改成“分场景注入”:base和project进首批上下文,history只按关键词触发,比如用户提到“库存”“超卖”“幂等”,才追加对应的经验区块。关键参数是单次注入总字符数控制在3000字以内,优先保证最前面三分之一是最高优先级规则。5.2 引导文件“老化”:规则和现状脱节项目重构后,我忘了同步project.md,AI还拿着旧的架构说事。从那以后我定了规矩:任何模块迁移、依赖升级,PR里必须包含steering文件的同步更新,review时单独检查。工具方面,我会定期跑一个diff,比对project.md里描述的目录结构和实际仓库,不一致就报警。5.3 钩子静默失败:经验断流但没人发现post_edit写文件失败时脚本没提示,日志在哪都没找着,结果一个星期history都没更新。后来我给每个钩子加了日志和失败标记,每次任务结束输出一行“本轮已归档3条变更”,没输出就说明挂了。自动化越安静,越容易无声地坏掉,必须能看见心跳。5.4 安全和隐私:别把密钥写进引导文件你会在steering files里写很多项目细节,如果这个仓库不小心公开,等于把架构弱点拱手送人。我建议把steering files加入.gitignore,尤其是history.md里可能包含安全事故细节;或者提供一个脱敏版本。还要提醒:不要把正在用的API key、数据库地址直接写进去,真要记录,写成占位符加查找路径。5.5 常见问题速查表症状可能原因处理办法AI完全不理会引导文件hooks没生效/注入顺序不对检查pre_task输出是否在对话开头AI老是提新方案但不符合架构project.md里架构规则太弱增加“禁止跨层调用”类的强约束history导致回答跑偏历史注入过多且无触发条件改为按关键词触发多人改完文件冲突严重缺少owner机制每条规则标注owner,PR时提前同步新成员不知道有这套东西缺少onboarding入口在README和PR模板里加说明最后分享一点真实体会。这套方案本身不复杂,难的是坚持维护。我见过很多团队把steering files建好以后就没再动过,几周后就和项目脱节了,等于白搭。要让这套机制真正跑起来,关键是把它嵌进日常工作流,而不是当成额外负担。让AI草拟、你只做快速确认,让文件随PR同步更新,规则和真实代码保持同频。久而久之,你会发现AI的建议越来越像团队里资深成员给的review意见——倒不是说它突然变聪明了,是因为你们把团队的项目知识,变成了一条持续的输入流。如果你也受够了每天重复教AI项目背景,不妨从今天开始给你的项目建一个.kiro目录,从三份文件开始。
你有没有这种感觉——同一个AI编程助手,在别人手里像干了十年的老兵,到了你手里,连你上礼拜刚拆分的模块都记不住。每次它都很客气地说“你好,有什么可以帮你”,然后你只能再花十分钟去解释:我们的项目分层是这样的,我们用 Java 17 加 Spring Boot,错误处理必须走错误码……第一天你还有耐心,第十天你已经开始怀疑人生了。这大概是每个重度使用AI编程助手的人都会撞上的墙:模型能力很强,但记忆窗口很短。它不是智商不够,是你从来就没给它准备过一本“操作手册”。我最近折腾的一套小方案,就是为了解决这个事。思路不玄乎:把项目的各种约定、经验、偏好写进几个叫 steering files 的文件里,再配一组叫 kiro hooks 的自动钩子,在合适的时机把对应的内容精准地喂给AI助手。做到后面,你会发现它不是越用越懂你,而是你越来越会教它——结果就是它写出来的东西越来越像你们团队自己人写的。这个方案不依赖任何特定的IDE或者云平台,纯本地文件加几个脚本,人人都能照着搭。下面我把文件格式、钩子触发、迭代方法、踩过的坑全部交代清楚。1. 先别急着写代码,先确认痛点在哪儿1.1 我实际遇到的三种“AI失忆”现场我实际见过比较典型的三种失忆现场。第一种是架构失忆。项目做到中期,模块拆分、依赖方向都已经有明确约束。你让AI助手在某个模块里加一个功能,它可能会顺着当前文件乱引用,甚至跨层调用,因为没有文件告诉它“你只能依赖service层的接口”。它对项目架构的了解,完全建立在当前打开的十几个文件上,只要其中一个文件里有个旧写法,它就会照着旧写法扩散。第二种是约定失忆。你们团队的错误处理方式、命名规范、commit信息格式,都在代码评审里反复强调过,但AI助手每次都是第一次听说。我见过有人为了统一风格,往每个新文件开头都贴一段注释,最后代码里全是噪音,维护成本直线上升。第三种是踩坑失忆。某个接口的用法定死了,换一种写法在特定版本下有bug;某个配置项不能改,改了线上会出问题。这些经验你不可能每次都写进prompt里,但不写,它就还会踩同样的坑。这三种情况往深了说,本质是一件事:AI助手的每次对话都是冷启动,它对你的项目没有长时记忆。市面上的AI编程产品普遍提供了类似自定义指令、规则文件之类的功能,但在一个复杂项目里,固定文本根本不够用,而且更新成本很高。所以我开始想,能不能把它做成一套项目内可积累、可自动化加载的记忆系统。1.2 换个思路:把上下文工程变成项目基建关键转变在于:不要指望AI记住你,而是把“你希望它知道的东西”沉淀成文件,再设计一套自动注入机制。这其实是把软件开发里的一个老思路搬到了AI交互领域——把易变的知识从代码里拿出来,放到配置文件里,让程序在运行时加载。这里的“程序”就是AI助手工作流,“配置文件”就是steering files。这个思路有个额外的好处:文件和Git天然亲和。谁改了什么、哪条经验是哪次事故沉淀下来的,都有历史记录,可以回滚、可以评审。它不像对话历史那样是个黑盒,而是一等公民,可以review,可以测试,可以随着项目一起演进。于是就有了这套方案的架构雏形。2. kiro hooks 和 steering files:两个关键概念拆解2.1 steering files:给AI看的“项目操作手册”我习惯把steering files比喻成新员工入职手册。它不负责教AI怎么编程(那是它本来就懂的),而是告诉它:这个项目的世界长什么样,我们怎么做事,遇到过什么坑。在实际项目里,我推荐按下面的结构存放这三份文件:.kiro/steering/base.md:个人或团队通用的编码偏好。比如注释语言、命名风格、commit粒度、禁止使用的反模式。这部分可以跨项目复用。.kiro/steering/project.md:当前项目的架构地图。比如目录职责、模块边界、技术栈版本、核心数据流、部署环境等。是给AI的第一份地图。.kiro/steering/history.md:经验日志。按时间追加,每条记录包含“场景-现象-原因-结论”。遇到类似问题,AI可以在这里搜到旧方案。这个文件系统可以直接拿一个pull request来维护。每次有新知识,就提交一次变更;每次发现文件里有过期内容,就开issue修掉。我给文件里每条规则定了一个标准格式,方便AI解析也方便人写:字段说明例子范围这条规则作用于哪个模块/场景支付模块规则期望的行为或约束严禁直接操作数据库表,必须走仓储接口理由为什么要有这条规则表结构可能重构,避免散落的SQL反例它阻止了什么错误做法不推荐写原生SQL加上“理由”这一栏是我觉得很重要的点。AI很擅长模式匹配,但如果你只告诉它“不能这样”,它容易在别的场景继续犯类似的错误;如果告诉它为什么,它就能迁移到相似问题上,这个在实践里效果非常明显。2.2 hooks:在正确的时间递上手册文件放在那儿,AI不会主动去看。你需要一个机制,在“该知道的时候”把“该知道的内容”送进模型上下文。这就是hooks的职责。我实现了一套很轻量的钩子机制,核心触发点有这些:session_start:新建对话时,注入base.md和project.md。file_open:打开某个源文件时,注入该模块的职责说明和历史风险。触发频率高,所以内容要精简。pre_generate:准备生成代码前,注入目标文件涉及的相关接口、风格约束。post_edit:每次AI改完文件,自动追加一条变更摘要到history.md里。这一步是整个方案能越用越聪明的关键。task_done:一次任务完成后,提取本次对话里产生的关键决策,人工确认后写入steering files。你没看错,这个方案不是单向地喂给AI知识,更关键的是让AI在使用过程中不断把新经验写回文件。这就形成一个循环:读文件→应用到任务→记录新经验→下次读文件时包含这些经验。循环跑起来,它就一直在长。2.3 两者结合后的整体工作流我来描述一下这套闭环的实际运行方式:你启动一个AI辅助任务,shell wrapper先检查有没有.kiro目录,有就按顺序读入steering files的核心区块,拼进系统提示词;任务进行中,每当AI写入文件,watcher会捕获变更事件,自动生成一条结构化的提交记录;等到任务结束,你再花半分钟review一下history里的新增条目,把有价值的经验提炼进project.md或base.md。换句话说,hooks是“输入与输出的调度器”,steering files是“记忆的存储层”。没有hooks的文件是死文档,没有文件的hooks是空转的定时器。两者配合,才能形成一套有生命的项目知识体系。3. 手把手搭一套可复用的引导体系3.1 目录结构与初始化脚本先假设你手上有一个真实项目,路径是~/work/demo-service。第一步是在项目根目录建一个.kiro目录。我直接贴一下初始化时的目录结构:.kiro/ ├── steering/ │ ├── base.md │ ├── project.md │ └── history.md ├── hooks/ │ ├── pre_task.sh │ ├── post_edit.sh │ ├── session_start.sh │ └── task_done.sh └── bin/ └── kiro不需要任何第三方依赖,纯shell和Python就能跑起来。如果你们团队有统一的脚手架,也可以直接把.kiro模板放进脚手架里,新项目自动带出来。初始化脚本做的事情很简单:生成目录、创建三份空的steering文件、填充文件用途注释头。我一般在project.md里预填当前判定得到的技术栈和目录结构,这些信息越早给AI,越能避免它在一开始就放飞自我。3.2 第一版引导文件怎么写:三个文件的样例别想着一次写完美。第一版只做一件事:把项目里那些只要问一个老员工就立刻能答上来的信息写进去。我拿一个模拟项目举例。base.md的第一版大概长这样:# 通用编码偏好 ## 语言与注释 - 代码注释使用中文,但公共API的docstring使用英文 - 禁止在注释里写“这段代码是做什么的”这废话,要写“为什么这样做” ## 命名 - 函数/变量名使用camelCase,类型使用PascalCase - 数据库表名使用snake_case,且必须带模块前缀 ## 命令 - 所有CLI工具必须提供--help - 脚本失败时返回非零退出码,并在stderr打印原因project.md的重点是“地图”:# 项目:模拟订单服务 ## 技术栈 - 语言: Go 1.22 - 存储: Postgres 15 + Redis 7 - 队列: RabbitMQ 3.12 ## 架构 - 四层分层:handler → service → repository → storage - 禁止跨层调用,handler不能直接碰storage - 模块间通信走内部事件,禁止直接实例化其他模块 ## 风险区域 - 支付回调接口:必须做幂等处理,参考standby/idempotent.go - 库存扣减:使用乐观锁,禁止先查后扣history.md一开始是空的,我先写一条示例:# 经验日志 ## 2024-11-02 库存超卖问题 - 场景: 并发下单时库存扣减出现负数 - 原因: 使用先查后改而非原子条件更新 - 结论: 库存扣减必须用 UPDATE ... WHERE stock >= ? 的方式这三份文件加起来不超过60行。你会发现它内容很少,但AI拿到它以后,生成的代码立刻就不会再犯那些基础架构错误了。很多时候不用贪多,几条精准规则胜过一大段泛泛而谈。3.3 钩子实现:一个几十行的调度脚本我实际用的hook引擎非常简单,逻辑都写在一个Python脚本里。核心代码大概长这样:#!/usr/bin/env python3 import sys, subprocess from pathlib import Path ROOT = Path(__file__).resolve().parent.parent HOOK_DIR = ROOT / "hooks" def run_trigger(trigger: str) -> None: file = HOOK_DIR / f"{trigger}.sh" if file.is_file(): print(f"[kiro] run {file.name}") subprocess.run(["bash", str(file)], check=False) if __name__ == "__main__": run_trigger(sys.argv[1])调用方式就是:.kiro/bin/kiro pre_task每个钩子脚本只负责一件事。例如pre_task.sh负责把steering files里任意任务都需要的信息拼起来:#!/usr/bin/env bash STEERING_DIR="$(dirname "$0")/../steering" cat <<EOF ===== PROJECT CONTEXT ===== $(cat "$STEERING_DIR/project.md") ===== CODING STYLE ===== $(cat "$STEERING_DIR/base.md") ===== END CONTEXT ===== EOF你甚至不需要写代码,直接把这些脚本的输出复制粘贴到AI助手的对话里也行。我最初就是这么干的,复制了几次以后才决定做成自动注入。post_edit.sh我用来捕获变更摘要,原理是先用git diff统计变更,再把摘要追加到history.md:#!/usr/bin/env bash CHANGE_LOG=".kiro/steering/history.md" { echo "" echo "## $(date +%Y-%m-%d) 变更摘要" echo "- 文件: $(git diff --name-only | tr '\n' ' ')" echo "- 说明: 待人工补充" } >> "$CHANGE_LOG"这只是一个原型脚本。实际生产环境里,我还会加上文件分类和去重逻辑,避免AI每改一个文件就堆一条完全没信息量的日志。人工确认的好处也在于此:避免把AI的胡言乱语也沉淀成经验。这套机制里,永远是人来做最终裁判,AI只负责草拟。3.4 接入日常工作的三种姿势第一种,把钩子接到命令行工具里。比如你有一个内部CLI,原本跑测试是task run test,现在把它包装成先执行kiro pre_task再执行原命令,AI拿到的上下文就是最新的。第二种,直接粘贴。不想动工具链,就在开始一次复杂对话前,手动跑一下.kiro/bin/kiro pre_task,把输出的上下文粘贴进对话。虽然笨,但对没有CLI的纯IDE用户来说最省事。第三种,用编辑器插件或任务宏。如果你的编辑器支持任务或宏,可以在打开项目事件里自动执行session_start脚本。现在主流IDE基本都支持,配置一次能用很久。3.5 快速验证闭环是否跑通搭好以后,我建议用三个测试用例验证一下。问AI“这个项目用什么语言和数据库”,看它是否能直接从project.md里回答,而不是猜。故意写一段跨层调用代码,看它会不会警告你不符合架构。在history.md里加一条新踩坑记录,然后在一个新对话里问“我要做类似的事情,有什么要小心”,看它是否引用那条记录。如果三个都能通过,说明这套体系从读取到注入到回写的闭环已经建立起来了。4. 怎么能让它越用越聪明:反馈循环的三个关键细节4.1 经验沉淀的流程:AI草拟,人确认,文件固化我要强调一个原则:不要直接让AI往steering files里写历史经验。我见过有人把post_edit做成全自动,结果三天后文件里躺着一堆互相矛盾的结论,AI照着做反而出错。全自动写入的问题在于,AI自己也是概率模型,它对自己刚产出的代码判断不一定可靠,有时候会把临时方案误记成长期约定。我推荐的流程是:AI先写到一个inbox.md,你每天花两三分钟把它归并进正式的history.md。归并时做两个筛选:这条经验是否已被旧条目覆盖?它是否只适用于一个临时场景?两个条件都满足才能进正式文件。这个人工闸门是保证文件可信度的基础。4.2 定期“知识压缩”:从日志变成规则随着项目推进,history.md会越来越长。这时候如果不整理,AI的上下文窗口会被大量历史细节占满,反而降低精度。我一般每两周做一次压缩:把已经稳定执行的结论,从history.md提升到project.md或base.md的正式规则里把被反例验证过的旧方案,从history里标成“已废弃”把重复出现的相似记录合并成一条这个过程很像代码重构。压缩之后,steering files保持精简,但每一条都更有分量。半小时的整理,能省下后面几周反复解释的时间。4.3 跨项目复用:把base.md做成团队资产base.md里的内容是通用的,比如命名风格、注释规范、commit规范,值得沉淀成团队资产。我们团队用了一个简单办法:把base.md模板放在一个公共仓库里,新项目初始化时自动拷一份,遇到全团队共识的变化,改模板而不是挨个项目改。project.md则是完全个性化的,复制意义不大。history.md如果要跨项目复用,通常是高度抽象后的结论,比如“缓存失效要用版本号而不是时间戳”这种,可以转移到base.md里。4.4 多人协作时的注意事项steering files放进Git以后,就会面临合并冲突。不过因为它是文本文件,冲突解决起来很容易。更重要的是约定review规则:任何修改steering files的PR,必须附上说明项目管理员合并前,确认这条修改不会让文件长度膨胀使用git blame查看某条规则的来源,回滚错误决策很方便多人同时维护时,最容易出现的是规则互相覆盖。我们现在的做法是,每条规则都带一个owner字段,谁提的规则谁负责后续维护。遇到意见不合,拿历史记录说话,而不是拍脑袋。5. 踩过的坑和排查方法5.1 上下文爆炸:注入太多导致AI丢了西瓜一开始我贪心,把history.md全文都塞进每一次对话。结果AI遇到具体问题的时候,反而被大量无关历史带偏,回答质量明显下降。后来改成“分场景注入”:base和project进首批上下文,history只按关键词触发,比如用户提到“库存”“超卖”“幂等”,才追加对应的经验区块。关键参数是单次注入总字符数控制在3000字以内,优先保证最前面三分之一是最高优先级规则。5.2 引导文件“老化”:规则和现状脱节项目重构后,我忘了同步project.md,AI还拿着旧的架构说事。从那以后我定了规矩:任何模块迁移、依赖升级,PR里必须包含steering文件的同步更新,review时单独检查。工具方面,我会定期跑一个diff,比对project.md里描述的目录结构和实际仓库,不一致就报警。5.3 钩子静默失败:经验断流但没人发现post_edit写文件失败时脚本没提示,日志在哪都没找着,结果一个星期history都没更新。后来我给每个钩子加了日志和失败标记,每次任务结束输出一行“本轮已归档3条变更”,没输出就说明挂了。自动化越安静,越容易无声地坏掉,必须能看见心跳。5.4 安全和隐私:别把密钥写进引导文件你会在steering files里写很多项目细节,如果这个仓库不小心公开,等于把架构弱点拱手送人。我建议把steering files加入.gitignore,尤其是history.md里可能包含安全事故细节;或者提供一个脱敏版本。还要提醒:不要把正在用的API key、数据库地址直接写进去,真要记录,写成占位符加查找路径。5.5 常见问题速查表症状可能原因处理办法AI完全不理会引导文件hooks没生效/注入顺序不对检查pre_task输出是否在对话开头AI老是提新方案但不符合架构project.md里架构规则太弱增加“禁止跨层调用”类的强约束history导致回答跑偏历史注入过多且无触发条件改为按关键词触发多人改完文件冲突严重缺少owner机制每条规则标注owner,PR时提前同步新成员不知道有这套东西缺少onboarding入口在README和PR模板里加说明最后分享一点真实体会。这套方案本身不复杂,难的是坚持维护。我见过很多团队把steering files建好以后就没再动过,几周后就和项目脱节了,等于白搭。要让这套机制真正跑起来,关键是把它嵌进日常工作流,而不是当成额外负担。让AI草拟、你只做快速确认,让文件随PR同步更新,规则和真实代码保持同频。久而久之,你会发现AI的建议越来越像团队里资深成员给的review意见——倒不是说它突然变聪明了,是因为你们把团队的项目知识,变成了一条持续的输入流。如果你也受够了每天重复教AI项目背景,不妨从今天开始给你的项目建一个.kiro目录,从三份文件开始。