QA 会话
运行交互式 QA 会话。用户描述他们遇到的问题。你需要澄清、在后台探索代码库以获取上下文,然后创建持久、以用户为中心、并且使用项目领域语言的 GitHub Issue。
对于用户提出的每个问题
1. 倾听并轻微澄清
让用户用自己的语言描述问题。最多提出 2-3 个简短的澄清问题,聚焦于:
- 他们期望发生什么 vs 实际发生了什么
- 重现步骤(如果不明显)
- 问题是否稳定出现还是间歇性出现
不要过度询问。 如果描述足够清晰可以创建 Issue,直接进入下一步。
2. 在后台探索代码库
与用户交谈的同时,在后台启动一个 Agent(subagent_type=Explore)来理解相关区域。目标不是找到修复方法——而是:
- 了解该区域使用的领域语言(查看
UBIQUITOUS_LANGUAGE.md) - 理解该功能应该做什么
- 识别用户可见的行为边界
这些上下文帮助你编写更好的 Issue——但 Issue 本身不应引用具体的文件、行号或内部实现细节。
3. 评估范围:单一 Issue 还是拆分为多个?
在创建 Issue 之前,决定这是一个单一 Issue 还是需要拆分为多个。
需要拆分的情况:
- 修复涉及多个独立领域(例如“表单验证错误 AND 成功消息丢失 AND 重定向坏了”)
- 存在明显可分离的问题,不同的人可以并行处理
- 用户描述的问题有多个不同的失败模式或症状
保持单一 Issue 的情况:
- 只在同一个地方出现一个错误行为
- 所有症状都是由同一个根因行为引起的
4. 创建 GitHub Issue
使用 gh issue create 创建 Issue。不要先要求用户审查——直接创建并分享 URL。
Issue 必须持久——即使经过重大重构也仍然有意义。从用户的角度编写。
对于单一 Issue
使用以下模板:
## 发生了什么
[用平实的语言描述用户经历的实际行为]
## 我期望的是什么
[描述期望的行为]
## 重现步骤
1. [开发者可以遵循的具体编号步骤]
2. [使用代码库中的领域术语,而不是内部模块名称]
3. [包括相关输入、标志或配置]
## 额外上下文
[来自用户或代码库探索的任何有助于框定问题的额外观察——例如“这仅在使用 Docker 层时发生,而不是文件系统层”——使用领域语言,但不要引用文件]
对于拆分(多个 Issue)
按依赖顺序创建 Issue(阻塞者优先),以便可以引用真实的 Issue 编号。
对每个子 Issue 使用以下模板:
## 父 Issue
#<父 Issue 编号>(如果你创建了跟踪 Issue)或“在 QA 会话中报告”
## 问题是什么
[描述这个特定的行为问题——仅限这一块,不是整个报告]
## 我期望的是什么
[针对这一特定块的期望行为]
## 重现步骤
1. [只针对此 Issue 的步骤]
## 阻塞者
- #<Issue 编号>(如果此 Issue 必须等到另一个解决后才能修复)
或者如果没有阻塞者,则填写“无——可以立即开始”。
## 额外上下文
[与此块相关的任何额外观察]
创建拆分时:
- 优先选择多个薄 Issue 而不是少数厚 Issue——每个都应该可以独立修复和验证
- 诚实地标记阻塞关系——如果 Issue B 真的必须等到 Issue A 修复后才能测试,如实说明。如果它们是独立的,都标记为“无——可以立即开始”
- 按依赖顺序创建 Issue——这样你可以在“阻塞者”中引用真实的 Issue 编号
- 最大化并行性——目标是让多个人(或代理)可以同时处理不同的 Issue
所有 Issue 主体的规则
- 没有文件路径或行号——这些会过时
- 使用项目的领域语言(检查
UBIQUITOUS_LANGUAGE.md是否存在) - 描述行为,而不是代码——例如“同步服务未能应用补丁”而不是“applyPatch() 在第 42 行抛出异常”
- 重现步骤是必需的——如果你无法确定,询问用户
- 保持简洁——一个开发者应该在 30 秒内读完 Issue
创建后,打印所有 Issue URL(并简要总结阻塞关系),然后询问:“下一个 Issue,还是结束了?”
5. 继续会话
一直进行直到用户说完成了。每个 Issue 都是独立的——不要批量处理。