1. 项目概述:为AI编码智能体引入操作系统级纪律
如果你和我一样,已经深度使用Claude Code这类AI编码助手超过半年,你一定会遇到一个核心痛点:上下文丢失。今天你让Claude重构了一个模块,选择了JSON存储方案,并详细讨论了为什么不用SQLite。明天你回来继续开发,Claude可能已经“忘记”了昨天的决策,开始建议引入Postgres,或者重复问你之前已经确认过的架构问题。这种“金鱼记忆”不仅浪费宝贵的对话轮次和Opus模型的token,更严重的是,它破坏了项目决策的连贯性,导致代码库出现前后矛盾的设计。
pm的出现,就是为了根治这个问题。它不是一个简单的任务追踪器,也不是另一个花哨的UI面板。你可以把它理解为一个嵌入在Claude Code工作流中的“操作系统”,或者更准确地说,是一个强制性的纪律执行层。它的核心哲学是:将人类软件工程中那些经过验证的最佳实践——比如设计决策记录、工作流阶段划分、代码审查前的准备——通过技术手段“焊死”在AI助手的工作流程中,让它无法绕过。
想象一下,你为Claude Code安装了一套不可卸载的“交通规则”和“飞行记录仪”。pm通过五个精心设计的钩子(Hooks)直接注入Claude的上下文,在它思考、提问、写代码的每一个关键节点进行干预。它强制要求Claude在动代码前先“读手册”(Doctrines),在做出选择时“记日志”(Decisions),在任务膨胀时“打报告”(Scope Guardrails)。最终,你得到的不再是一堆散乱的、上下文无关的代码片段,而是一个有完整决策链、可追溯、可继承的工程记录。这对于需要多轮会话协作的中大型功能开发、长期维护的项目,或者团队间交接AI生成代码的场景,价值是颠覆性的。
2. 核心设计哲学与架构拆解
2.1 核心理念:从“建议”到“强制执行”
市面上的大多数AI工作流工具,其设计思路是“增强”或“辅助”。它们提供建议、模板或快捷方式,但最终执行权仍在用户或智能体手中。pm的设计截然不同,它走的是“约束”和“强制执行”的路线。这背后是一个深刻的洞察:在缺乏明确约束的情况下,基于概率模型的AI智能体,其行为是发散且不可预测的。让它“最好”记录一下决策,它可能因为节省token或追求最快输出路径而选择忽略。
因此,pm的架构核心是Claude Code Hooks。这些钩子不是可选的插件,而是直接写入项目本地.claude/settings.json的规则。特别是PreToolUse这个钩子,它能在Claude执行Edit或Write命令前进行拦截。如果pm发现当前没有活跃任务(active work),或者任务已超出预设范围(scope creep),或者必要的“教条”未被阅读,它会直接返回一个BLOCKED错误,物理上阻止代码编辑的发生。这种“硬拦截”机制,是将工作流纪律从“软性文化”转变为“刚性制度”的关键。
注意:这种强制性的设计意味着你需要完全接纳
pm的哲学。它不适合“快速修个拼写错误”的场景。对于这类情况,pm也提供了逃生通道:你可以在提示词中明确加入“quick fix”这样的信号,pm的钩子会识别并临时放宽某些检查。但这应该是个例外,而非常态。
2.2 三层控制体系:记忆、流程与护栏
pm的功能可以清晰地分为三个层次,共同构成一个完整的控制体系:
持久化记忆层(Persistent Memory):这是
pm的基石,解决“遗忘”问题。所有通过pm decide记录的设计决策、理由和后续行动项,都以结构化的方式存储在.pm/data.json中。更重要的是,UserPromptSubmit钩子会在每一次对话交互时,自动将与当前提示词关键词匹配的历史决策注入Claude的上下文。这意味着Claude在思考时,背景信息里永远包含着过去的智慧,实现了真正的跨会话记忆。工作流纪律层(Workflow Discipline):这是
pm的骨架,解决“混乱”问题。它将一次代码变更抽象为严格的“发现(Discovery)”和“执行(Execution)”两阶段。- 发现阶段:禁止写代码。Claude必须在此阶段完成上下文拉取(
pm recap)、查阅历史决策(pm why)、制定计划(根据planning设置)和提出澄清问题(根据questions设置)。只有满足了所有前置条件,PreToolUse钩子才会放行。 - 执行阶段:Claude可以自主编码,但每个编辑动作都必须关联到一个已启动的
pm任务(pm start)。这就像在工厂里,每个零件加工都必须有对应的工单。
- 发现阶段:禁止写代码。Claude必须在此阶段完成上下文拉取(
行为护栏层(Guardrails):这是
pm的安全网,解决“失控”问题。它包含一系列自动化的边界检查:- 范围蔓延拦截:一个
issue(用于1-2个文件的快速修复)如果涉及文件超过4个或编辑超过10次,会被强制要求升级为feature(包含多个task的结构化工作)。这防止了小修小补演变成不可控的大改动。 - 探索成本提示:
pm会统计每个任务中的Read和Grep操作。当探索成本过高时(例如Read + 2*Grep >= 3),它会提示Claude将探索性子任务委托给更轻量级的模型(如Haiku/Sonnet),以节省主会话(通常是Opus)的token和上下文空间。 - 会话后清理:
pm sweep命令会自动关闭所有未完成的事项、过时的任务和草稿,确保项目状态整洁,为下一次会话提供干净的起点。
- 范围蔓延拦截:一个
2.3 数据存储与自愈机制
pm的所有状态都存储在项目根目录下的.pm/文件夹中,采用纯JSON格式,无需数据库或网络服务。这种设计保证了极致的简单性和可移植性。你可以将.pm/目录加入.gitignore,也可以选择性地提交data.json以在团队间共享决策记录。
自愈(Self-healing)是pm另一个值得称道的设计。每次运行pm命令(即使是打开TUI),它都会静默检查.claude/settings.json中的钩子配置。如果钩子被意外删除、修改,或者你克隆了一个新项目,pm会自动重新安装它们。这意味着你永远不需要思考“我的pm环境是否正确搭建了”——它自己会搞定。这种零维护的设计极大地提升了工具的可靠性和用户体验。
3. 核心功能深度解析与实操要点
3.1 持久化记忆:如何让AI记住“为什么”
持久化记忆是pm的灵魂,但其实现方式非常巧妙。它不是一个模糊的“向量数据库记忆”,而是高度结构化、面向行动的决策记录。
记录决策:pm decide命令详解当你和Claude共同做出一个关键选择时,应立即使用此命令进行记录。其语法富有深意:
pm decide auth-storage "Use JSON storage instead of SQLite" \ --reasoning "Authentication state is simple; need zero native dependencies for easy deployment across environments." \ --action "Never add a Postgres dependency to the auth module. If complexity grows, revisit with a dedicated session."- ID (
auth-storage):一个简短的、描述性的标识符。好的ID应该像代码变量名一样清晰,例如user-api-rate-limit,ui-component-library-choice。 - 描述:用引号包裹的、一句明确的决定陈述。
--reasoning:这是最重要的部分。不仅要记录“是什么”,更要记录“为什么”。这个理由将成为未来会话中判断该决策是否仍适用的关键依据。环境变了,理由可能就不成立了。--action:可选的后续行动项或明确禁令。这能将决策转化为具体的开发约束,例如“禁止引入XX库”、“必须通过XX接口访问”。
检索决策:自动注入与主动查询pm采用“推送为主,拉取为辅”的策略。UserPromptSubmit钩子会自动分析你的提示词,提取关键词(如“storage”, “auth”, “rate limit”),并将匹配的历史决策注入上下文。大多数时候,Claude无需主动查询就能“看到”相关历史。
当你需要主动探索时,使用pm why <keyword>。它会搜索所有决策记录,返回匹配项。实操心得:养成在开始任何非琐碎任务前,先让Claude运行pm recap(概述当前工作)和pm why “相关领域”的习惯。这能有效避免重复劳动和设计冲突。
3.2 工作流纪律:可配置的严格等级
pm没有采用“一刀切”的严格流程,而是通过三个可配置的维度让你控制纪律的松紧度。通过pm settings命令循环切换等级:
| 设置项 | 等级 | 控制内容 | 弱等级下的表现 | 强等级下的表现 |
|---|---|---|---|---|
planning | none/medium/all | 编码前必须进行的规划深度 | none: 无要求。medium: 建议性提示。 | all:硬性阻塞。必须阅读planning教条并制定计划,否则无法编辑代码。 |
questions | none/medium/thorough | 发现阶段需要提出的澄清问题深度 | none: 无要求。medium: 建议性提示。 | thorough:硬性阻塞。必须阅读questions教条并进行深入提问。 |
followup | none/medium/thorough | 初始回答后,进行跟进追问的深度 | none: 无要求。medium: 建议性提示。 | thorough:硬性阻塞。必须阅读followup教条并进行深入追问。 |
decisions教条是特例:无论以上设置如何,它始终是硬性要求。这意味着在任何等级下,Claude都必须先阅读pm doctrine decisions,理解如何记录和利用决策,才能开始编码。这凸显了持久化记忆在pm体系中的核心地位。
如何选择等级?
- 探索期/原型开发:可设为
planning=medium, questions=thorough, followup=medium。强调多提问以明确需求,但规划可以灵活。 - 成熟期/功能开发:建议
planning=all, questions=thorough, followup=thorough。在动代码前进行充分设计和澄清,确保方向正确,减少返工。 - 维护期/小修小补:可设为
planning=none, questions=none, followup=none。配合提示词中的“quick fix”信号,实现快速修改。
3.3 教条系统:模块化的行为指南
pm没有采用一个庞大的、一次性注入的“超级提示词”,而是设计了一个精巧的教条系统。它包含10个小型Markdown文件,每个文件专注于一个特定的工作环节。
教条的工作机制:
- 路由注入:
SessionStart钩子每次都会向Claude的上下文注入最小的router教条。这个文件就像一个目录,告诉Claude其他教条的存在和用途。 - 按需拉取:当工作流进入特定阶段(如需要规划时),Claude会根据
router的指引,运行pm doctrine planning来获取详细的规划指南。这个“拉取”动作会被静默记录在.pm/doctrine-session.json中。 - 强制检查:
PreToolUse钩子在允许编辑前,会检查此记录文件。如果当前配置要求planning=all,但planning教条未被拉取,编辑操作将被硬性阻塞。
这样做的好处:
- 节省上下文窗口:只有当前需要的指南才会被加载,最大化了用于代码和推理的token。
- 关注点分离:每个教条内容高度聚焦,易于编写和维护。
- 可定制性(高级用法):理论上,你可以修改项目本地
.pm/doctrines/目录下的教条文件,来定制Claude在你项目中的具体行为准则。
3.4 范围控制与子代理委托
这是pm中两个非常实用的“自动驾驶”功能,能有效控制开发成本和模型开销。
范围控制:Issue vs. Featurepm对工作项有明确的分类:
- Issue:用于1-2个文件的简单修复或小改动。通过
pm add-issue “描述”创建。 - Feature:用于涉及3个以上文件或需要多个步骤的结构化工作。通过
pm add-feature “描述”创建,内部可以包含多个phase和task。
护栏规则:当一个issue涉及的文件数达到4个,或编辑次数达到10次,PreToolUse钩子会强制阻塞,并提示:BLOCKED: This issue has grown too large. Run: pm upgrade <issueId>。执行升级后,该工作项会转换为一个feature,从而可以结构化地管理更复杂的工作。这强制你和Claude在早期就意识到工作范围的膨胀,并及时调整管理策略。
子代理委托:优化token与上下文大语言模型的token是宝贵资源,尤其是使用Opus等顶级模型时。让Opus去执行大量的文件阅读(Read)和全局搜索(Grep)是昂贵的,而且会污染主要任务的上下文。
pm的PreToolUse钩子会统计每个任务内的探索操作:Read计1分,Grep计2分(因为通常更耗资源)。当累计分数达到3时,UserPromptSubmit钩子会在上下文中插入一个提示:
💡 Subagents: 3 reads this task. For further exploration, delegate to the Explore agent (Haiku/Sonnet — saves Opus tokens, keeps context lean). Pull rules: pm doctrine subagents这提示Claude可以开启一个新的、使用更轻量级模型(如Haiku)的会话,专门处理探索性工作,然后将结论摘要发回主会话。这不是强制阻塞,而是一个强烈的优化建议。遵循这个建议,能显著降低对话成本,并保持主任务上下文的清洁。
4. 完整实操流程:从零开始一个功能开发
让我们通过一个完整的例子,看看如何在实际项目中使用pm来开发一个“用户个人资料图片上传”功能。
4.1 初始化与项目设置
首先,在你的Node.js项目根目录下进行全局安装和初始化:
# 全局安装pm npm install -g @piotrjura/pm # 进入你的项目目录 cd your-project # 首次运行,初始化pm pm首次运行会启动TUI,并提示你将创建.pm/目录、安装Claude Code钩子、添加Bash(pm *)权限。确认后,初始化完成。此后,在任何子目录下运行pm都会打开TUI查看状态。
接下来,我们为这个新功能设置严格的工作流纪律:
# 设置深度规划、深度提问和深度跟进 pm settings # 使用箭头键和回车,将 planning, questions, followup 都设置为 ‘thorough’ (最强等级)现在,Claude在为我们编写任何代码前,都必须进行完整的规划、提问和决策记录。
4.2 阶段一:发现与规划
我们在Claude Code中开启一个新会话。SessionStart钩子会自动触发,向Claude注入当前项目状态简报和router教条。
第一步:创建功能条目我们不在Claude里直接开始聊需求,而是先通过pm创建结构化的工作项。
# 在项目终端或Claude的Bash工具中运行 pm add-feature “Implement user profile picture upload”这会在.pm/data.json中创建一个feature,并生成一个ID(如feat_abc123)。TUI中可以看到这个新功能。
第二步:启动Claude会话并拉取教条回到Claude,我们输入提示:“Implement user profile picture upload. The feature ID is feat_abc123.”
UserPromptSubmit钩子立刻工作:
- 识别到有活跃功能(
feat_abc123)。 - 检查教条拉取状态。因为我们设置了
planning=thorough,而planning教条未被阅读,所以它会返回一个BLOCKING通知,要求Claude先运行pm doctrine planning。 - 同时,它会注入与“upload”、“profile”、“user”相关的任何历史决策。
Claude看到阻塞提示,必须遵从:
pm doctrine planning阅读完规划教条后,Claude理解了它需要先制定一个计划。它可能会运行pm recap来查看功能详情,然后运行pm why “upload”或pm why “storage”来查找相关历史决策(比如之前是否决定过使用AWS S3还是本地存储)。
第三步:制定计划与提问根据planning和questions教条的指导,Claude会输出一个初步计划,并开始提出澄清问题,例如:
- “图片大小限制是多少?”
- “支持哪些文件格式?”
- “上传后需要生成缩略图吗?存储路径结构是怎样的?”
- “是否需要集成CDN?”
我们一一回答。由于followup也设置为thorough,Claude可能会根据我们的回答进行更深度的追问,直到它认为需求已完全明确。
4.3 阶段二:执行与编码
当所有必要的教条都被拉取,且Claude认为规划已完成后,PreToolUse钩子解除阻塞。
第四步:分解任务并开始工作Claude会将大功能分解为多个任务(task)。它通过pm来管理这个过程:
# Claude 创建任务 pm add-task “Set up Multer middleware for file upload” --feature feat_abc123 pm add-task “Implement API endpoint POST /api/users/:id/avatar” --feature feat_abc123 pm add-task “Create image processing service (resize, format conversion)” --feature feat_abc123 pm add-task “Update user model and API response to include avatar URL” --feature feat_abc123 # 然后开始第一个任务 pm start task_xyz789 # 第一个任务的ID关键点:只有执行了pm start的任务,才处于“活跃工作”状态。PreToolUse钩子只允许编辑与活跃任务相关的文件。
第五步:编码与决策记录Claude开始编写Multer中间件。当它需要在“将文件存储在uploads/本地目录”和“直接流式上传到云存储”之间做选择时,它应该记录这个决策:
pm decide profile-pic-storage “Store uploaded files locally in ‘uploads/’ directory initially” \ --reasoning “Simpler for development and testing. Can be replaced with S3 later without changing the API interface.” \ --action “Ensure the ‘uploads/’ directory is gitignored. Write a clear comment in the config that this is a dev setup.”这个决策会被自动关联到当前活跃的任务和功能上。
第六步:应对范围蔓延在实现API端点时,Claude发现还需要修改用户认证中间件来记录日志。这涉及了第5个文件。PreToolUse钩子检测到当前issue(在feature下的每个task初期也被视为一个逻辑issue)范围超标,立即阻塞编辑并提示:“BLOCKED: This issue has grown to 5 file(s)...”。Claude需要评估:这是一个新的子任务,还是应该调整当前任务的范围?如果需要,它可以创建一个新的任务来专门处理日志增强。
第七步:探索优化在编写图像处理服务时,Claude需要查阅sharp库的文档,多次使用Read。当探索分数达到3时,上下文会收到子代理委托提示。Claude可以决定是否开启一个Haiku会话去专门研究sharp的最佳实践,然后将总结发回,从而节省主会话的token。
4.4 阶段三:收尾与清理
所有任务完成后,Claude运行:
# 标记任务完成 pm done task_xyz789 --note “Multer middleware configured with size and type filters.” # ... 完成其他任务 # 最后,标记整个功能完成 pm done feat_abc123 --note “Profile picture upload feature fully implemented and tested.”在会话的最后,或者开始新工作前,运行清理命令:
pm sweep这个命令会关闭所有状态为“进行中”但已长时间无活动的项,并清理临时数据,确保项目管理界面整洁。
5. 常见问题、故障排查与高级技巧
5.1 安装与钩子问题
问题:运行pm后,Claude Code似乎没有反应,没有看到阻塞或提示。
- 排查步骤1:检查
.claude/settings.json文件是否存在,以及其中hooks部分是否包含pm安装的五个钩子。可以运行cat .claude/settings.json | grep -A5 -B5 “pm”查看。 - 排查步骤2:确认Claude Code的版本支持自定义钩子。确保你使用的是最新版本。
- 排查步骤3:在Claude Code中尝试运行一个简单的
pm recap命令。如果报错“command not found”,可能是全局npm包路径未在Claude的环境变量中。一个解决办法是在项目本地也安装一次:npm install @piotrjura/pm --save-dev,然后Claude可能会优先使用本地node_modules/.bin/pm。 - 解决方案:最简单的办法是退出并重启Claude Code桌面应用。重启后,运行
pm命令,其自愈机制通常会重新正确安装钩子。
问题:钩子似乎生效了,但阻塞信息没有出现,Claude还是直接编辑了代码。
- 可能原因:你的提示词中包含了
quick fix、ignore pm或类似的信号词。pm的钩子设计会识别这些信号并临时禁用某些严格检查。确保在正式的开发会话中避免使用这些词。 - 可能原因:
pm的配置 (planning,questions,followup) 被设置为了none。检查当前设置:在TUI中按s,或运行pm settings查看。
5.2 工作流与命令使用
问题:我不小心开始编码了,但没有先pm start一个任务,现在被钩子阻塞了,怎么办?
- 标准流程:按照阻塞提示的信息,运行
pm add-issue “描述”或pm add-task “描述” --feature <featureId>创建一个工作项,然后pm start <workId>。 - 快速补救:如果你确实只是想做一个微小的、不属于任何计划任务的修改,可以在Claude的提示词中明确说明“
quick fix: 修改某个拼写错误”,pm的钩子可能会允许这次编辑(取决于配置)。但这不是推荐做法。
问题:pm sweep会删除我未完成的工作吗?
- 不会。
pm sweep的设计是智能的。它主要会关闭那些没有活跃编辑动作超过30分钟的“僵尸”任务或议题。对于你刚刚还在操作的任务,它不会被清理。如果你确实想强制清理所有进行中的项目,可以使用pm cleanup --force,但请谨慎使用。
问题:如何查看所有的历史决策?
- TUI查看:运行
pm打开TUI,按w键即可进入决策视图,浏览所有记录的决策。 - 命令行筛选:你可以使用
pm why配合关键词搜索,但目前没有直接列出所有决策的CLI命令。决策数据存储在.pm/data.json中,你也可以直接查看这个文件(注意它是JSON格式)。
5.3 高级技巧与自定义
技巧1:利用决策记录进行知识传承.pm/data.json文件是项目的宝贵知识库。你可以选择性地将其加入版本控制(但注意忽略.pm/session.json等临时文件)。这样,当新成员加入项目,或者你隔了几个月再回来维护时,运行pm recap和pm why就能迅速理解之前的架构决策和来龙去脉,这是普通代码注释无法比拟的。
技巧2:自定义教条(高级)pm的教条文件位于~/.pm/doctrines/(全局)或<project>/.pm/doctrines/(项目)。你可以复制并修改这些Markdown文件,来定制适合你团队或项目特定规范的工作流指南。例如,在planning.md中加入你们团队特有的“设计文档模板”要求。注意:修改后需要重启Claude Code会话或确保教条被重新拉取。
技巧3:与团队工作流结合虽然pm是本地工具,但你可以建立团队规范:要求每个功能开发都必须创建一个对应的pm feature,并将关键的pm decide记录作为代码审查的一部分。这能将AI辅助开发的“黑盒”过程部分白盒化,提升协作质量。
技巧4:处理复杂分支和实验如果你正在进行一个高风险的实验性重构,可以创建一个独立的feature,并将其planning和questions等级设为thorough。而对于一些修复已知bug的分支,则可以设置为none以追求速度。pm的配置是项目级的,但你可以通过有意识地创建不同的功能/议题来间接实现不同严格等级的工作流。
pm工具带来的是一种范式转变,它将AI编码从随机的、对话驱动的辅助,转向了有纪律、可记录、可复现的工程实践。最初的适应阶段可能会感觉有些“束缚”,但一旦习惯,你会发现它带来的上下文连贯性和决策可追溯性,能极大提升复杂项目开发的信心和效率。它不仅仅是管理Claude,更是在帮助你塑造一个更可靠、更专业的AI协作伙伴。