mcpField
W
why

why

github.com/poteto开发161116 次安装22 周前更新
代码仓库

关于 why

why 是用于调查代码设计动机与历史背景的 Agent 技能,适合需要了解约束、边界情况和被舍弃方案的开发者。它要求并行检查多类证据,并明确标注依据、置信度和信息缺口。

主要功能

  1. 01从代码历史建立调查锚点
  2. 02并行检索多类证据来源
  3. 03区分直接证据与推断
  4. 04报告矛盾与信息缺口
  5. 05为动机结论提供引用

适用场景

  1. 01追查某项设计决策的由来
  2. 02了解防御性代码考虑的边界情况
  3. 03调查替代方案为何未采用

MCP 相关

技能会枚举可用 MCP,并按证据类别映射与并行调查;MCP 可涵盖工单、文档、团队聊天、可观测性、错误追踪和分析数据。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/poteto/plugins --skill why

安装后在 Claude Code 中输入/why确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
epistemics.md
investigator-prompt.md
source-playbook.md
synthesizer-prompt.md
references/sources/
code-archaeology.md
databricks.md
datadog.md
incident-postmortem.md
linear.md
notion.md
sentry.md
slack.md

详细介绍

原因

探究代码背后的动机和意图。为什么要这样构建?考虑了哪些边缘情况?哪些产品、业务或运营约束影响了设计?舍弃了哪些替代方案,原因是什么?

与 how 技能配套。how 回答代码做什么以及如何运作。why 回答促使代码形成如今形态的各种因素。

此技能的工作方式

历史背景分散在七类证据中:源代码管理历史、问题或工单跟踪、长篇文档、实时团队聊天、基础设施可观测性、错误或异常跟踪,以及产品分析数据仓库。仅凭问题无法预测答案会出现在哪一类中,因此此技能会在运行时枚举可用的 MCP,将每个 MCP 映射到一个类别,并行查询全部七类,然后综合结果并明确校准置信度。已搜索类别中的空结果,也是关于决策过程的重要证据;应与正面发现一并报告。默认做法是全面覆盖,而非尽量精简。

工作态度

以谨慎、审慎、精确的态度开展调查。像侦探一样,从零碎记录中拼凑历史案件。当记录稀少时,要如实说明。

具体来说:

  • 证据先于叙述。 先收集材料,再看它们支持怎样的故事。切勿先选定一个故事,再搜集与之相符的证据。
  • 精准胜于润色。 优先采用准确引文和出处,而不是流畅的转述。读者应能在一分钟内追溯并核实任何说法。
  • 考虑尚未看到的内容。 你找到的证据只是样本,并非全部事实。下结论前,先问:如果另一种解释成立,你会预期看到什么?你是否查找过这些证据?
  • 指出缺口。 如果线索中断、来源无法搜索,或某个问题没有答案,就记录这个缺口。不要用听起来权威的猜测掩盖它。
  • 有意使用保留措辞。 证据间接时,措辞应体现这一点(“似乎”“可能”“表明”)。措辞与置信度相匹配是输出的必要特征,不能由综合者以风格选择为由擅自改变。
  • 不走读代码的捷径。 代码能告诉你它做什么,却很少能说明它为何存在。不要仅凭代码的结构推断意图。

这种态度是实际工作方法,而非免责声明。

核心认识论原则

此技能从零散的历史证据中构建拼凑式理解。工单会过时,聊天线程可能被删除,提交说明可能不实,人们可能会在 PR 描述和实现之间改变主意,原作者也可能已离开公司。

对已知与推断的内容,必须严格如实。目标不是讲出令人满意的故事,而是呈现证据、校准置信度,并让用户自行判断。

原则:

  • 所有内容均须引用。 每条关于意图的说法都应引用具体的提交哈希、PR 编号、工单 ID、文档 URL、聊天永久链接或代码注释。无法引用的内容属于推断,必须明确标注。
  • 优先使用“似乎”,而非“因为”。 证据间接时应使用保留措辞。只有直接、明确的证据才适合使用肯定语气。
  • 呈现矛盾。 如果两个来源说法不一,应同时展示。不要悄悄挑选符合叙述的那一个。
  • 承认缺口。 如果在搜索过的所有来源中都找不到问题的答案,就如实说明。坦诚地说“我们没能查明原因”,胜过自信地猜测。
  • 允许存在多种假设。 如果证据支持多种解释,就逐一列出,并提供各自的证据。让用户自行综合判断。
  • 警惕事后合理化。 如今看似合理的代码,编写时可能有现已不再适用的原因,也可能根本没有充分理由。不要事后补造意图。

