1. 项目概述:当AI写代码时,谁来为决策负责?
最近两年,AI编程助手的发展速度让人眼花缭乱。从最初的代码补全,到现在的“一句话需求,自动生成完整功能”,开发者的生产力工具正在经历一场深刻的变革。但作为一个在一线写了十几年代码的老兵,我观察到一个越来越明显的现象:我们正在进入一个“代码生产过剩,但决策质量堪忧”的时代。
你的AI助手可以在一分钟内生成过去需要半天才能写完的代码。这很棒,对吧?但问题也随之而来:这些代码背后的设计决策是怎么做出的?为什么选择方案A而不是方案B?一个月后,当需求变更或发现bug时,当初做决策的上下文还在吗?更重要的是,如果AI助手基于过时或错误的假设生成了代码,我们该如何系统地发现并纠正?
这就是Haft要解决的核心问题。它不是一个替代你写代码的AI,也不是一个简单的文档生成器。你可以把它理解为一个**“工程决策的治理层”**,一个架设在你的意图(“我想实现什么”)和AI代理的执行(“AI怎么写代码”)之间的智能看门人。它的使命是确保“我们不仅交付得快,更交付得对”。
简单来说,Haft强迫(或者说,引导)你和你的AI助手在动手写代码之前,先完成一套严谨的思考流程:定义清楚问题、探索多种方案、在公平的条件下比较它们、将最终决策记录为可验证的“合约”,并持续监控这些决策所依赖的假设是否依然成立。当假设失效时,它会第一时间提醒你。
2. Haft的核心设计哲学:从“快”到“对”的范式转变
2.1 为什么传统的AI编码流程存在缺陷?
在深入Haft的具体功能前,我们需要先理解它试图解决的痛点。目前主流的AI编码工作流,无论是使用Cursor、Claude Code还是其他工具,其本质往往是线性的、一次性的。
- 决策黑盒:你给AI一个指令(例如“优化这个API的响应速度”),AI直接生成代码。它可能隐含地考虑了多种方案(比如加缓存、优化数据库查询、引入异步处理),但最终只输出了一个结果。你无从知晓它放弃了哪些选项,以及放弃的理由。
- 上下文丢失:这次对话中做出的决策,不会被结构化地保存。一周后,另一个开发者(甚至是你自己)看到这段代码,很难理解当初为什么选择这个特定的缓存库,或者为什么设置这样的过期时间。所有的“为什么”都淹没在聊天历史里。
- 假设漂移:决策往往基于当时的假设(例如“用户量不会突然激增10倍”、“第三方服务API的99%可用性承诺是可靠的”)。当这些假设在后续发生变化时,没有任何机制能自动关联并提醒你,当初基于此假设的代码可能需要重新评估。
- 验证脱节:代码写完后,我们通常通过测试来验证其“正确性”,但很少去验证其“决策质量”。也就是说,我们检查代码是否按写的执行,但不检查当初选择这个方案是否依然是最优解。
Haft的核心理念,就是将这些隐性的、脆弱的决策过程,转变为显性的、结构化的、可长期维护的资产。
2.2 “第一性原理框架”的工程化实践
Haft并非凭空创造了一套方法论,它的思想根基源于Anatoly Levenchuk提出的“第一性原理框架”。FPF是一套跨学科的严谨思考架构,强调在解决问题前先框定问题,在比较方案前先明确比较的维度和标准。
Haft所做的,是将这套抽象的思考框架,工程化为AI代理可以理解和执行的具体工具。它给你的AI助手装上了一个“FPF原生操作系统”,让它的“思考”过程不再是黑箱,而是可追溯、可审查、可验证的。
举个例子,在没有Haft的情况下,你问AI:“用户登录太慢,优化一下。” AI可能会直接去改数据库索引。而在Haft的框架下,它会引导AI(和你)先执行以下步骤:
- 框定问题:是数据库查询慢?网络延迟高?还是会话管理逻辑复杂?
- 定义特征:衡量“快”的标准是什么?是平均响应时间(P95),还是首次加载时间?哪些用户角色最受影响?
- 探索方案:生成 genuinely different(真正不同)的选项,比如:优化现有查询、引入读写分离、增加应用层缓存、使用更快的身份验证协议。
- 公平比较:在相同的基准和约束下(比如都基于当前用户规模、相同的基础设施预算)评估每个方案。
- 记录决策:将最终选择的方案及其理由、关键假设、成功指标、回滚计划,作为一个“决策合约”保存下来。
这个流程产出的不仅仅是一段代码,更是一份伴随代码生命周期的“设计说明书”。
3. 核心组件与工作流深度解析
Haft通过一组MCP工具和一个核心命令行工具来运作。理解这些组件如何协同工作是有效使用它的关键。
3.1 六大MCP工具:结构化思考的积木
MCP是Model Context Protocol的缩写,它允许像Claude、Cursor这样的AI工具与外部工具(如Haft)安全交互。Haft提供了六个核心MCP工具,每个都对应决策流程中的一个关键环节。
| 工具 | 核心作用 | 实操要点与输出物 |
|---|---|---|
haft_note | 记录微决策与验证点。用于捕捉开发过程中那些小的、临时的决定或待验证的假设。 | 每个Note可以附加一个自动过期时间。例如,你可以记录:“假设库X的v2.0版本在本月底前是稳定的。” 并设置一个月后过期。到期后,Haft会提醒你验证这个假设是否依然成立。这是防止“临时方案变永久方案”的有效手段。 |
haft_problem | 定义与框定问题。这是所有工作的起点,确保团队在解决“同一个问题”。 | 需要明确问题类型(优化、诊断、搜索、合成),并定义比较维度。例如,对于一个“优化图片加载速度”的问题,维度可能包括“首次加载时间”、“90分位延迟”、“CDN成本”、“实现复杂度”。每个维度还可以关联一个“角色”,比如“用户体验工程师关心延迟,运维工程师关心成本”。 |
haft_solution | 探索与生成解决方案变体。目标是产生多样化的、真正不同的选项,避免群体思维。 | Haft会检查生成的方案是否“足够不同”。它不仅仅是在表面参数上变化(比如把缓存时间从60秒改成120秒),而是鼓励架构层面的不同选择(比如内存缓存 vs. 分布式缓存 vs. 客户端缓存)。 |
haft_decision | 创建决策合约。这是整个流程的产出核心,将选择哪个方案以及为什么,以结构化形式固定下来。 | 一个决策合约包含多个关键部分: 1.不变量:必须始终为真的条件(例如,“用户会话数据必须在100ms内可获取”)。 2.声明:可衡量的成功标准(例如,“P95 API响应时间降低至200ms以下”)。 3.证据:支持该决策的数据或事实,有形式化等级和有效期。 4.生命周期:包括“创建于”、“有效至”、“回滚计划”等字段。 |
haft_refresh | 管理决策生命周期。主动检查所有决策资产(Note, Problem, Decision)的健康状况。 | 这是Haft的“巡检”工具。它会扫描所有记录的证据是否过期、决策所依赖的外部条件是否改变、关联的代码模块是否发生了可能违反不变量的大改动。它将静态的文档变成了动态的、需要维护的资产。 |
haft_query | 知识图谱查询。在项目历史的决策网络中导航和搜索。 | 你可以查询:“所有与‘认证模块’相关的决策”、“上周所有状态为‘需复审’的决策”、“违反了‘数据库连接数’不变量的代码变更”。这相当于为你的代码库建立了一个“决策搜索引擎”。 |
3.2 核心工作流:两种驱动模式
Haft提供了两种使用模式,适应不同的工作习惯和场景复杂度。
模式一:一站式命令/h-reason这是最快捷的入门方式。你只需要向AI助手(如Claude)描述你的问题,然后使用/h-reason命令。
用户:我们的图片上传服务在高并发时经常超时,需要优化。 AI(使用/h-reason):正在启动Haft推理流程... 1. 框定问题:识别出瓶颈可能在于:a) 单机文件处理瓶颈,b) 同步阻塞式存储写入,c) 缺乏请求队列。 2. 生成方案:探索三种变体:a) 引入Redis队列异步处理,b) 改用S3分片上传,c) 升级服务器并使用更快的本地SSD缓存。 3. 公平比较:在模拟的1000RPS压力下,比较三个方案的预估成本、P99延迟、架构复杂度。 4. 记录决策:选择方案a(Redis队列),因为它在成本和复杂度增加有限的情况下,能最大程度平滑流量峰值。记录决策合约 dec-20241027-abc123。整个过程是自动的,Haft会根据问题的复杂度自动选择合适的推理深度。
模式二:手动分步驱动对于更复杂、或你想更深度参与决策过程的问题,可以手动调用每个步骤对应的命令:
/h-frame “我们的监控仪表盘数据加载太慢” ↓ 产出:一个清晰定义的“Problem”对象,明确了是“前端渲染慢”还是“后端聚合查询慢”。 /h-char “对于监控数据,什么最重要?” ↓ 产出:定义关键维度:数据新鲜度(<5秒)、查询灵活性、同时支持的用户数、渲染性能。 /h-explore “生成不同的技术方案” ↓ 产出:3个真正不同的方案:1) 预计算聚合表,2) 流式处理+增量更新,3) 引入OLAP数据库。 /h-compare “在相同数据量和查询模式基准下比较” ↓ 产出:一个对比表格,显示每个方案在四个维度上的预估表现,并标识出帕累托最优解。 /h-decide “我们选择方案2,因为...” ↓ 产出:最终的决策合约,包含不变量、证据和回滚计划。这种模式让你对每个思考环节都有完全的控制权,适合用于重要的架构决策。
实操心得:刚开始可以多用
/h-reason快速感受流程。当团队开始对重要模块进行重构或技术选型时,强烈建议采用手动分步模式,并邀请相关成员一起参与h-compare环节的讨论。这不仅能产生更好的决策,本身也是一个极好的技术沟通和对齐过程。
4. 从决策到代码:闭环的实现
记录决策只是第一步。Haft更强大的地方在于,它能将这个决策直接连接到代码实现和后续验证,形成一个完整的闭环。
4.1haft run:让AI在决策的约束下写代码
当你通过上述流程产生了一个决策合约(例如dec-20241027-abc123)后,真正的魔法开始了。你不需要手动把决策文档复制粘贴给AI,而是直接运行:
haft run dec-20241027-abc123 --agent claude这个命令会做以下几件事:
- 读取决策上下文:Haft从知识图谱中加载该决策的所有信息——要解决的问题、考虑过的方案、选择当前方案的理由、必须遵守的不变量、成功的衡量标准。
- 构建智能提示:它将上述信息结构化为一个详细的、包含约束条件的提示词。
- 生成代码:用这个提示词启动你指定的AI代理(如Claude、Codex)。AI是在完整的决策背景下工作的,它生成的代码会天然地尝试去满足那些不变量和声明。
- 自动建立基线:代码生成并(假设)测试通过后,Haft会自动为相关文件创建一个“基线”快照。这个基线代表了决策被正确实现那一刻的代码状态。
举个例子:假设你的决策是“引入Redis缓存用户配置,不变量是‘缓存缺失率低于1%’”。当你运行haft run后,AI生成的代码就不会只是一个简单的SET/GET,它很可能会包含缓存预热逻辑、适当的过期策略、以及缓存击穿保护——因为这些是实现“低缺失率”这个不变量的常见技术手段。
4.2haft check与证据工作流:持续验证的守护者
代码写完了,事情就结束了吗?在Haft的世界里,这只是另一个开始。决策合约中记录的“声明”和“证据”需要被持续验证。
- 主动测量:你可以使用
haft_decision(action="measure", ...)工具,在代码部署后,收集实际的生产指标(如真实的缓存命中率、API延迟),并将其作为新的“证据”附加到决策上。 - 信任衰减:Haft为每个决策计算一个动态的“有效信任度”。这个分数会随着证据的老化而自然衰减。一份一年前证明系统性能达标的压测报告,其说服力显然不如上周的报告。Haft用模型量化了这种衰减。
- 健康检查:
haft check命令是项目的“治理健康扫描仪”。它在本地运行,检查所有决策资产的状态:- 是否有证据已过期?
- 是否有决策的“有效至”日期已过?
- 是否有代码的变更(通过Git Diff分析)可能破坏了某个决策所依赖的不变量?
- 是否有决策声明中的阈值被最新测量数据所违反?
如果haft check返回错误(exit code 1),就意味着项目中存在需要人工介入审查的“治理发现项”。这可能是技术债的早期预警信号。
避坑指南:不要试图为所有决策都收集高等级证据(F3:生产环境长期监控数据)。这成本太高。合理的策略是:对于核心架构决策,追求F2或F3级证据;对于局部优化决策,F1(集成测试结果)或F0(开发者断言)即可。关键是建立定期运行
haft check的习惯,比如在每次迭代回顾会议前。
5. 桌面应用与多工具集成
5.1 桌面应用:可视化的决策驾驶舱
虽然Haft的核心是CLI和MCP插件,但其正在开发中的桌面应用提供了一个更直观的交互界面。你可以把它看作一个专为工程决策设计的“看板”或“仪表盘”。
- 治理总览:一屏查看所有决策的健康状态(绿色/黄色/红色),快速定位风险点。
- 问题板:以卡片形式陈列所有待解决的“Problem”,可以拖拽排序优先级。
- 决策详情:点击任何一个决策,可以看到其完整的谱系:它源于哪个问题、击败了哪些方案、当前的证据链、信任度分数以及所有关联的代码文件。
- 一键实施:在桌面应用上点击决策卡的“Implement”按钮,效果和
haft run一样,会在你的编辑器中启动AI代理会话。 - 多项目管理:方便同时监控多个代码仓库的决策状态。
目前桌面应用处于pre-alpha阶段,但它的方向很明确:降低Haft的使用门槛,让决策状态对团队更加透明。
5.2 与各类AI编码工具集成
Haft的MCP插件模式是其稳定且强大的部分。它几乎支持所有主流的AI编码环境:
- Claude Code:通过
haft init安装后,在Claude Code中可以直接使用/h-系列命令。 - Cursor:同样通过
haft init --cursor安装。特别注意:安装后,需要手动进入Cursor设置 → MCP Servers,找到haft并启用它。Cursor默认会禁用新添加的MCP服务器。 - Gemini CLI / Codex / Air:都有对应的
init标志。安装过程会在相应位置创建MCP配置文件和技能/命令。
集成原理:haft init本质上是在做两件事:
- 在AI工具的MCP配置中,注册
haft作为一个服务器(通常通过一个本地运行的Socket或Stdio进程)。 - 在AI工具的“技能”或“命令”目录中,安装Haft提供的工具描述文件。这样AI工具就知道有哪些
/h-命令可用,以及如何调用它们。
这种设计意味着,无论你使用哪种AI编辑器,你与Haft交互的体验和产生的决策资产都是统一的、可互操作的。
6. 实战部署与团队协作指南
将Haft引入个人项目或团队,需要一些规划和最佳实践。
6.1 初始化与项目上船
对于新项目,在根目录执行haft init后,你就拥有了一个.haft目录,用于存储所有决策资产(以JSON或Markdown格式)。建议将.haft目录加入版本控制(如Git)。这样,决策历史就和代码历史一起被追踪和协作。
对于已有项目,初始化后,运行/h-onboard命令。这是一个非常强大的功能:Haft会智能地扫描你的现有代码库,尝试识别出其中隐含的、未被记录的架构决策,并提示你将它们捕获为正式的决策合约。这就像是给你的遗留代码做一次“决策考古”,对于厘清技术债务至关重要。
6.2 团队工作流设计
- 决策记录作为代码审查的一部分:在发起Pull Request时,要求关联的决策合约ID(如
dec-xxxxx)必须写在PR描述中。审查者不仅可以看代码Diff,还可以查看完整的决策上下文,理解“为什么这样改”,从而做出更准确的审查。 - 定期治理会议:每周或每两周,运行
haft check,将产生的“治理发现项”作为会议议题。例如:“决策‘dec-123’关于使用库ABC的证据已过期,需要更新测试。”“决策‘dec-456’的不变量可能被最近的重构破坏,需要验证。” 这能将技术债的管理从被动救火变为主动巡检。 - 知识传承:新成员加入项目时,除了看代码,还可以通过
haft query来查询关键模块的决策历史。这是比文档更生动、更权威的项目上下文教学。
6.3 常见问题与排查
Q1: 运行/h-reason时,AI没有调用Haft工具,而是自己开始瞎编流程。A: 这通常是因为MCP连接未正确建立。首先,确认你已运行haft init并带有正确的工具标志(如--cursor)。其次,对于Cursor,务必去设置里手动启用Haft MCP服务器。最后,尝试重启你的AI编辑器,让MCP配置重新加载。
Q2:haft check报告了大量“证据过期”警告,如何处理?A: 这是正常现象,尤其是刚开始引入Haft时。不要试图一次性修复所有警告。优先处理那些:
- 关联核心业务逻辑或系统稳定性的决策。
- 近期可能发生变化的领域(如使用了即将停止维护的第三方库)。
- 被频繁修改的代码模块所关联的决策。 对于其他警告,可以批量延长其证据有效期,或计划一个技术债修复周期来处理。
Q3: 决策记录会不会太多,变成一种负担?A: 关键在于区分决策的粒度。不是每个if-else都需要记录。建议为以下情况创建决策合约:
- 技术选型:选择哪个数据库、框架、缓存方案。
- 架构设计:模块边界划分、通信协议、数据流设计。
- 重要优化:为了性能、成本、可维护性所做的有取舍的设计。
- 关键业务逻辑实现:复杂的算法、核心的状态机。 对于微小的、临时的决定,使用
haft_note并设置一个较短的过期时间即可。
Q4: 如何保证决策合约本身的质量?A: Haft在v6.1版本引入了“决策质量强制检查”(haft check的一部分)。它会检查诸如“一个问题是否对应多个决策”(违反单一责任)、“比较方案时是否有明确的公平性计划”等规则。团队也可以共同维护一个.haft/workflow.md文件,定义自己团队的决策记录规范,这个文件会被注入到每个AI提示中,引导生成更符合要求的合约。
7. 总结与展望
Haft代表了一种新的软件工程范式。在AI辅助编码能力突飞猛进的今天,它把关注点从“如何让AI写出更多代码”拉回到了“如何保证AI(以及我们)做出的每一个工程决策都是经得起时间考验的”。
它不是一个银弹,而是一套纪律。它要求我们在享受AI带来的速度红利时,不放弃工程师应有的严谨和远见。通过将决策结构化、资产化、并链接到代码,Haft在代码仓库之上,构建了一个活的“决策图谱”。这张图记录了系统的演化逻辑,守护着系统的健康状态,并最终成为团队最宝贵的知识库。
从个人使用来看,它能极大地提升复杂任务的处理质量和思考的条理性。从团队协作来看,它是打破知识孤岛、实现架构意图持久化传承的利器。虽然它的桌面应用和一些高级功能还在演进中,但其核心的MCP工具链已经非常稳定和实用。
我个人在几个项目中引入Haft后,最深的体会是:它强迫我慢下来思考,反而让我整体上走得更快、更稳。那些过去在几个月后需要花大量时间重新梳理的“当时为什么这么写”,现在都有了清晰的答案。当AI助手基于一个过时的决策合约开始生成可能不合适的代码时,Haft的警告就像一位时刻在线的资深架构师,轻轻拍了拍我的肩膀说:“等等,情况已经变了,我们得重新想想。”