阅读 references/epistemics.md,了解完整的置信度框架和措辞指南。综合者必须遵循该指南。

步骤 1:理解目标和问题

解析用户的诉求。目标通常是一段代码、某种模式、一项功能或一个命名的设计决策。问题通常属于以下某一种:

  • “为什么要这样设计 X?”设计依据。
  • “为什么做 X 而不是 Y?”权衡或替代方案。
  • “哪些边缘情况促使我们这样做?”防御性考量。
  • “是什么业务或产品限制导致这样做?”外部驱动因素。
  • “为什么这段代码还存在?”死代码相关问题。
  • “X 的历史是什么?”广泛的考古式追溯。

如果目标含糊不清(例如没有明确指代对象的“为什么要这样做?”),请根据对话上下文(打开的文件、最近的编辑、光标位置、刚讨论过的内容)尽可能推断。简要说明你的理解,让用户在你理解有误时能够纠正,然后继续。

步骤 2:确定代码锚点

在启动调查人员之前,先将调查锚定在具体代码上。你需要:

  • 相关文件路径和行范围
  • 关键符号(函数名、类名、常量)
  • 初始提交列表,即最近修改目标的几次提交
  • 合并提交中的 PR 编号(主题行中的模式 (#1234))

在此处直接收集这些信息。成本很低,而且每位调查人员都需要这些信息。

# Blame target lines for last-touch commits
git blame -L <start>,<end> <file>

# Full file history, with patches, through renames
git log --follow -p -- <file>

# Last N commits touching the file, PR numbers visible
git log --oneline -20 -- <file>

# Extract PR numbers from a commit message
git log -1 --format=%B <commit>

对于任何有实质内容的提交,使用 gh 获取 PR 正文和讨论:

gh pr view <number> --json title,body,author,createdAt,mergedAt,labels,closingIssuesReferences,comments,reviews

将这些信息作为种子上下文(文件路径、符号、提交、PR 编号、关联的工单 ID)记录下来,并传给调查人员,避免他们重复查找。

步骤 3:并行启动调查人员(默认做法)

默认进行完整的并行调查。 每类证据都存在于不同类型的系统中,而仅凭问题本身无法判断答案会出现在哪里,因此必须逐一查看。默认并行调查所有可用类别。

发现

在启动调查员之前,先列出 Cursor 环境中可用的 MCP。如果存在可用工具映射,请使用该映射。否则,检查 Cursor 暴露的 mcps/ 目录,查看已启用的 MCP 服务。

将每个可用的 MCP 映射到一个证据类别:

  1. 源代码控制历史
  2. 问题 / 任务跟踪器
  3. 长篇文档
  4. 实时团队聊天
  5. 基础设施可观测性
  6. 错误 / 异常跟踪
  7. 产品分析数据仓库

源代码控制始终可通过 git 和 gh 使用。对于其他六类,请依据 MCP 名称、服务说明、工具名称和资源描述进行分类。如果某个 MCP 可能属于多个类别,请选择与其主要证据相符的类别。请在覆盖映射中记录有歧义的情况。

目标是建立完整的覆盖映射,而不是只列出最低限度的内容。问题跟踪器没有结果,也能证明该决策未通过工单记录,这本身就是有用的信息。请记录这一空结果,不要跳过搜索。

在一条消息中启动所有匹配的调查员,让它们并行运行。每个类别安排一名调查员,便于其专门熟悉一种工具的查询词汇和结果形式。不要让一名 Agent 负责多个 MCP。

子 Agent 配置(每个):

  • subagent_type:generalPurpose
  • model:已配置的 why-investigators 模型(默认 composer-2.5-fast)
  • readonly:false(Agent 模式)。不要使用 readonly/Ask 模式。 该模式会剥夺 MCP 访问权限,导致依赖 MCP 的调查员无法工作。源代码控制调查员使用 readonly 是安全的,但请保持模式统一。调查员仍不应写入任何内容。这是行为准则,不是沙箱。

每名调查员需获得:

  1. references/investigator-prompt.md 中的基础提示词
  2. 所选 MCP 对应的类别手册 references/sources/<source>.md,根据 references/source-playbook.md 中的示例进行调整
  3. 如果目标代码看起来具有防御性(空值检查、重试逻辑、超时处理、速率限制、功能标志、出口防护、OOM 处理),则还需提供跨领域文档 references/sources/incident-postmortem.md
  4. 第 2 步中的代码锚点(文件路径、符号、提交哈希、PR 编号、工单 ID)
  5. 用户的原始问题
调查员名单。每个可用的证据类别安排一名调查员

为每个有匹配 MCP 的类别启动一名调查员。每名调查员只负责一个工具或 MCP。

每个条目都列明该类别实际包含的内容,以及它独有的、可能揭示“原因”的信息。请据此了解预期结果、类别无结果时如何描述信息缺口,以及(仅在少数可明确证明与问题无关的情况下)如何说明跳过理由。各类别的内容都有重叠,但每类都掌握其他类别无法获取的一种证据。

  1. 源代码控制调查员。Git 历史记录、用于 PR 的 gh、代码注释和测试。始终启动;这是唯一有保证可用的信息源。最擅长揭示评审期间记录的实现理由。PR 描述中陈述的问题、讨论替代方案的评审串、记录非显而易见约束的行内注释、体现触发边界情况的测试名称,以及关联工单或事件的提交信息。由于它直接关联最终提交的差异,因此可信度最高。

  2. 问题 / 任务跟踪器调查员(例如 Linear、Jira、GitHub Issues、Plane、Shortcut MCP)。工单、项目文档、状态更新、规格附件。最擅长揭示推动决策的产品或业务因素。客户请求(“Acme 需要 X,以通过其 SOC2 审计”)、合规截止日期、上级计划的背景(“第三季度企业就绪计划”)、工单范围变更,以及用于标记动机的标签(customer:*、incident-followup、compliance、perf-regression)。当原因存在于工程团队之外时,这类证据最有力。

  3. 长篇文档调查工具(例如 Notion、Confluence、Google Docs、Coda MCP)。PRD、规格说明、RFC、设计文档、ADR、事后复盘、团队页面、会议记录。最擅长揭示长篇设计依据:问题陈述、明确列出「考虑过的替代方案」和「被否决的方案」的章节、设定优先级的战略文档、记录最终决策的 ADR,以及与代码直接相关的事后复盘行动项。也就是那些在变成代码之前就写明缘由的内容。

  4. 实时团队聊天调查工具(例如 Slack、Discord、Microsoft Teams、Mattermost MCP)。功能名称和符号搜索、PR URL 提及、事件频道(#sev-*、#incident-*)、上线日期前后作者账号的活动。最擅长揭示从未写进文档的实时讨论:事件期间的紧急决策、PR 作者与评审者之间的问答、随意讨论「我们决定采用 X,因为 Y」的消息串,以及无需 PRD 的小改动背后的依据。当版本控制、工单和文档留下的线索很少时,这尤其重要。

  5. 基础设施可观测性调查工具(例如 Datadog、New Relic、Honeycomb、Grafana、Splunk MCP)。指标、监控器、仪表板、日志、APM 跟踪、正式事件。基础设施和运行时视角。最擅长揭示促使编写这段代码的基础设施与运行时实际情况:数值与代码常量相符的监控阈值、PR 合并前一段时间内的指标峰值、作为事后复盘行动项创建的仪表板,以及提及目标对象的事件时间线。当目标对象会对基础设施信号(超时、重试、速率限制、熔断器)作出反应时,调查效果最佳。

  6. 错误 / 异常跟踪调查工具(例如 Sentry、Rollbar、Bugsnag、Airbrake MCP)。问题、事件、堆栈跟踪、发布记录。最擅长揭示促使编写防御性或纠正性代码的具体异常和错误变化趋势:经过目标函数的堆栈跟踪、首次出现 / 最后出现时间范围涵盖 PR 上线日期的问题,以及显示错误在特定版本停止出现的发布关联。最适用于 catch 代码块、空值保护、类型检查、重试和其他防护逻辑。

  7. 产品分析数据仓库调查工具(例如 Databricks、Snowflake、BigQuery、ClickHouse、dbt、Redshift MCP)。产品分析事件、实验和功能标记曝光表、使用量和计费事件、查询历史、数据仓库遥测。产品和数据视角。它弥补了基础设施可观测性的不足,关注上线日期前后的用户行为和数据实际情况,而非基础设施指标。最擅长揭示影响代码设计的产品和数据实际情况:功能使用趋势(从零开始阶跃式增长,是该 PR 发布此功能的有力证据)、与上线决策相关的实验 / 功能标记曝光数据、揭示阈值常量来源的上线前分布(例如,limit = 128 * 1024 与上传大小列的 p99 相符),以及用于迁移 / 回填的数据管道规模证据。最适用于由功能标记控制的代码、由实验驱动的上线、数据迁移,以及「这个数值是从哪儿来的」之类的问题。

何时跳过调查员

只有在最终的“咨询过的来源”部分给出明确、书面的理由,才能跳过。有效理由有两种:

  • 此环境中没有适用于该类别的 MCP。 将其标记为缺口,而非选择。例如:“跳过实时团队聊天。没有可用的匹配 MCP,因此无法搜索对话记录。”
  • 已证实该来源无关,而不只是“可能无关”。 标准很高。例如:“跳过错误/异常跟踪。目标是构建时脚本,没有运行时代码路径。”不能只说:“功能不太可能出现在错误跟踪中,因为它是个功能,而不是错误。”

“这是纯功能代码,错误跟踪里不会有任何内容”并不足够,“我怀疑长篇文档里不会有这个内容”也不够。执行搜索;让空结果说明问题。调查员返回空结果的代价是一个子 Agent。漏掉一份实际存在的设计文档,则可能导致错误答案。

如果范围评估表明目标只是单个提交中的简单改动,且 PR 描述已经包含完整答案,那么在确认所有七个可用类别的搜索都是多余的之后,你可以直接作答。请明确说明这一点。这种情况应该很少见。

第 4 步:综合

启动一个综合子 Agent:

  • subagent_type:generalPurpose
  • model:你配置的综合分析模型(默认 claude-opus-4-8-thinking-xhigh)
  • readonly:false(Agent 模式)。综合分析 Agent 的质量检查会抽查引用,这可能需要访问 MCP。Readonly/Ask 模式会移除 MCP,导致无法完成这项工作。

综合分析 Agent 会收到:

  1. 调查员的发现,包括任何空结果,以及任何附带理由而跳过的类别
  2. 第 2 步中的代码定位信息(文件路径、符号、提交哈希、PR 编号、工单 ID)
  3. 用户的原始问题
  4. references/epistemics.md 中的认识论框架
  5. references/synthesizer-prompt.md 中的综合分析提示词模板

它的任务是给出最终输出:一篇按置信度加权、附有证据引用的说明,清楚区分“我们知道的内容”和“我们的推断”,并诚实说明缺口和空结果来源。

第 5 步:呈现

将综合分析 Agent 的输出呈现给用户。你可以稍作润色以提升清晰度,或补充对话中的上下文,但不要改写置信度表述。认识论框架正是本流程的核心。为了显得更权威而删去保留措辞,恰恰是这项技能要防止的错误做法。

输出格式

最终输出采用以下结构。可按需调整,但须保留置信度区分。

问题。简洁复述用户的问题。

相关代码。文件路径、行范围和关键符号。用一两行说明,让读者能快速定位。

发现(直接证据)。附上明确引用(PR #、工单 ID、文档 URL、聊天永久链接、提交哈希、带文件名和行号的代码注释)。每条要点都应是有文本证据支持的内容。使用现在时,并引用或转述来源。

合理推断。有间接证据或多项信号共同支持,但未在任何地方明确说明的内容。每条要点都必须说明推断链:“鉴于 A 和 B,很可能 C。”使用审慎措辞(“似乎”“很可能”“表明”)。

其他可能的解释。如果证据支持多种说法,请列出。对每种说法,说明假设、支持证据和反对证据。如果答案明确,则跳过此部分。

尚不明确之处。明确指出信息缺口、证据无法回答的用户问题,以及已搜索但没有结果的来源。具体说明。“我们搜索了问题跟踪系统中的‘rate limit’,未找到讨论这一具体阈值的工单”比“我们不知道原因”更有帮助。

查阅的来源。每位调查者占一行,包括没有找到结果的来源。读者应能一目了然地看出:(a) 查询了哪些 MCP;(b) 哪些没有结果;(c) 哪些被跳过以及原因。这份覆盖范围清单有助于用户判断调查是否充分,并指出可能遗漏的来源。

每行格式如下:- <来源>:<搜索内容>。<发现的内容,或“没有相关结果”,或“已跳过。原因”>。

示例:

  • 源代码管理(git/gh):git log --follow backend/retry.ts、PR #49074、#47812。发现 PR #49074 引入了指数退避机制,并关联 ENG-4421。
  • 问题跟踪系统(Linear):搜索了“retry”和 ENG-4421。发现 ENG-4421 父工单,但没有关于退避参数的讨论。
  • 长篇文档(Notion):搜索了“retry policy”“backend retries”“ENG-4421”。没有相关结果。
  • 实时团队聊天(Slack):已跳过。此环境中没有匹配的 MCP。缺口:未搜索聊天记录。
  • 基础设施可观测性(Datadog):搜索了 retry_count 指标,以及 2024-08-14 前后的监控项。发现监控项“Upstream 5xx rate > 1%”创建于 PR #49074 同一天。
  • 错误/异常跟踪(Sentry):搜索了 2024 年 8 月首次出现且调用栈经过 retry.ts 的问题。发现问题 SENTRY-3821 在 PR 提交前一周激增。
  • 产品分析数据仓库(Databricks):查询了 <your_analytics_db>.<schema>.stg_backend_upstream_retry 在 2024-08-14 前后 30 天的数据。按天统计的失败分类事件数从 PR 前约 1.2k/天降至 PR 后不足 50/天。还检查了 system.query.history 中相关的迁移查询,未发现相关内容。

在“查阅的来源”部分之后,如果用户提出的“为什么”问题是实际修改这段代码的前置问题,请将代码沿革调查结果整理为适合变更规划的 Preserve / Change / Avoid / Risk 约束集。

应避免的常见失误

  • 信口编造。基于微薄证据构建看似合理的叙述。没有引用来源的要点应放在“推断”或“假设”中,而不是“我们的发现”中。
  • 将代码作为证明代码自身意图的证据。“因为检查了 null,所以会处理 null 情况”说的是机制,不是动机。动机应来自外部来源(PR 讨论、工单、注释、对话),否则应标记为推断。
  • 近因偏差。假定最新提交最具权威性。当前形态往往是许多早期决策累积而成的。应追溯其演变过程。
  • 迎合式认同。如果用户提出某个理由(“我猜这是为了提高性能?”),应将其视为假设并独立核查证据,而不是一味附和。
  • 跳过差距部分。如实说明未能查明的内容,本身就是价值所在。
  • 因预判而跳过调查人员。未经搜索就预先认定“长篇文档大概没有这个信息”或“这不是错误跟踪相关的内容”。默认调查全部七类可避免这种情况。没有结果也是一条数据;跳过搜索则会留下盲点。
  • 将多个调查人员合并为一个 Agent。每个 MCP 都有自己的查询词汇、结果形式和陷阱;合并会削弱专业性,也更难评估覆盖范围。每个类别始终安排一名调查人员。

参考文件

  • references/epistemics.md。置信度等级与措辞指南。综合人员必须遵循。
  • references/investigator-prompt.md。调查子 Agent 的基础提示词模板。
  • references/source-playbook.md。指向下方各类别指南的索引。
  • references/sources/*.md。每个类别各有一份独立示例指南,另有跨类别的 incident-postmortem.md。为调查人员提供与其类别对应的单个文件,并根据可用的 MCP 调整。
  • references/synthesizer-prompt.md。综合子 Agent 的提示词模板,其中包含输出格式。

评论

支持 Markdown