<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Claude Docs Blog</title>
        <link>https://luuman.github.io/claude-doc/blog</link>
        <description>Claude Docs Blog</description>
        <lastBuildDate>Sun, 15 Feb 2026 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>zh</language>
        <item>
            <title><![CDATA[案例 5：CI/CD 集成与自动 PR 审查]]></title>
            <link>https://luuman.github.io/claude-doc/blog/cicd-integration</link>
            <guid>https://luuman.github.io/claude-doc/blog/cicd-integration</guid>
            <pubDate>Sun, 15 Feb 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[在 GitHub Actions 中集成 Claude Code，每次 PR 自动触发 AI 审查并发布评论]]></description>
            <content:encoded><![CDATA[<p><strong>场景：</strong> 希望每次提交 PR 时自动获得 AI 审查意见，无需人工触发，审查结果直接作为 PR 评论发布。团队 review 周期从平均 4 小时缩短至 30 分钟。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="核心思路">核心思路<a href="https://luuman.github.io/claude-doc/blog/cicd-integration#%E6%A0%B8%E5%BF%83%E6%80%9D%E8%B7%AF" class="hash-link" aria-label="核心思路的直接链接" title="核心思路的直接链接" translate="no">​</a></h2>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">PR 提交</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  → GitHub Actions 触发</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    → Claude Code（Headless 模式）分析 diff</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      → 输出审查报告</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        → 自动发布为 PR 评论</span><br></span></code></pre></div></div>
<p>Claude Code 的 <code>-p</code> 参数（Headless 模式）是实现这一流程的关键——它让 Claude Code 脱离交互界面，以命令行工具的形式在 CI 环境中运行。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="快速接入5-分钟配置">快速接入：5 分钟配置<a href="https://luuman.github.io/claude-doc/blog/cicd-integration#%E5%BF%AB%E9%80%9F%E6%8E%A5%E5%85%A55-%E5%88%86%E9%92%9F%E9%85%8D%E7%BD%AE" class="hash-link" aria-label="快速接入：5 分钟配置的直接链接" title="快速接入：5 分钟配置的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="第-1-步添加-api-key-到-github-secrets">第 1 步：添加 API Key 到 GitHub Secrets<a href="https://luuman.github.io/claude-doc/blog/cicd-integration#%E7%AC%AC-1-%E6%AD%A5%E6%B7%BB%E5%8A%A0-api-key-%E5%88%B0-github-secrets" class="hash-link" aria-label="第 1 步：添加 API Key 到 GitHub Secrets的直接链接" title="第 1 步：添加 API Key 到 GitHub Secrets的直接链接" translate="no">​</a></h3>
<p>在 GitHub 仓库 Settings → Secrets and variables → Actions 中添加：</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">ANTHROPIC_API_KEY = sk-ant-xxxxxxxxxxxxxxxx</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="第-2-步创建工作流文件">第 2 步：创建工作流文件<a href="https://luuman.github.io/claude-doc/blog/cicd-integration#%E7%AC%AC-2-%E6%AD%A5%E5%88%9B%E5%BB%BA%E5%B7%A5%E4%BD%9C%E6%B5%81%E6%96%87%E4%BB%B6" class="hash-link" aria-label="第 2 步：创建工作流文件的直接链接" title="第 2 步：创建工作流文件的直接链接" translate="no">​</a></h3>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockTitle_OeMC">.github/workflows/claude-review.yml</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token key atrule" style="color:#C792EA">name</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> Claude Code Review</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token key atrule" style="color:#C792EA">on</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token key atrule" style="color:#C792EA">pull_request</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token key atrule" style="color:#C792EA">types</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">[</span><span class="token plain">opened</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> synchronize</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> reopened</span><span class="token punctuation" style="color:#C792EA">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token key atrule" style="color:#C792EA">paths</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">'src/**'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">'tests/**'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token key atrule" style="color:#C792EA">jobs</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token key atrule" style="color:#C792EA">review</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token key atrule" style="color:#C792EA">runs-on</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> ubuntu</span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain">latest</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token key atrule" style="color:#C792EA">permissions</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token key atrule" style="color:#C792EA">contents</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> read</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token key atrule" style="color:#C792EA">pull-requests</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> write</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token key atrule" style="color:#C792EA">steps</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#C792EA">uses</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> actions/checkout@v4</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        </span><span class="token key atrule" style="color:#C792EA">with</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          </span><span class="token key atrule" style="color:#C792EA">fetch-depth</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> </span><span class="token number" style="color:#F78C6C">0</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#C792EA">uses</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> actions/setup</span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain">node@v4</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        </span><span class="token key atrule" style="color:#C792EA">with</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          </span><span class="token key atrule" style="color:#C792EA">node-version</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">'20'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#C792EA">name</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> 安装 Claude Code</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        </span><span class="token key atrule" style="color:#C792EA">run</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> npm install </span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain">g @anthropic</span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain">ai/claude</span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain">code</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#C792EA">name</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> 生成 PR Diff</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        </span><span class="token key atrule" style="color:#C792EA">id</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> diff</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        </span><span class="token key atrule" style="color:#C792EA">run</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">|</span><span class="token scalar string" style="color:#ECC48D"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">          git diff origin/${{ github.base_ref }}...HEAD \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">            -- '*.ts' '*.tsx' '*.js' '*.py' \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">            &gt; /tmp/pr-diff.txt</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">          echo "lines=$(wc -l &lt; /tmp/pr-diff.txt)" &gt;&gt; $GITHUB_OUTPUT</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#C792EA">name</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> Claude 代码审查</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        </span><span class="token key atrule" style="color:#C792EA">env</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          </span><span class="token key atrule" style="color:#C792EA">ANTHROPIC_API_KEY</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> $</span><span class="token punctuation" style="color:#C792EA">{</span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"> secrets.ANTHROPIC_API_KEY </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token punctuation" style="color:#C792EA">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        </span><span class="token key atrule" style="color:#C792EA">run</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">|</span><span class="token scalar string" style="color:#ECC48D"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">          REVIEW=$(cat /tmp/pr-diff.txt | claude -p "</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">          请对以下代码变更进行专业审查，用中文输出，格式如下：</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          </span><span class="token comment" style="color:#637777;font-style:italic">## 总体评价</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          </span><span class="token punctuation" style="color:#C792EA">[</span><span class="token plain">简短总结，说明本次变更的质量</span><span class="token punctuation" style="color:#C792EA">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          </span><span class="token comment" style="color:#637777;font-style:italic">## 发现的问题</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          </span><span class="token punctuation" style="color:#C792EA">[</span><span class="token plain">列出 Bug、安全漏洞、性能问题，标注严重程度</span><span class="token punctuation" style="color:#C792EA">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          </span><span class="token comment" style="color:#637777;font-style:italic">## 改进建议</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          </span><span class="token punctuation" style="color:#C792EA">[</span><span class="token plain">具体可操作的优化建议</span><span class="token punctuation" style="color:#C792EA">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          </span><span class="token comment" style="color:#637777;font-style:italic">## 值得肯定的地方</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          </span><span class="token punctuation" style="color:#C792EA">[</span><span class="token plain">优秀的实践值得表扬</span><span class="token punctuation" style="color:#C792EA">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          " </span><span class="token punctuation" style="color:#C792EA">-</span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain">dangerously</span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain">skip</span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain">permissions 2</span><span class="token punctuation" style="color:#C792EA">&gt;</span><span class="token plain">/dev/null)</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          </span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">            echo 'REVIEW&lt;&lt;REVIEW_EOF'</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">            echo "$REVIEW"</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">            echo 'REVIEW_EOF'</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">&gt;</span><span class="token punctuation" style="color:#C792EA">&gt;</span><span class="token plain"> $GITHUB_ENV</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#C792EA">name</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> 发布 PR 评论</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        </span><span class="token key atrule" style="color:#C792EA">uses</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> actions/github</span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain">script@v7</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        </span><span class="token key atrule" style="color:#C792EA">with</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          </span><span class="token key atrule" style="color:#C792EA">github-token</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> $</span><span class="token punctuation" style="color:#C792EA">{</span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"> secrets.GITHUB_TOKEN </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token punctuation" style="color:#C792EA">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          </span><span class="token key atrule" style="color:#C792EA">script</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">|</span><span class="token scalar string" style="color:#ECC48D"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">            const review = process.env.REVIEW;</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">            await github.rest.issues.createComment({</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">              owner: context.repo.owner,</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">              repo: context.repo.repo,</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">              issue_number: context.issue.number,</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">              body: `## 🤖 Claude Code 自动审查\n\n${review}\n\n---\n*审查范围：${{ steps.diff.outputs.lines }} 行变更 · ${new Date().toISOString()}*`</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">            });</span><br></span></code></pre></div></div>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="进阶配置">进阶配置<a href="https://luuman.github.io/claude-doc/blog/cicd-integration#%E8%BF%9B%E9%98%B6%E9%85%8D%E7%BD%AE" class="hash-link" aria-label="进阶配置的直接链接" title="进阶配置的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="安全门禁检测高危问题自动拦截">安全门禁：检测高危问题自动拦截<a href="https://luuman.github.io/claude-doc/blog/cicd-integration#%E5%AE%89%E5%85%A8%E9%97%A8%E7%A6%81%E6%A3%80%E6%B5%8B%E9%AB%98%E5%8D%B1%E9%97%AE%E9%A2%98%E8%87%AA%E5%8A%A8%E6%8B%A6%E6%88%AA" class="hash-link" aria-label="安全门禁：检测高危问题自动拦截的直接链接" title="安全门禁：检测高危问题自动拦截的直接链接" translate="no">​</a></h3>
<p>在工作流中添加安全检查步骤，发现高危问题时阻止 PR 合并：</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#C792EA">name</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> 安全扫描（高危问题自动拦截）</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        </span><span class="token key atrule" style="color:#C792EA">env</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          </span><span class="token key atrule" style="color:#C792EA">ANTHROPIC_API_KEY</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> $</span><span class="token punctuation" style="color:#C792EA">{</span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"> secrets.ANTHROPIC_API_KEY </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token punctuation" style="color:#C792EA">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        </span><span class="token key atrule" style="color:#C792EA">run</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">|</span><span class="token scalar string" style="color:#ECC48D"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">          SECURITY_RESULT=$(cat /tmp/pr-diff.txt | claude -p "</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">          专注于安全角度审查以下代码变更：</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">          1. SQL 注入</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">          2. XSS 漏洞</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">          3. 硬编码密钥或密码</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">          4. 权限控制缺失</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">          5. 不安全的反序列化</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          如果发现任何高危漏洞，在输出开头加上 </span><span class="token punctuation" style="color:#C792EA">[</span><span class="token plain">SECURITY_BLOCK</span><span class="token punctuation" style="color:#C792EA">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          " </span><span class="token punctuation" style="color:#C792EA">-</span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain">dangerously</span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain">skip</span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain">permissions 2</span><span class="token punctuation" style="color:#C792EA">&gt;</span><span class="token plain">/dev/null)</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          if echo "$SECURITY_RESULT" </span><span class="token punctuation" style="color:#C792EA">|</span><span class="token plain"> grep </span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain">q "\</span><span class="token punctuation" style="color:#C792EA">[</span><span class="token plain">SECURITY_BLOCK\</span><span class="token punctuation" style="color:#C792EA">]</span><span class="token plain">"; then</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">            echo "❌ 检测到高危安全漏洞，PR 被拦截"</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">            echo "$SECURITY_RESULT"</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">            exit 1  </span><span class="token comment" style="color:#637777;font-style:italic"># 非零退出码使 CI 失败</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          fi</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          echo "✅ 安全检查通过"</span><br></span></code></pre></div></div>
<p>在 Branch Protection Rules 中将此 Job 设为 Required Status Check，PR 有高危漏洞时无法合并。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="结构化-json-输出便于解析">结构化 JSON 输出（便于解析）<a href="https://luuman.github.io/claude-doc/blog/cicd-integration#%E7%BB%93%E6%9E%84%E5%8C%96-json-%E8%BE%93%E5%87%BA%E4%BE%BF%E4%BA%8E%E8%A7%A3%E6%9E%90" class="hash-link" aria-label="结构化 JSON 输出（便于解析）的直接链接" title="结构化 JSON 输出（便于解析）的直接链接" translate="no">​</a></h3>
<p>对于需要进一步处理审查结果的场景，使用 <code>--output-format stream-json</code>：</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#C792EA">name</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> 结构化审查（供其他工具消费）</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        </span><span class="token key atrule" style="color:#C792EA">env</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          </span><span class="token key atrule" style="color:#C792EA">ANTHROPIC_API_KEY</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> $</span><span class="token punctuation" style="color:#C792EA">{</span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"> secrets.ANTHROPIC_API_KEY </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token punctuation" style="color:#C792EA">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        </span><span class="token key atrule" style="color:#C792EA">run</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">|</span><span class="token scalar string" style="color:#ECC48D"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">          cat /tmp/pr-diff.txt | claude -p "</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">          审查代码，输出 JSON 格式：</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">          {</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">            \"score\": 1-10,</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">            \"issues\": [{\"severity\": \"high|medium|low\", \"file\": \"...\", \"description\": \"...\"}],</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">            \"summary\": \"...\"</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">          }</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">          只输出 JSON，不要其他内容</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">          " --dangerously-skip-permissions \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">            --output-format stream-json | \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">          jq -r 'select(.type=="text") | .content' &gt; /tmp/review.json</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          </span><span class="token comment" style="color:#637777;font-style:italic"># 可以进一步处理 JSON，例如创建 GitHub Check 注释</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          cat /tmp/review.json</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="增量审查只审查新变更">增量审查（只审查新变更）<a href="https://luuman.github.io/claude-doc/blog/cicd-integration#%E5%A2%9E%E9%87%8F%E5%AE%A1%E6%9F%A5%E5%8F%AA%E5%AE%A1%E6%9F%A5%E6%96%B0%E5%8F%98%E6%9B%B4" class="hash-link" aria-label="增量审查（只审查新变更）的直接链接" title="增量审查（只审查新变更）的直接链接" translate="no">​</a></h3>
<p>避免每次审查整个 PR，只审查新增的提交：</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#C792EA">name</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> 增量 Diff（只看新提交）</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        </span><span class="token key atrule" style="color:#C792EA">run</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">|</span><span class="token scalar string" style="color:#ECC48D"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">          # 获取最新 commit 的变更，而非整个 PR 的 diff</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">          git diff HEAD~1...HEAD \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">            -- '*.ts' '*.py' \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">            &gt; /tmp/incremental-diff.txt</span><br></span></code></pre></div></div>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="gitlab-ci-接入">GitLab CI 接入<a href="https://luuman.github.io/claude-doc/blog/cicd-integration#gitlab-ci-%E6%8E%A5%E5%85%A5" class="hash-link" aria-label="GitLab CI 接入的直接链接" title="GitLab CI 接入的直接链接" translate="no">​</a></h2>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockTitle_OeMC">.gitlab-ci.yml</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token key atrule" style="color:#C792EA">claude-review</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token key atrule" style="color:#C792EA">stage</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> test</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token key atrule" style="color:#C792EA">image</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> node</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain">20</span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain">alpine</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token key atrule" style="color:#C792EA">only</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain"> merge_requests</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token key atrule" style="color:#C792EA">script</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain"> npm install </span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain">g @anthropic</span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain">ai/claude</span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain">code</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain"> git diff $CI_MERGE_REQUEST_DIFF_BASE_SHA</span><span class="token punctuation" style="color:#C792EA">...</span><span class="token plain">HEAD </span><span class="token punctuation" style="color:#C792EA">&gt;</span><span class="token plain"> /tmp/diff.txt</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">|</span><span class="token scalar string" style="color:#ECC48D"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">      cat /tmp/diff.txt | claude -p "进行代码审查，用中文输出 Markdown 格式报告" \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token scalar string" style="color:#ECC48D">        --dangerously-skip-permissions &gt; review.md</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain"> cat review.md</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token key atrule" style="color:#C792EA">artifacts</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token key atrule" style="color:#C792EA">paths</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token punctuation" style="color:#C792EA">-</span><span class="token plain"> review.md</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token key atrule" style="color:#C792EA">expire_in</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> 1 week</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token key atrule" style="color:#C792EA">variables</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token key atrule" style="color:#C792EA">ANTHROPIC_API_KEY</span><span class="token punctuation" style="color:#C792EA">:</span><span class="token plain"> $ANTHROPIC_API_KEY  </span><span class="token comment" style="color:#637777;font-style:italic"># 在 GitLab CI/CD Variables 中配置</span><br></span></code></pre></div></div>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="实际效果">实际效果<a href="https://luuman.github.io/claude-doc/blog/cicd-integration#%E5%AE%9E%E9%99%85%E6%95%88%E6%9E%9C" class="hash-link" aria-label="实际效果的直接链接" title="实际效果的直接链接" translate="no">​</a></h2>
<p>发布到 PR 的审查评论示例：</p>
<div class="language-markdown codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-markdown codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token title important punctuation" style="color:#C792EA">##</span><span class="token title important" style="color:#D6DEEB"> 🤖 Claude Code 自动审查</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token title important punctuation" style="color:#C792EA">##</span><span class="token title important" style="color:#D6DEEB"> 总体评价</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">本次 PR 实现了 JWT 刷新机制，整体逻辑清晰，但存在一个中等风险的安全问题需要处理。</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token title important punctuation" style="color:#C792EA">##</span><span class="token title important" style="color:#D6DEEB"> 发现的问题</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token bold punctuation" style="color:#C792EA">**</span><span class="token bold content">[Medium] 安全</span><span class="token bold punctuation" style="color:#C792EA">**</span><span class="token plain"> </span><span class="token code-snippet code keyword" style="color:#C792EA">`src/auth/AuthService.ts:89`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">JWT 验证时未检查 </span><span class="token code-snippet code keyword" style="color:#C792EA">`exp`</span><span class="token plain">（过期时间）字段，过期的 token 可能仍被接受。</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">建议：在第 89 行添加 </span><span class="token code-snippet code keyword" style="color:#C792EA">`if (payload.exp &lt; Date.now() / 1000) throw new Error('Token expired')`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token bold punctuation" style="color:#C792EA">**</span><span class="token bold content">[Low] 质量</span><span class="token bold punctuation" style="color:#C792EA">**</span><span class="token plain"> </span><span class="token code-snippet code keyword" style="color:#C792EA">`src/auth/routes.ts:45`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token code-snippet code keyword" style="color:#C792EA">`refreshToken`</span><span class="token plain"> 函数返回 </span><span class="token code-snippet code keyword" style="color:#C792EA">`any`</span><span class="token plain"> 类型，影响类型安全。</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token title important punctuation" style="color:#C792EA">##</span><span class="token title important" style="color:#D6DEEB"> 改进建议</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">1.</span><span class="token plain"> 添加 token 过期检查（必须）</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">2.</span><span class="token plain"> 将 refreshToken 返回类型改为 </span><span class="token code-snippet code keyword" style="color:#C792EA">`Promise&lt;TokenPair&gt;`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">3.</span><span class="token plain"> 考虑将刷新逻辑提取为 </span><span class="token code-snippet code keyword" style="color:#C792EA">`TokenRefreshService`</span><span class="token plain">，降低 AuthService 的职责</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token title important punctuation" style="color:#C792EA">##</span><span class="token title important" style="color:#D6DEEB"> 值得肯定的地方</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> 刷新逻辑与认证逻辑分离得很好</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> 错误处理覆盖了主要边界情况</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> 测试覆盖了 happy path 和异常情况</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token hr punctuation" style="color:#C792EA">---</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token italic punctuation" style="color:#C792EA">*</span><span class="token italic content">审查范围：147 行变更 · 2025-02-18T14:30:00Z</span><span class="token italic punctuation" style="color:#C792EA">*</span><br></span></code></pre></div></div>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="关键参数说明">关键参数说明<a href="https://luuman.github.io/claude-doc/blog/cicd-integration#%E5%85%B3%E9%94%AE%E5%8F%82%E6%95%B0%E8%AF%B4%E6%98%8E" class="hash-link" aria-label="关键参数说明的直接链接" title="关键参数说明的直接链接" translate="no">​</a></h2>

























<table><thead><tr><th>参数</th><th>用途</th></tr></thead><tbody><tr><td><code>-p "提示词"</code></td><td>Headless 模式，非交互式执行</td></tr><tr><td><code>--dangerously-skip-permissions</code></td><td>CI 环境必须，跳过交互式权限确认</td></tr><tr><td><code>--output-format stream-json</code></td><td>结构化输出，便于脚本解析</td></tr><tr><td><code>--max-turns 5</code></td><td>限制最大循环次数，防止 CI 超时</td></tr></tbody></table>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>关于成本</div><div class="admonitionContent_BuS1"><p>每次 PR 审查大约消耗 500-2000 个 token（取决于 diff 大小），使用 claude-sonnet-4-6 大约花费 $0.005-0.02，远低于人工 review 的时间成本。可以通过 <code>head -n 500 /tmp/pr-diff.txt</code> 截断超大 diff 控制成本。</p></div></div>]]></content:encoded>
            <category>Claude Code</category>
            <category>教程</category>
            <category>自动化</category>
            <category>并行开发</category>
        </item>
        <item>
            <title><![CDATA[案例 4：自动化测试生成]]></title>
            <link>https://luuman.github.io/claude-doc/blog/test-generation</link>
            <guid>https://luuman.github.io/claude-doc/blog/test-generation</guid>
            <pubDate>Thu, 12 Feb 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[配置自修复 Agent 为遗留代码库自动补全测试，直到覆盖率达标]]></description>
            <content:encoded><![CDATA[<p><strong>场景：</strong> 历史遗留代码库缺乏测试，覆盖率不足 20%。重构前需要补全关键路径的测试，但手写测试耗时巨大。目标：用 Claude Code 自动生成测试，并自动运行、自动修复失败，直到覆盖率达标。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="执行流程">执行流程<a href="https://luuman.github.io/claude-doc/blog/test-generation#%E6%89%A7%E8%A1%8C%E6%B5%81%E7%A8%8B" class="hash-link" aria-label="执行流程的直接链接" title="执行流程的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="第-1-步扫描需要补测试的文件">第 1 步：扫描需要补测试的文件<a href="https://luuman.github.io/claude-doc/blog/test-generation#%E7%AC%AC-1-%E6%AD%A5%E6%89%AB%E6%8F%8F%E9%9C%80%E8%A6%81%E8%A1%A5%E6%B5%8B%E8%AF%95%E7%9A%84%E6%96%87%E4%BB%B6" class="hash-link" aria-label="第 1 步：扫描需要补测试的文件的直接链接" title="第 1 步：扫描需要补测试的文件的直接链接" translate="no">​</a></h3>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">扫描 src/services/ 目录，找出所有没有对应测试文件的源码文件，</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">列出它们的函数数量和代码行数，按"函数数量多"到"函数数量少"排序</span><br></span></code></pre></div></div>
<p>Claude Code 分析后输出：</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">找到以下文件缺少测试覆盖：</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">文件                              行数    函数数    优先级</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">src/services/OrderService.ts      342     18       🔴 高</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">src/services/PaymentService.ts    289     14       🔴 高</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">src/services/UserService.ts       156     9        🟡 中</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">src/services/NotificationService  98      5        🟢 低</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">建议从 OrderService.ts 开始，它是核心业务逻辑且函数最多。</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="第-2-步触发自动测试生成">第 2 步：触发自动测试生成<a href="https://luuman.github.io/claude-doc/blog/test-generation#%E7%AC%AC-2-%E6%AD%A5%E8%A7%A6%E5%8F%91%E8%87%AA%E5%8A%A8%E6%B5%8B%E8%AF%95%E7%94%9F%E6%88%90" class="hash-link" aria-label="第 2 步：触发自动测试生成的直接链接" title="第 2 步：触发自动测试生成的直接链接" translate="no">​</a></h3>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">使用 test-writer agent 为 src/services/OrderService.ts 生成完整测试，</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">要求单元测试覆盖率达到 85% 以上，所有测试必须通过才算完成</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="第-3-步agent-自动运行自修复循环">第 3 步：Agent 自动运行（自修复循环）<a href="https://luuman.github.io/claude-doc/blog/test-generation#%E7%AC%AC-3-%E6%AD%A5agent-%E8%87%AA%E5%8A%A8%E8%BF%90%E8%A1%8C%E8%87%AA%E4%BF%AE%E5%A4%8D%E5%BE%AA%E7%8E%AF" class="hash-link" aria-label="第 3 步：Agent 自动运行（自修复循环）的直接链接" title="第 3 步：Agent 自动运行（自修复循环）的直接链接" translate="no">​</a></h3>
<p>Agent 自动执行以下循环：</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">[循环 1]</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">✓ 读取 OrderService.ts（342 行，18 个公共方法）</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">✓ 检测到使用 Jest 测试框架</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">✓ 生成初始测试文件：__tests__/OrderService.test.ts（89 个测试用例）</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">✗ 运行测试：12 个失败</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">失败原因分析：</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">- createOrder 测试：Mock 的 database.save 返回值格式不对</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">- calculateDiscount 测试：边界值计算有误</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">- cancelOrder 测试：缺少对 status 字段的 Mock</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">[自动修复中...]</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">✓ 修正 Mock 返回值格式</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">✓ 修正边界值计算（0.00 → 0）</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">✓ 添加 status 字段 Mock</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">[循环 2]</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">✗ 运行测试：3 个失败（原有 12 个减少到 3 个）</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">失败原因分析：</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">- sendNotification 在 cancelOrder 中被调用，但 Mock 未配置</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">[自动修复中...]</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">✓ 在测试前添加 jest.spyOn(NotificationService, 'send').mockResolvedValue(undefined)</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">[循环 3]</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">✓ 运行测试：89/89 全部通过 ✅</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">覆盖率报告：</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">- 语句覆盖率：92.3%</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">- 分支覆盖率：87.6%</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">- 函数覆盖率：100%</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">- 行覆盖率：91.8%</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">✅ 目标达成（要求 85%，实际 92.3%）</span><br></span></code></pre></div></div>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="实际生成的测试示例">实际生成的测试示例<a href="https://luuman.github.io/claude-doc/blog/test-generation#%E5%AE%9E%E9%99%85%E7%94%9F%E6%88%90%E7%9A%84%E6%B5%8B%E8%AF%95%E7%A4%BA%E4%BE%8B" class="hash-link" aria-label="实际生成的测试示例的直接链接" title="实际生成的测试示例的直接链接" translate="no">​</a></h2>
<p>以下是 Agent 为 <code>OrderService.createOrder</code> 生成的测试：</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token comment" style="color:#637777;font-style:italic">// __tests__/services/OrderService.test.ts（由 Claude Code 自动生成）</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token keyword" style="color:#C792EA">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"> OrderService </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C792EA">from</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">'../../src/services/OrderService'</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token keyword" style="color:#C792EA">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"> Database </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C792EA">from</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">'../../src/db/Database'</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token keyword" style="color:#C792EA">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"> NotificationService </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C792EA">from</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">'../../src/services/NotificationService'</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token keyword" style="color:#C792EA">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"> OrderStatus</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> PaymentMethod </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C792EA">from</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">'../../src/types/order'</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">jest</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token function" style="color:#82AAFF">mock</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token string" style="color:#ECC48D">'../../src/db/Database'</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">jest</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token function" style="color:#82AAFF">mock</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token string" style="color:#ECC48D">'../../src/services/NotificationService'</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token keyword" style="color:#C792EA">const</span><span class="token plain"> MockedDatabase </span><span class="token operator" style="color:#7FDBCA">=</span><span class="token plain"> Database </span><span class="token keyword" style="color:#C792EA">as</span><span class="token plain"> jest</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token plain">MockedClass</span><span class="token operator" style="color:#7FDBCA">&lt;</span><span class="token keyword" style="color:#C792EA">typeof</span><span class="token plain"> Database</span><span class="token operator" style="color:#7FDBCA">&gt;</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token function" style="color:#82AAFF">describe</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token string" style="color:#ECC48D">'OrderService'</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">(</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token plain"> </span><span class="token operator" style="color:#7FDBCA">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token keyword" style="color:#C792EA">let</span><span class="token plain"> orderService</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> OrderService</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token keyword" style="color:#C792EA">let</span><span class="token plain"> mockDb</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> jest</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token plain">Mocked</span><span class="token operator" style="color:#7FDBCA">&lt;</span><span class="token plain">Database</span><span class="token operator" style="color:#7FDBCA">&gt;</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token function" style="color:#82AAFF">beforeEach</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token plain"> </span><span class="token operator" style="color:#7FDBCA">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    jest</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token function" style="color:#82AAFF">clearAllMocks</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    mockDb </span><span class="token operator" style="color:#7FDBCA">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C792EA">new</span><span class="token plain"> </span><span class="token class-name" style="color:#82AAFF">MockedDatabase</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token plain"> </span><span class="token keyword" style="color:#C792EA">as</span><span class="token plain"> jest</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token plain">Mocked</span><span class="token operator" style="color:#7FDBCA">&lt;</span><span class="token plain">Database</span><span class="token operator" style="color:#7FDBCA">&gt;</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    orderService </span><span class="token operator" style="color:#7FDBCA">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C792EA">new</span><span class="token plain"> </span><span class="token class-name" style="color:#82AAFF">OrderService</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token plain">mockDb</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token function" style="color:#82AAFF">describe</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token string" style="color:#ECC48D">'createOrder'</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">(</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token plain"> </span><span class="token operator" style="color:#7FDBCA">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token keyword" style="color:#C792EA">const</span><span class="token plain"> validOrderData </span><span class="token operator" style="color:#7FDBCA">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      userId</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">'user-123'</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      items</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">[</span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"> productId</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">'prod-1'</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> quantity</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token number" style="color:#F78C6C">2</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> price</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token number" style="color:#F78C6C">50</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token punctuation" style="color:#C792EA">]</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      paymentMethod</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> PaymentMethod</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token constant" style="color:#F78C6C">CREDIT_CARD</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token function" style="color:#82AAFF">it</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token string" style="color:#ECC48D">'should create order successfully with valid data'</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> </span><span class="token keyword" style="color:#C792EA">async</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">(</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token plain"> </span><span class="token operator" style="color:#7FDBCA">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token keyword" style="color:#C792EA">const</span><span class="token plain"> savedOrder </span><span class="token operator" style="color:#7FDBCA">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"> id</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">'order-456'</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> </span><span class="token operator" style="color:#7FDBCA">...</span><span class="token plain">validOrderData</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> status</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> OrderStatus</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token constant" style="color:#F78C6C">PENDING</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      mockDb</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token plain">save</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token function" style="color:#82AAFF">mockResolvedValue</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token plain">savedOrder</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token keyword" style="color:#C792EA">const</span><span class="token plain"> result </span><span class="token operator" style="color:#7FDBCA">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C792EA">await</span><span class="token plain"> orderService</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token function" style="color:#82AAFF">createOrder</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token plain">validOrderData</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token function" style="color:#82AAFF">expect</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token plain">result</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token plain">id</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token function" style="color:#82AAFF">toBe</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token string" style="color:#ECC48D">'order-456'</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token function" style="color:#82AAFF">expect</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token plain">result</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token plain">status</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token function" style="color:#82AAFF">toBe</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token plain">OrderStatus</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token constant" style="color:#F78C6C">PENDING</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token function" style="color:#82AAFF">expect</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token plain">mockDb</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token plain">save</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token function" style="color:#82AAFF">toHaveBeenCalledWith</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        expect</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token function" style="color:#82AAFF">objectContaining</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"> userId</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">'user-123'</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token punctuation" style="color:#C792EA">)</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token function" style="color:#82AAFF">it</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token string" style="color:#ECC48D">'should throw error when order has no items'</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> </span><span class="token keyword" style="color:#C792EA">async</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">(</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token plain"> </span><span class="token operator" style="color:#7FDBCA">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token keyword" style="color:#C792EA">const</span><span class="token plain"> emptyOrder </span><span class="token operator" style="color:#7FDBCA">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"> </span><span class="token operator" style="color:#7FDBCA">...</span><span class="token plain">validOrderData</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> items</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">[</span><span class="token punctuation" style="color:#C792EA">]</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token keyword" style="color:#C792EA">await</span><span class="token plain"> </span><span class="token function" style="color:#82AAFF">expect</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token plain">orderService</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token function" style="color:#82AAFF">createOrder</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token plain">emptyOrder</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        </span><span class="token punctuation" style="color:#C792EA">.</span><span class="token plain">rejects</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token function" style="color:#82AAFF">toThrow</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token string" style="color:#ECC48D">'Order must contain at least one item'</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token function" style="color:#82AAFF">it</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token string" style="color:#ECC48D">'should calculate total price correctly'</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> </span><span class="token keyword" style="color:#C792EA">async</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">(</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token plain"> </span><span class="token operator" style="color:#7FDBCA">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token keyword" style="color:#C792EA">const</span><span class="token plain"> multiItemOrder </span><span class="token operator" style="color:#7FDBCA">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        </span><span class="token operator" style="color:#7FDBCA">...</span><span class="token plain">validOrderData</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        items</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          </span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"> productId</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">'prod-1'</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> quantity</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token number" style="color:#F78C6C">2</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> price</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token number" style="color:#F78C6C">50</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">          </span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"> productId</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">'prod-2'</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> quantity</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token number" style="color:#F78C6C">1</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> price</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token number" style="color:#F78C6C">30</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        </span><span class="token punctuation" style="color:#C792EA">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      mockDb</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token plain">save</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token function" style="color:#82AAFF">mockResolvedValue</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"> id</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">'order-789'</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> </span><span class="token operator" style="color:#7FDBCA">...</span><span class="token plain">multiItemOrder</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> total</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token number" style="color:#F78C6C">130</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token keyword" style="color:#C792EA">const</span><span class="token plain"> result </span><span class="token operator" style="color:#7FDBCA">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C792EA">await</span><span class="token plain"> orderService</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token function" style="color:#82AAFF">createOrder</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token plain">multiItemOrder</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token function" style="color:#82AAFF">expect</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token plain">result</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token plain">total</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token punctuation" style="color:#C792EA">.</span><span class="token function" style="color:#82AAFF">toBe</span><span class="token punctuation" style="color:#C792EA">(</span><span class="token number" style="color:#F78C6C">130</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"> </span><span class="token comment" style="color:#637777;font-style:italic">// 2×50 + 1×30</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token punctuation" style="color:#C792EA">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token punctuation" style="color:#C792EA">}</span><span class="token punctuation" style="color:#C792EA">)</span><span class="token punctuation" style="color:#C792EA">;</span><br></span></code></pre></div></div>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="批量自动化处理">批量自动化处理<a href="https://luuman.github.io/claude-doc/blog/test-generation#%E6%89%B9%E9%87%8F%E8%87%AA%E5%8A%A8%E5%8C%96%E5%A4%84%E7%90%86" class="hash-link" aria-label="批量自动化处理的直接链接" title="批量自动化处理的直接链接" translate="no">​</a></h2>
<p>对多个文件批量生成测试：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockTitle_OeMC">scripts/auto-test-generation.sh</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">#!/bin/bash</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 批量为遗留文件生成测试</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">set -euo pipefail</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">COVERAGE_TARGET=${1:-80}  # 默认覆盖率目标 80%</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">OUTPUT_LOG="./test-generation.log"</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">echo "开始自动测试生成，覆盖率目标：${COVERAGE_TARGET}%" | tee "$OUTPUT_LOG"</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 找出没有测试的文件</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">MISSING_TESTS=$(find src/services -name "*.ts" ! -name "*.test.ts" | while read file; do</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  test_file=$(echo "$file" | sed 's/src\///' | sed 's/\.ts$/.test.ts/')</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  if [ ! -f "__tests__/$test_file" ]; then</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    echo "$file"</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  fi</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">done)</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">TOTAL=$(echo "$MISSING_TESTS" | wc -l)</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">CURRENT=0</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">echo "$MISSING_TESTS" | while read source_file; do</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  CURRENT=$((CURRENT + 1))</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  echo ""</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  echo "[$CURRENT/$TOTAL] 处理：$source_file" | tee -a "$OUTPUT_LOG"</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  result=$(claude --agent test-writer \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    "为 $source_file 生成完整测试，覆盖率目标 ${COVERAGE_TARGET}%，所有测试必须通过" \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    --dangerously-skip-permissions \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    --output-format stream-json 2&gt;/dev/null | \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    jq -r 'select(.type=="text") | .content' | tail -5)</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  echo "$result" | tee -a "$OUTPUT_LOG"</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  # 防止 API 速率限制</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  sleep 3</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">done</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">echo ""</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">echo "========================================" | tee -a "$OUTPUT_LOG"</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">echo "自动测试生成完成，查看日志：$OUTPUT_LOG"</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">echo "运行 npm test -- --coverage 查看总覆盖率"</span><br></span></code></pre></div></div>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="关键技巧">关键技巧<a href="https://luuman.github.io/claude-doc/blog/test-generation#%E5%85%B3%E9%94%AE%E6%8A%80%E5%B7%A7" class="hash-link" aria-label="关键技巧的直接链接" title="关键技巧的直接链接" translate="no">​</a></h2>





























<table><thead><tr><th>技巧</th><th>说明</th></tr></thead><tbody><tr><td>自修复循环</td><td>Agent 自动运行测试并修复失败，无需人工介入</td></tr><tr><td>覆盖率驱动</td><td>指定覆盖率目标，Agent 持续优化直到达标</td></tr><tr><td>框架自动检测</td><td>Agent 从 package.json 检测已有测试框架，不引入新依赖</td></tr><tr><td>批量处理</td><td>脚本化后可以一次性处理整个目录</td></tr><tr><td>限制重试次数</td><td>设置最大重试次数，避免无限循环</td></tr></tbody></table>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>测试质量注意</div><div class="admonitionContent_BuS1"><p>自动生成的测试覆盖了 API 表面，但可能遗漏业务意图的深层验证。建议：</p><ol>
<li class="">生成后人工 review 核心业务逻辑的测试用例</li>
<li class="">重点关注 Agent 未能生成的测试（提示"需要人工介入"的部分）</li>
<li class="">将自动生成的测试作为基础，人工补充边界场景</li>
</ol></div></div>]]></content:encoded>
            <category>Claude Code</category>
            <category>教程</category>
            <category>自动化</category>
        </item>
        <item>
            <title><![CDATA[案例 3：代码质量并行审查]]></title>
            <link>https://luuman.github.io/claude-doc/blog/parallel-review</link>
            <guid>https://luuman.github.io/claude-doc/blog/parallel-review</guid>
            <pubDate>Sun, 08 Feb 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[用 3 个并行子代理同时从代码质量、安全、性能三个维度审查 PR，覆盖率大幅提升]]></description>
            <content:encoded><![CDATA[<p><strong>场景：</strong> 团队 PR 审查流程慢，单人审查容易遗漏安全漏洞和性能问题。希望用 Claude Code 的子代理机制，让三个专业 Agent 并行从不同维度审查代码，输出综合报告。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="配置三个专业审查代理">配置三个专业审查代理<a href="https://luuman.github.io/claude-doc/blog/parallel-review#%E9%85%8D%E7%BD%AE%E4%B8%89%E4%B8%AA%E4%B8%93%E4%B8%9A%E5%AE%A1%E6%9F%A5%E4%BB%A3%E7%90%86" class="hash-link" aria-label="配置三个专业审查代理的直接链接" title="配置三个专业审查代理的直接链接" translate="no">​</a></h2>
<p>在项目根目录创建 <code>.claude/agents.json</code>：</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token property" style="color:#F78C6C">"agents"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token property" style="color:#F78C6C">"name"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"quality-reviewer"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token property" style="color:#F78C6C">"displayName"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"代码质量审查"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token property" style="color:#F78C6C">"description"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"审查代码可读性、设计模式、DRY 原则、命名规范"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token property" style="color:#F78C6C">"model"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"claude-sonnet-4-6"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token property" style="color:#F78C6C">"systemPrompt"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"你是一位专注于代码质量的高级工程师。审查时重点关注：\n\n1. **可读性**：命名是否清晰？逻辑是否易懂？注释是否必要？\n2. **DRY 原则**：是否有重复代码？是否可以提取公共函数？\n3. **单一职责**：函数/类是否只做一件事？是否过于庞大？\n4. **设计模式**：是否有更好的设计方式？\n5. **错误处理**：边界情况是否处理完整？\n\n输出格式：\n## 代码质量报告\n### 问题列表（按严重程度）\n[Critical/Major/Minor] 文件名:行号 - 问题描述 - 建议修改方式\n\n### 总体评价\n[1-10分] 和总结"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token property" style="color:#F78C6C">"tools"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">[</span><span class="token string" style="color:#ECC48D">"Read"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"Glob"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"Grep"</span><span class="token punctuation" style="color:#C792EA">]</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token property" style="color:#F78C6C">"temperature"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token number" style="color:#F78C6C">0.3</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token property" style="color:#F78C6C">"name"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"security-reviewer"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token property" style="color:#F78C6C">"displayName"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"安全漏洞审查"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token property" style="color:#F78C6C">"description"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"扫描 SQL 注入、XSS、CSRF、权限绕过、敏感信息泄露等安全问题"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token property" style="color:#F78C6C">"model"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"claude-sonnet-4-6"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token property" style="color:#F78C6C">"systemPrompt"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"你是一位专注于安全的高级工程师，熟悉 OWASP Top 10。审查时重点检查：\n\n1. **注入攻击**：SQL 注入、命令注入、LDAP 注入\n2. **XSS**：反射型、存储型、DOM 型\n3. **认证与授权**：权限检查是否完整？Token 是否安全？\n4. **敏感信息**：是否有硬编码的密码/API Key？日志是否泄露敏感信息？\n5. **依赖安全**：新增依赖是否有已知漏洞？\n6. **加密**：是否使用了不安全的加密算法？\n\n输出格式：\n## 安全审查报告\n### 漏洞列表\n[Critical/High/Medium/Low] OWASP-类别 - 文件名:行号 - 漏洞描述 - 修复建议\n\n### 总体安全评估"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token property" style="color:#F78C6C">"tools"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">[</span><span class="token string" style="color:#ECC48D">"Read"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"Glob"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"Grep"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"Bash"</span><span class="token punctuation" style="color:#C792EA">]</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token property" style="color:#F78C6C">"temperature"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token number" style="color:#F78C6C">0.1</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token property" style="color:#F78C6C">"name"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"performance-reviewer"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token property" style="color:#F78C6C">"displayName"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"性能问题审查"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token property" style="color:#F78C6C">"description"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"分析 N+1 查询、不必要重渲染、内存泄露、算法复杂度等性能问题"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token property" style="color:#F78C6C">"model"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"claude-sonnet-4-6"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token property" style="color:#F78C6C">"systemPrompt"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"你是一位专注于性能优化的高级工程师。审查时重点关注：\n\n1. **数据库查询**：是否有 N+1 查询？索引是否合理？是否有不必要的全表扫描？\n2. **前端性能**：不必要的重渲染？大列表是否虚拟化？图片是否优化？\n3. **内存管理**：是否有内存泄露风险？大对象是否及时释放？\n4. **算法复杂度**：是否有 O(n²) 或以上复杂度的操作可以优化？\n5. **网络请求**：是否有重复请求？是否可以批量或缓存？\n6. **同步阻塞**：是否有不必要的同步操作阻塞主线程？\n\n输出格式：\n## 性能审查报告\n### 问题列表\n[High/Medium/Low Impact] 文件名:行号 - 问题描述 - 优化方案 - 预期收益\n\n### 总体性能评估"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token property" style="color:#F78C6C">"tools"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">[</span><span class="token string" style="color:#ECC48D">"Read"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"Glob"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"Grep"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"Bash"</span><span class="token punctuation" style="color:#C792EA">]</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token property" style="color:#F78C6C">"temperature"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token number" style="color:#F78C6C">0.2</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token punctuation" style="color:#C792EA">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token punctuation" style="color:#C792EA">}</span><br></span></code></pre></div></div>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="执行并行审查">执行并行审查<a href="https://luuman.github.io/claude-doc/blog/parallel-review#%E6%89%A7%E8%A1%8C%E5%B9%B6%E8%A1%8C%E5%AE%A1%E6%9F%A5" class="hash-link" aria-label="执行并行审查的直接链接" title="执行并行审查的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="方式一在-claude-code-交互界面中指令触发">方式一：在 Claude Code 交互界面中指令触发<a href="https://luuman.github.io/claude-doc/blog/parallel-review#%E6%96%B9%E5%BC%8F%E4%B8%80%E5%9C%A8-claude-code-%E4%BA%A4%E4%BA%92%E7%95%8C%E9%9D%A2%E4%B8%AD%E6%8C%87%E4%BB%A4%E8%A7%A6%E5%8F%91" class="hash-link" aria-label="方式一：在 Claude Code 交互界面中指令触发的直接链接" title="方式一：在 Claude Code 交互界面中指令触发的直接链接" translate="no">​</a></h3>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">请用三个子代理并行审查 src/auth/ 目录下最近修改的代码：</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">1. quality-reviewer：审查代码质量和设计</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">2. security-reviewer：扫描安全漏洞</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">3. performance-reviewer：分析性能问题</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">审查目标：</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">- 涉及文件：src/auth/AuthService.ts, src/auth/middleware.ts, src/auth/routes.ts</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">- 背景：这是一次认证模块重构，新增了 JWT 刷新机制和权限分组</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">三个代理完成后，将结果汇总为一份综合审查报告，按严重程度排序所有问题。</span><br></span></code></pre></div></div>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="输出示例">输出示例<a href="https://luuman.github.io/claude-doc/blog/parallel-review#%E8%BE%93%E5%87%BA%E7%A4%BA%E4%BE%8B" class="hash-link" aria-label="输出示例的直接链接" title="输出示例的直接链接" translate="no">​</a></h2>
<p>综合报告示例结构：</p>
<div class="language-markdown codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-markdown codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token title important punctuation" style="color:#C792EA">#</span><span class="token title important" style="color:#D6DEEB"> 代码审查综合报告</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">审查时间：2025-02-18 14:30:22</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">审查目录：src/auth/</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token hr punctuation" style="color:#C792EA">---</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token title important punctuation" style="color:#C792EA">##</span><span class="token title important" style="color:#D6DEEB"> 代码质量报告</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token title important punctuation" style="color:#C792EA">###</span><span class="token title important" style="color:#D6DEEB"> 问题列表</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">[Major] AuthService.ts:45 - </span><span class="token code-snippet code keyword" style="color:#C792EA">`refreshToken`</span><span class="token plain"> 方法超过 80 行，建议拆分</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">[Minor] middleware.ts:12 - 变量名 </span><span class="token code-snippet code keyword" style="color:#C792EA">`t`</span><span class="token plain"> 语义不清，建议改为 </span><span class="token code-snippet code keyword" style="color:#C792EA">`token`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token title important punctuation" style="color:#C792EA">###</span><span class="token title important" style="color:#D6DEEB"> 总体评价</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">7/10 - 整体结构清晰，但部分函数职责过重</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token hr punctuation" style="color:#C792EA">---</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token title important punctuation" style="color:#C792EA">##</span><span class="token title important" style="color:#D6DEEB"> 安全审查报告</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token title important punctuation" style="color:#C792EA">###</span><span class="token title important" style="color:#D6DEEB"> 漏洞列表</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">[High] A2-失效认证 - AuthService.ts:89 - JWT 验证时未检查 </span><span class="token code-snippet code keyword" style="color:#C792EA">`iss`</span><span class="token plain"> 字段，可能被跨系统伪造</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">[Medium] A3-敏感数据泄露 - routes.ts:34 - 错误日志中输出了完整的 token 字符串</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token title important punctuation" style="color:#C792EA">###</span><span class="token title important" style="color:#D6DEEB"> 总体安全评估</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">中等风险，存在一个需要立即修复的认证漏洞</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token hr punctuation" style="color:#C792EA">---</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token title important punctuation" style="color:#C792EA">##</span><span class="token title important" style="color:#D6DEEB"> 必须修复（Critical/High）</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> [安全-High] AuthService.ts:89 - JWT 验证缺少 iss 字段检查</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token title important punctuation" style="color:#C792EA">##</span><span class="token title important" style="color:#D6DEEB"> 建议修复（Medium）</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> [安全-Medium] routes.ts:34 - 日志中暴露完整 token</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> [质量-Major] AuthService.ts:45 - refreshToken 函数过长需拆分</span><br></span></code></pre></div></div>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="效率对比">效率对比<a href="https://luuman.github.io/claude-doc/blog/parallel-review#%E6%95%88%E7%8E%87%E5%AF%B9%E6%AF%94" class="hash-link" aria-label="效率对比的直接链接" title="效率对比的直接链接" translate="no">​</a></h2>






























<table><thead><tr><th>指标</th><th>单人人工审查</th><th>Claude Code 并行审查</th></tr></thead><tbody><tr><td>审查时间</td><td>4-8 小时</td><td>5-15 分钟</td></tr><tr><td>覆盖维度</td><td>取决于个人经验</td><td>质量+安全+性能全覆盖</td></tr><tr><td>遗漏率</td><td>20-40%（疲劳等因素）</td><td>&lt;5%</td></tr><tr><td>可重复性</td><td>不同人结果不同</td><td>规则一致，结果可复现</td></tr></tbody></table>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="关键技巧">关键技巧<a href="https://luuman.github.io/claude-doc/blog/parallel-review#%E5%85%B3%E9%94%AE%E6%8A%80%E5%B7%A7" class="hash-link" aria-label="关键技巧的直接链接" title="关键技巧的直接链接" translate="no">​</a></h2>

























<table><thead><tr><th>技巧</th><th>说明</th></tr></thead><tbody><tr><td>专业化分工</td><td>每个 Agent 只专注一个维度，避免泛泛而谈</td></tr><tr><td>低温度配置</td><td>审查类任务 temperature 0.1-0.3，保证一致性</td></tr><tr><td>明确输出格式</td><td>在 systemPrompt 中规定报告格式，方便自动解析</td></tr><tr><td>背景上下文</td><td>告诉 Agent 这次 PR 的目的，提高审查针对性</td></tr></tbody></table>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>适合集成到 CI/CD</div><div class="admonitionContent_BuS1"><p>将此脚本添加到 GitHub Actions，每次 PR 自动触发三路并行审查，将报告作为 PR 评论发布。参考 <a class="" href="https://luuman.github.io/claude-doc/docs/claude-code/advanced-features/headless-mode">Headless 模式</a> 中的 GitHub Actions 示例。</p></div></div>]]></content:encoded>
            <category>Claude Code</category>
            <category>教程</category>
            <category>并行开发</category>
            <category>自动化</category>
        </item>
        <item>
            <title><![CDATA[案例 2：自动化数据抓取与导出]]></title>
            <link>https://luuman.github.io/claude-doc/blog/web-scraping</link>
            <guid>https://luuman.github.io/claude-doc/blog/web-scraping</guid>
            <pubDate>Thu, 05 Feb 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[通过 Chrome DevTools MCP 让 Claude Code 直接操控浏览器抓取数据，自动生成 Excel 报表]]></description>
            <content:encoded><![CDATA[<p><strong>场景：</strong> 每日需要从内部管理后台（需要登录，无公开 API）抓取各区域销售数据，整理成固定格式的 Excel 报表发送给运营团队。原本需要 1 小时手工操作，目标压缩至 10 分钟全自动执行。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="前置准备">前置准备<a href="https://luuman.github.io/claude-doc/blog/web-scraping#%E5%89%8D%E7%BD%AE%E5%87%86%E5%A4%87" class="hash-link" aria-label="前置准备的直接链接" title="前置准备的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="安装-chrome-devtools-mcp">安装 Chrome DevTools MCP<a href="https://luuman.github.io/claude-doc/blog/web-scraping#%E5%AE%89%E8%A3%85-chrome-devtools-mcp" class="hash-link" aria-label="安装 Chrome DevTools MCP的直接链接" title="安装 Chrome DevTools MCP的直接链接" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 添加 Chrome DevTools MCP 服务器</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">claude mcp add chrome-devtools npx @modelcontextprotocol/server-chrome-devtools</span><br></span></code></pre></div></div>
<p>确认安装成功：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 在 Claude Code 中检查</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">/mcp</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 应该看到 chrome-devtools: 已连接</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="安装-python-依赖">安装 Python 依赖<a href="https://luuman.github.io/claude-doc/blog/web-scraping#%E5%AE%89%E8%A3%85-python-%E4%BE%9D%E8%B5%96" class="hash-link" aria-label="安装 Python 依赖的直接链接" title="安装 Python 依赖的直接链接" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">pip install openpyxl pandas</span><br></span></code></pre></div></div>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="实现过程">实现过程<a href="https://luuman.github.io/claude-doc/blog/web-scraping#%E5%AE%9E%E7%8E%B0%E8%BF%87%E7%A8%8B" class="hash-link" aria-label="实现过程的直接链接" title="实现过程的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="第-1-步登录并获取数据">第 1 步：登录并获取数据<a href="https://luuman.github.io/claude-doc/blog/web-scraping#%E7%AC%AC-1-%E6%AD%A5%E7%99%BB%E5%BD%95%E5%B9%B6%E8%8E%B7%E5%8F%96%E6%95%B0%E6%8D%AE" class="hash-link" aria-label="第 1 步：登录并获取数据的直接链接" title="第 1 步：登录并获取数据的直接链接" translate="no">​</a></h3>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">使用 Chrome DevTools 打开我们的管理后台：</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">1. 导航到 https://admin.internal.com/login</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">2. 用账号 admin@company.com 登录（我来输密码）</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">3. 进入"销售报表"→"区域概览"页面</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">4. 截图确认页面加载完成</span><br></span></code></pre></div></div>
<p>Claude Code 通过 <code>chrome_navigate</code> 打开页面，<code>chrome_fill</code> 填写表单，<code>chrome_screenshot</code> 截图确认：</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">[截图：已成功登录到管理后台，当前在区域概览页面]</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">页面上我看到一个表格，包含以下列：</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">- 区域名称</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">- 昨日销售额</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">- 本周累计</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">- 完成率</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">- 同比增长</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">共 12 个区域的数据。需要我抓取这些数据吗？</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="第-2-步提取表格数据">第 2 步：提取表格数据<a href="https://luuman.github.io/claude-doc/blog/web-scraping#%E7%AC%AC-2-%E6%AD%A5%E6%8F%90%E5%8F%96%E8%A1%A8%E6%A0%BC%E6%95%B0%E6%8D%AE" class="hash-link" aria-label="第 2 步：提取表格数据的直接链接" title="第 2 步：提取表格数据的直接链接" translate="no">​</a></h3>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">是的，把所有行的数据都抓下来，输出为 JSON 格式</span><br></span></code></pre></div></div>
<p>Claude Code 使用 <code>chrome_evaluate</code> 执行 JavaScript 提取数据。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="自动化定时执行">自动化定时执行<a href="https://luuman.github.io/claude-doc/blog/web-scraping#%E8%87%AA%E5%8A%A8%E5%8C%96%E5%AE%9A%E6%97%B6%E6%89%A7%E8%A1%8C" class="hash-link" aria-label="自动化定时执行的直接链接" title="自动化定时执行的直接链接" translate="no">​</a></h2>
<p>将整个流程封装成脚本，配合 cron 每天自动运行：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockTitle_OeMC">scripts/daily-sales-report.sh</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">#!/bin/bash</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 每日自动抓取销售数据并发送报表</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># cron: 0 8 * * 1-5 /path/to/daily-sales-report.sh</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">claude -p "</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">使用 Chrome DevTools 登录管理后台，抓取区域销售数据，</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">生成格式化 Excel 文件保存到 ~/reports/ 目录，</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">完成后输出文件路径</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">" --dangerously-skip-permissions \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  --output-format stream-json | \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  jq -r 'select(.type=="text") | .content' | \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  tail -1  # 获取文件路径</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 发送邮件</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">REPORT_FILE=$(ls ~/reports/销售日报_*.xlsx | tail -1)</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">python3 -c "</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">import smtplib</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">from email.mime.multipart import MIMEMultipart</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">from email.mime.base import MIMEBase</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">from email import encoders</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">import os</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">msg = MIMEMultipart()</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">msg['From'] = 'robot@company.com'</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">msg['To'] = 'team@company.com'</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">msg['Subject'] = '每日销售报表'</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">with open('$REPORT_FILE', 'rb') as f:</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    attachment = MIMEBase('application', 'octet-stream')</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    attachment.set_payload(f.read())</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    encoders.encode_base64(attachment)</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    attachment.add_header('Content-Disposition', f'attachment; filename=\"{os.path.basename(\"$REPORT_FILE\")}\"')</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    msg.attach(attachment)</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">with smtplib.SMTP('smtp.company.com', 587) as s:</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    s.login('robot@company.com', os.environ['EMAIL_PASS'])</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    s.send_message(msg)</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">print('邮件已发送')</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">"</span><br></span></code></pre></div></div>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="效率对比">效率对比<a href="https://luuman.github.io/claude-doc/blog/web-scraping#%E6%95%88%E7%8E%87%E5%AF%B9%E6%AF%94" class="hash-link" aria-label="效率对比的直接链接" title="效率对比的直接链接" translate="no">​</a></h2>






























<table><thead><tr><th>指标</th><th>手动操作</th><th>Claude Code 自动化</th></tr></thead><tbody><tr><td>耗时</td><td>~60 分钟</td><td>~10 分钟</td></tr><tr><td>需要人工值守</td><td>全程</td><td>仅首次配置</td></tr><tr><td>出错风险</td><td>高（手动复制粘贴）</td><td>低（程序化提取）</td></tr><tr><td>节假日执行</td><td>需专人操作</td><td>自动运行</td></tr></tbody></table>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="关键技巧">关键技巧<a href="https://luuman.github.io/claude-doc/blog/web-scraping#%E5%85%B3%E9%94%AE%E6%8A%80%E5%B7%A7" class="hash-link" aria-label="关键技巧的直接链接" title="关键技巧的直接链接" translate="no">​</a></h2>





























<table><thead><tr><th>技巧</th><th>说明</th></tr></thead><tbody><tr><td>Chrome DevTools MCP</td><td>可以操控需要登录的页面，无公开 API 也能抓取</td></tr><tr><td><code>chrome_evaluate</code></td><td>直接执行 JS 提取结构化数据，比解析 HTML 更稳定</td></tr><tr><td><code>chrome_screenshot</code></td><td>截图确认页面状态，方便调试</td></tr><tr><td>数据数字化</td><td>抓取时转换为数值类型，方便后续计算合计</td></tr><tr><td>cron 定时化</td><td>结合 Headless 模式实现全自动定时执行</td></tr></tbody></table>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>扩展应用</div><div class="admonitionContent_BuS1"><p>同样的方式可以抓取：竞品价格监控、行业数据报告、内部 OA 系统数据、ERP 系统报表……只要能在浏览器中访问，Claude Code + Chrome DevTools MCP 就能实现自动化。</p></div></div>]]></content:encoded>
            <category>Claude Code</category>
            <category>教程</category>
            <category>自动化</category>
        </item>
        <item>
            <title><![CDATA[案例 1：批量文件重命名]]></title>
            <link>https://luuman.github.io/claude-doc/blog/batch-rename</link>
            <guid>https://luuman.github.io/claude-doc/blog/batch-rename</guid>
            <pubDate>Sun, 01 Feb 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[用自然语言驱动批量文件操作，无需手写 Shell 脚本]]></description>
            <content:encoded><![CDATA[<p><strong>场景：</strong> 设计师交付了 300 张切图，文件名规则混乱（如 <code>icon_home_v2_final_FINAL.png</code>、<code>btn-submit_copy2.png</code>），需要按照项目命名规范重命名为 <code>icon-home.png</code>、<code>btn-submit.png</code> 格式。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="解决过程">解决过程<a href="https://luuman.github.io/claude-doc/blog/batch-rename#%E8%A7%A3%E5%86%B3%E8%BF%87%E7%A8%8B" class="hash-link" aria-label="解决过程的直接链接" title="解决过程的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="第-1-步将文件夹拖入终端">第 1 步：将文件夹拖入终端<a href="https://luuman.github.io/claude-doc/blog/batch-rename#%E7%AC%AC-1-%E6%AD%A5%E5%B0%86%E6%96%87%E4%BB%B6%E5%A4%B9%E6%8B%96%E5%85%A5%E7%BB%88%E7%AB%AF" class="hash-link" aria-label="第 1 步：将文件夹拖入终端的直接链接" title="第 1 步：将文件夹拖入终端的直接链接" translate="no">​</a></h3>
<p>将设计资产文件夹从 Finder/Explorer 拖拽到终端，路径会自动填入：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 路径自动填入后，启动 Claude Code</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">claude</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="第-2-步描述重命名规则">第 2 步：描述重命名规则<a href="https://luuman.github.io/claude-doc/blog/batch-rename#%E7%AC%AC-2-%E6%AD%A5%E6%8F%8F%E8%BF%B0%E9%87%8D%E5%91%BD%E5%90%8D%E8%A7%84%E5%88%99" class="hash-link" aria-label="第 2 步：描述重命名规则的直接链接" title="第 2 步：描述重命名规则的直接链接" translate="no">​</a></h3>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">我的 /Users/me/project/assets/icons/ 目录下有 300 张切图，</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">文件名像这样：icon_home_v2_final_FINAL.png、btn-submit_copy2.png</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">请帮我重命名，规则如下：</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">1. 全部转为小写</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">2. 下划线统一换成连字符</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">3. 去掉 _v2、_final、_copy[数字] 这类版本后缀</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">4. 文件名只保留语义部分，如 icon-home.png、btn-submit.png</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">执行前先预览变更列表，我确认后再执行。</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="第-3-步claude-生成预览">第 3 步：Claude 生成预览<a href="https://luuman.github.io/claude-doc/blog/batch-rename#%E7%AC%AC-3-%E6%AD%A5claude-%E7%94%9F%E6%88%90%E9%A2%84%E8%A7%88" class="hash-link" aria-label="第 3 步：Claude 生成预览的直接链接" title="第 3 步：Claude 生成预览的直接链接" translate="no">​</a></h3>
<p>Claude Code 会先分析目录，生成变更预览：</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">分析完成，找到 283 个文件需要重命名：</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">icon_home_v2_final_FINAL.png    →  icon-home.png</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">icon_search_v1_copy3.png        →  icon-search.png</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">btn_submit_v2_FINAL.png         →  btn-submit.png</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">bg_hero_section_final2.png      →  bg-hero-section.png</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">... (还有 279 个)</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">注意事项：</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">⚠️  发现 3 组重名冲突（重命名后文件名相同）：</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">   - icon_user.png 和 icon_user_v2.png → 都会变成 icon-user.png</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">   - 建议：保留最新版，旧版加 -old 后缀？</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">是否按此规则执行？(确认 / 调整规则 / 处理冲突后再执行)</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="第-4-步处理冲突并确认">第 4 步：处理冲突并确认<a href="https://luuman.github.io/claude-doc/blog/batch-rename#%E7%AC%AC-4-%E6%AD%A5%E5%A4%84%E7%90%86%E5%86%B2%E7%AA%81%E5%B9%B6%E7%A1%AE%E8%AE%A4" class="hash-link" aria-label="第 4 步：处理冲突并确认的直接链接" title="第 4 步：处理冲突并确认的直接链接" translate="no">​</a></h3>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">重名冲突的处理：icon_user_v2.png 保留为 icon-user.png，</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">icon_user.png 改名为 icon-user-v1.png</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">其余的按你说的规则执行，开始吧</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="第-5-步执行重命名">第 5 步：执行重命名<a href="https://luuman.github.io/claude-doc/blog/batch-rename#%E7%AC%AC-5-%E6%AD%A5%E6%89%A7%E8%A1%8C%E9%87%8D%E5%91%BD%E5%90%8D" class="hash-link" aria-label="第 5 步：执行重命名的直接链接" title="第 5 步：执行重命名的直接链接" translate="no">​</a></h3>
<p>Claude Code 生成并执行重命名脚本：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">#!/bin/bash</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 由 Claude Code 生成的重命名脚本</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">rename_file() {</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  local old="$1"</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  local new="$2"</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  if [ -f "$new" ]; then</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    echo "⚠️  跳过（目标已存在）: $old → $new"</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    return</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  fi</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  mv "$old" "$new"</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  echo "✓ $old → $new"</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">}</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">cd /Users/me/project/assets/icons/</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">rename_file "icon_home_v2_final_FINAL.png" "icon-home.png"</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">rename_file "icon_search_v1_copy3.png" "icon-search.png"</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># ... 283 行</span><br></span></code></pre></div></div>
<p>执行完成后输出统计：</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">完成！</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">✓ 成功重命名：280 个</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">⚠️  跳过（冲突）：3 个</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">✗ 失败：0 个</span><br></span></code></pre></div></div>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="常见变体">常见变体<a href="https://luuman.github.io/claude-doc/blog/batch-rename#%E5%B8%B8%E8%A7%81%E5%8F%98%E4%BD%93" class="hash-link" aria-label="常见变体的直接链接" title="常见变体的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="按日期前缀重命名">按日期前缀重命名<a href="https://luuman.github.io/claude-doc/blog/batch-rename#%E6%8C%89%E6%97%A5%E6%9C%9F%E5%89%8D%E7%BC%80%E9%87%8D%E5%91%BD%E5%90%8D" class="hash-link" aria-label="按日期前缀重命名的直接链接" title="按日期前缀重命名的直接链接" translate="no">​</a></h3>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">把 exports/ 目录下所有文件加上今天的日期前缀，格式：2025-02-18_原文件名</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="序号化重命名">序号化重命名<a href="https://luuman.github.io/claude-doc/blog/batch-rename#%E5%BA%8F%E5%8F%B7%E5%8C%96%E9%87%8D%E5%91%BD%E5%90%8D" class="hash-link" aria-label="序号化重命名的直接链接" title="序号化重命名的直接链接" translate="no">​</a></h3>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">把 screenshots/ 里的图片按修改时间排序，</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">重命名为 screenshot-001.png、screenshot-002.png...</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="跨格式重命名">跨格式重命名<a href="https://luuman.github.io/claude-doc/blog/batch-rename#%E8%B7%A8%E6%A0%BC%E5%BC%8F%E9%87%8D%E5%91%BD%E5%90%8D" class="hash-link" aria-label="跨格式重命名的直接链接" title="跨格式重命名的直接链接" translate="no">​</a></h3>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">把所有 .jpeg 扩展名改成 .jpg，同时把文件名里的空格替换成连字符</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="基于内容重命名配合-vision">基于内容重命名（配合 Vision）<a href="https://luuman.github.io/claude-doc/blog/batch-rename#%E5%9F%BA%E4%BA%8E%E5%86%85%E5%AE%B9%E9%87%8D%E5%91%BD%E5%90%8D%E9%85%8D%E5%90%88-vision" class="hash-link" aria-label="基于内容重命名（配合 Vision）的直接链接" title="基于内容重命名（配合 Vision）的直接链接" translate="no">​</a></h3>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">看一下 banners/ 目录里每张图的内容（可以截图），</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">按图片中显示的产品名称重命名文件</span><br></span></code></pre></div></div>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="关键技巧">关键技巧<a href="https://luuman.github.io/claude-doc/blog/batch-rename#%E5%85%B3%E9%94%AE%E6%8A%80%E5%B7%A7" class="hash-link" aria-label="关键技巧的直接链接" title="关键技巧的直接链接" translate="no">​</a></h2>

























<table><thead><tr><th>技巧</th><th>说明</th></tr></thead><tbody><tr><td>先预览后执行</td><td>要求 Claude Code 在执行前展示变更列表</td></tr><tr><td>拖拽引用路径</td><td>直接拖文件夹到终端，避免手敲路径出错</td></tr><tr><td>冲突明确处理</td><td>预先指定冲突文件的处理策略</td></tr><tr><td>保留备份</td><td>大规模操作前建议 <code>cp -r assets/ assets.bak/</code></td></tr></tbody></table>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>无需写脚本</div><div class="admonitionContent_BuS1"><p>整个过程不需要你手写任何 Shell 脚本——用自然语言描述规则，Claude Code 生成脚本并执行。如果规则有例外情况，直接在对话中补充说明即可。</p></div></div>]]></content:encoded>
            <category>Claude Code</category>
            <category>教程</category>
            <category>自动化</category>
        </item>
        <item>
            <title><![CDATA[可视化任务管理系统搭建]]></title>
            <link>https://luuman.github.io/claude-doc/blog/visual-management</link>
            <guid>https://luuman.github.io/claude-doc/blog/visual-management</guid>
            <pubDate>Wed, 28 Jan 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[构建 Claude Code 的 Web 管理面板，实现任务看板、自动化调度与实时监控]]></description>
            <content:encoded><![CDATA[<blockquote>
<p>从命令行手动管理到 Web 看板自动化调度，构建你自己的 Claude Code Manager。支持任务创建、需求自动拆分、并行执行、实时日志监控和一键合并。</p>
</blockquote>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="整体架构">整体架构<a href="https://luuman.github.io/claude-doc/blog/visual-management#%E6%95%B4%E4%BD%93%E6%9E%B6%E6%9E%84" class="hash-link" aria-label="整体架构的直接链接" title="整体架构的直接链接" translate="no">​</a></h2>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">┌─────────────────────────────────────────────────┐</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">│              浏览器 / 手机 PWA                     │</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">│  ┌──────────┐ ┌──────────┐ ┌──────────────────┐  │</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">│  │ 任务看板  │ │ 实时日志  │ │ 项目/Worktree管理 │  │</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">│  └──────────┘ └──────────┘ └──────────────────┘  │</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">└───────────────────┬─────────────────────────────┘</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">                    │ WebSocket + REST API</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">┌───────────────────▼─────────────────────────────┐</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">│            Python 后端 (FastAPI)                   │</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">│  ┌──────────┐ ┌───────────┐ ┌────────────────┐  │</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">│  │ 任务调度器 │ │ CC进程管理 │ │ Git Worktree管理│  │</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">│  └──────────┘ └───────────┘ └────────────────┘  │</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">│  ┌──────────┐ ┌───────────┐ ┌────────────────┐  │</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">│  │ 日志解析器 │ │ 模板引擎  │ │  SQLite 存储   │  │</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">│  └──────────┘ └───────────┘ └────────────────┘  │</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">└───────────────────┬─────────────────────────────┘</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">                    │ subprocess</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">┌───────────────────▼─────────────────────────────┐</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">│          Claude Code 实例 ×N                      │</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">│  ┌─────────┐ ┌─────────┐ ┌─────────┐            │</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">│  │ worktree1│ │ worktree2│ │ worktree3│  ...      │</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">│  │ feat/auth│ │ feat/ui  │ │ feat/api │           │</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">│  └─────────┘ └─────────┘ └─────────┘            │</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">└─────────────────────────────────────────────────┘</span><br></span></code></pre></div></div>
<p>系统分为三层：</p>
<ul>
<li class=""><strong>前端层</strong>：基于原生 HTML/CSS/JS 的单文件看板，通过 WebSocket 接收实时日志，通过 REST API 操作任务。支持 PWA，可添加到手机桌面。</li>
<li class=""><strong>后端层</strong>：FastAPI 提供异步 API，aiosqlite 管理持久化数据，asyncio 并发调度多个 Claude Code 实例。</li>
<li class=""><strong>执行层</strong>：每个任务在独立的 Git Worktree 中运行，Claude Code 以 <code>stream-json</code> 格式输出，后端解析后通过 WebSocket 广播。</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="项目结构">项目结构<a href="https://luuman.github.io/claude-doc/blog/visual-management#%E9%A1%B9%E7%9B%AE%E7%BB%93%E6%9E%84" class="hash-link" aria-label="项目结构的直接链接" title="项目结构的直接链接" translate="no">​</a></h2>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">claude-code-manager/</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">├── app.py              # FastAPI 后端主入口</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">├── requirements.txt    # Python 依赖</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">├── tasks.db            # SQLite 数据库（自动创建）</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">├── manifest.json       # PWA 清单</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">├── sw.js               # Service Worker</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">├── templates/          # 项目模板</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">│   ├── CLAUDE.md.tpl   # CLAUDE.md 通用模板</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">│   └── PROGRESS.md.tpl # 进度追踪模板</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">└── frontend/</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    └── index.html      # 看板 UI（单文件）</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="启动与使用">启动与使用<a href="https://luuman.github.io/claude-doc/blog/visual-management#%E5%90%AF%E5%8A%A8%E4%B8%8E%E4%BD%BF%E7%94%A8" class="hash-link" aria-label="启动与使用的直接链接" title="启动与使用的直接链接" translate="no">​</a></h2>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 1. 创建项目目录</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">mkdir claude-code-manager &amp;&amp; cd claude-code-manager</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">mkdir -p frontend templates</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 2. 安装依赖</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">pip install fastapi uvicorn websockets aiosqlite</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 3. 将 app.py 和 frontend/index.html 放入对应目录</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 4. 启动服务</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">uvicorn app:app --host 0.0.0.0 --port 8080</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 5. 浏览器访问</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># http://localhost:8080</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>首次使用步骤</div><div class="admonitionContent_BuS1"><ol>
<li class="">打开 <code>http://localhost:8080</code></li>
<li class="">后端会自动在 API 中注册默认项目（演示模式下 <code>project_id = 'default'</code>）</li>
<li class="">点击「新建任务」，填写标题和提示词</li>
<li class="">或者点击「批量拆分」，粘贴需求文档，让 AI 自动拆分成多个任务</li>
<li class="">点击「全部启动」，并行执行所有待执行任务</li>
<li class="">实时查看右侧日志面板</li>
<li class="">任务完成后点击「合并分支」将代码合并到主线</li>
</ol></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="自动化任务流程">自动化任务流程<a href="https://luuman.github.io/claude-doc/blog/visual-management#%E8%87%AA%E5%8A%A8%E5%8C%96%E4%BB%BB%E5%8A%A1%E6%B5%81%E7%A8%8B" class="hash-link" aria-label="自动化任务流程的直接链接" title="自动化任务流程的直接链接" translate="no">​</a></h2>
<p>以下是从需求输入到代码合并的完整端到端流程：</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">用户输入需求</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    │</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    ▼  POST /api/tasks/batch</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">Claude Code 自动拆分 → 5 个独立任务</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    │</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    ▼  用户看板上审阅生成的任务列表</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    │  可以手动编辑/删除不需要的任务</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    │</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    ▼  点击「全部启动」 POST /api/tasks/run-all</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">5 个 Git Worktree 并行创建</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">5 个 Claude Code 实例并行启动</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    │</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    ▼  WebSocket 实时推送日志</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">看板显示每个任务的运行状态和实时输出</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    │</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    ▼  各任务独立完成</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">状态变为 success / failed</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    │</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    ▼  对每个 success 任务点击「合并分支」</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">自动执行 git merge --no-ff，删除 worktree</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    │</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    ▼</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">主分支包含所有新功能</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="并行执行效率对比">并行执行效率对比<a href="https://luuman.github.io/claude-doc/blog/visual-management#%E5%B9%B6%E8%A1%8C%E6%89%A7%E8%A1%8C%E6%95%88%E7%8E%87%E5%AF%B9%E6%AF%94" class="hash-link" aria-label="并行执行效率对比的直接链接" title="并行执行效率对比的直接链接" translate="no">​</a></h3>




















<table><thead><tr><th>方式</th><th>5 个任务耗时</th><th>CPU 利用率</th></tr></thead><tbody><tr><td>串行手动执行</td><td>~150 分钟</td><td>20%</td></tr><tr><td>此系统并行执行</td><td>~35 分钟</td><td>85%+</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="手机端-pwa-配置">手机端 PWA 配置<a href="https://luuman.github.io/claude-doc/blog/visual-management#%E6%89%8B%E6%9C%BA%E7%AB%AF-pwa-%E9%85%8D%E7%BD%AE" class="hash-link" aria-label="手机端 PWA 配置的直接链接" title="手机端 PWA 配置的直接链接" translate="no">​</a></h2>
<p>将以下文件添加到 <code>claude-code-manager/</code> 目录，实现 PWA 支持：</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockTitle_OeMC">manifest.json</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token property" style="color:#F78C6C">"name"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"Claude Code Manager"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token property" style="color:#F78C6C">"short_name"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"CC Manager"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token property" style="color:#F78C6C">"description"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"Claude Code 可视化任务管理系统"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token property" style="color:#F78C6C">"start_url"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"/"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token property" style="color:#F78C6C">"display"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"standalone"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token property" style="color:#F78C6C">"background_color"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"#0d1117"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token property" style="color:#F78C6C">"theme_color"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"#161b22"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token property" style="color:#F78C6C">"icons"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#C792EA">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token punctuation" style="color:#C792EA">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token property" style="color:#F78C6C">"src"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"data:image/svg+xml,&lt;svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'&gt;&lt;text y='.9em' font-size='90'&gt;🤖&lt;/text&gt;&lt;/svg&gt;"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token property" style="color:#F78C6C">"sizes"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"any"</span><span class="token punctuation" style="color:#C792EA">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">      </span><span class="token property" style="color:#F78C6C">"type"</span><span class="token operator" style="color:#7FDBCA">:</span><span class="token plain"> </span><span class="token string" style="color:#ECC48D">"image/svg+xml"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    </span><span class="token punctuation" style="color:#C792EA">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  </span><span class="token punctuation" style="color:#C792EA">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token punctuation" style="color:#C792EA">}</span><br></span></code></pre></div></div>
<p><strong>添加到桌面步骤：</strong></p>
<ol>
<li class="">在 Chrome（Android）或 Safari（iOS）中打开 <code>http://your-server:8080</code></li>
<li class="">Chrome：点击右上角菜单 → "添加到主屏幕"</li>
<li class="">Safari：点击分享按钮 → "添加到主屏幕"</li>
<li class="">安装后图标出现在桌面，以独立 App 模式运行，无浏览器导航栏</li>
<li class="">支持离线访问界面（API 调用需要网络连接）</li>
</ol>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>局域网访问</div><div class="admonitionContent_BuS1"><p>将 <code>your-server</code> 替换为运行服务器的局域网 IP（如 <code>192.168.1.100:8080</code>），手机连接同一 WiFi 即可访问。可使用 <code>ip addr</code> 查看服务器 IP。</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="进阶增强方向">进阶增强方向<a href="https://luuman.github.io/claude-doc/blog/visual-management#%E8%BF%9B%E9%98%B6%E5%A2%9E%E5%BC%BA%E6%96%B9%E5%90%91" class="hash-link" aria-label="进阶增强方向的直接链接" title="进阶增强方向的直接链接" translate="no">​</a></h2>

















































<table><thead><tr><th>方向</th><th>做法</th></tr></thead><tbody><tr><td>语音输入</td><td>输入框加 Web Speech API，对着手机说需求，自动填入 prompt</td></tr><tr><td>定时任务</td><td>集成 APScheduler，每天凌晨自动跑测试套件或生成日报</td></tr><tr><td>多项目切换</td><td>左侧加项目 Tab 栏，支持同时管理多个 Git 仓库</td></tr><tr><td>成功率统计</td><td>记录每个 prompt 模板的成功/失败比，优化提示词模板库</td></tr><tr><td>自动合并</td><td>任务成功且测试通过（CI 绿灯）→ 自动创建 PR，无需手动操作</td></tr><tr><td>Webhook 通知</td><td>任务完成/失败时通过 HTTP 推送到钉钉机器人、飞书、Slack</td></tr><tr><td>认证保护</td><td>添加 HTTP Basic Auth 中间件或 JWT Token 认证</td></tr><tr><td>任务模板库</td><td>保存常用 prompt 模板，一键复用（如「写单元测试」「代码审查」）</td></tr><tr><td>资源限制</td><td>设置最大并发任务数，避免同时启动过多 Claude Code 实例</td></tr><tr><td>任务依赖</td><td>支持 task A 完成后自动触发 task B，构建任务 DAG</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="安全注意事项">安全注意事项<a href="https://luuman.github.io/claude-doc/blog/visual-management#%E5%AE%89%E5%85%A8%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9" class="hash-link" aria-label="安全注意事项的直接链接" title="安全注意事项的直接链接" translate="no">​</a></h2>
<div class="theme-admonition theme-admonition-danger admonition_xJq3 alert alert--danger"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"></path></svg></span>安全提醒</div><div class="admonitionContent_BuS1"><ul>
<li class="">此系统应仅在<strong>内网或 VPN</strong> 下运行，不要暴露在公网</li>
<li class=""><code>--dangerously-skip-permissions</code> 意味着 Claude Code 有完整的系统权限，可以读写任意文件</li>
<li class="">建议在 Docker 容器中运行，通过 volume mount 限制文件系统访问范围</li>
<li class="">定期检查 Git 提交历史（<code>git log --stat</code>），确保 AI 没有引入意外改动</li>
<li class="">任务的 prompt 内容可能被恶意用户构造为提示词注入，建议对输入做基础过滤</li>
</ul></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="docker-部署推荐">Docker 部署（推荐）<a href="https://luuman.github.io/claude-doc/blog/visual-management#docker-%E9%83%A8%E7%BD%B2%E6%8E%A8%E8%8D%90" class="hash-link" aria-label="Docker 部署（推荐）的直接链接" title="Docker 部署（推荐）的直接链接" translate="no">​</a></h3>
<div class="language-dockerfile codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockTitle_OeMC">Dockerfile</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-dockerfile codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">FROM python:3.12-slim</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 安装 Claude Code CLI</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">RUN npm install -g @anthropic-ai/claude-code</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">WORKDIR /app</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">COPY requirements.txt .</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">RUN pip install -r requirements.txt</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">COPY . .</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 只挂载指定的项目目录，而非整个宿主机文件系统</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">VOLUME ["/projects"]</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">EXPOSE 8080</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8080"]</span><br></span></code></pre></div></div>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 构建和运行</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">docker build -t cc-manager .</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">docker run -d \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  -p 8080:8080 \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  -v /home/user/my-project:/projects/my-project \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  -e ANTHROPIC_API_KEY=your_key \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  cc-manager</span><br></span></code></pre></div></div>]]></content:encoded>
            <category>Claude Code</category>
            <category>教程</category>
            <category>自动化</category>
            <category>效率提升</category>
        </item>
        <item>
            <title><![CDATA[并行 Claude Code 实战落地指南]]></title>
            <link>https://luuman.github.io/claude-doc/blog/parallel-implementation</link>
            <guid>https://luuman.github.io/claude-doc/blog/parallel-implementation</guid>
            <pubDate>Tue, 20 Jan 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[从单实例到多实例并行，一步步搭建高效的 Claude Code 开发工作流]]></description>
            <content:encoded><![CDATA[<blockquote>
<p>基于胡渊鸣的实践经验，本文将其方法论拆解为可直接落地的 6 个阶段。每个阶段独立可用，按需逐步升级。</p>
</blockquote>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="前置条件">前置条件<a href="https://luuman.github.io/claude-doc/blog/parallel-implementation#%E5%89%8D%E7%BD%AE%E6%9D%A1%E4%BB%B6" class="hash-link" aria-label="前置条件的直接链接" title="前置条件的直接链接" translate="no">​</a></h2>
<ul>
<li class="">Claude Code 已安装 (<code>npm install -g @anthropic-ai/claude-code</code>)</li>
<li class="">项目已用 Git 管理</li>
<li class="">建议在独立的云服务器或容器中操作（如 EC2、本地 Docker）</li>
</ul>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="阶段-1无打断模式效率-2">阶段 1：无打断模式（效率 ×2）<a href="https://luuman.github.io/claude-doc/blog/parallel-implementation#%E9%98%B6%E6%AE%B5-1%E6%97%A0%E6%89%93%E6%96%AD%E6%A8%A1%E5%BC%8F%E6%95%88%E7%8E%87-2" class="hash-link" aria-label="阶段 1：无打断模式（效率 ×2）的直接链接" title="阶段 1：无打断模式（效率 ×2）的直接链接" translate="no">​</a></h2>
<p>最低门槛的改进。</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">claude --dangerously-skip-permissions</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-danger admonition_xJq3 alert alert--danger"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"></path></svg></span>重要前提</div><div class="admonitionContent_BuS1"><p>开启跳权限模式前，必须确保项目有 Git 版本控制。建议加一个定时备份：</p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain"># crontab -e 添加，每小时自动备份</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">0 * * * * cd /your/project &amp;&amp; git add -A &amp;&amp; git stash push -m "auto-backup-$(date +\%H\%M)"</span><br></span></code></pre></div></div></div></div>
<p>效果：单个 prompt 下 Claude Code 能连续工作 5+ 分钟，不会被权限弹窗中断。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="阶段-2claudemd--progressmd质量-2">阶段 2：CLAUDE.md + PROGRESS.md（质量 ×2）<a href="https://luuman.github.io/claude-doc/blog/parallel-implementation#%E9%98%B6%E6%AE%B5-2claudemd--progressmd%E8%B4%A8%E9%87%8F-2" class="hash-link" aria-label="阶段 2：CLAUDE.md + PROGRESS.md（质量 ×2）的直接链接" title="阶段 2：CLAUDE.md + PROGRESS.md（质量 ×2）的直接链接" translate="no">​</a></h2>
<p>在项目根目录创建两个文件，这是所有后续步骤的基础。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="claudemd--项目规范不频繁改动">CLAUDE.md — 项目规范（不频繁改动）<a href="https://luuman.github.io/claude-doc/blog/parallel-implementation#claudemd--%E9%A1%B9%E7%9B%AE%E8%A7%84%E8%8C%83%E4%B8%8D%E9%A2%91%E7%B9%81%E6%94%B9%E5%8A%A8" class="hash-link" aria-label="CLAUDE.md — 项目规范（不频繁改动）的直接链接" title="CLAUDE.md — 项目规范（不频繁改动）的直接链接" translate="no">​</a></h3>
<p>完整模板示例：</p>
<div class="language-markdown codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-markdown codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token title important punctuation" style="color:#C792EA">#</span><span class="token title important" style="color:#D6DEEB"> 项目名称</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token title important punctuation" style="color:#C792EA">##</span><span class="token title important" style="color:#D6DEEB"> 技术栈</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> 前端: React + TypeScript</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> 后端: Node.js + Express</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> 数据库: PostgreSQL</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token title important punctuation" style="color:#C792EA">##</span><span class="token title important" style="color:#D6DEEB"> 项目结构</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">src/</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">├── components/    # UI 组件</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">├── services/      # 业务逻辑</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">├── utils/         # 工具函数</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">└── types/         # 类型定义</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token title important punctuation" style="color:#C792EA">##</span><span class="token title important" style="color:#D6DEEB"> 常用命令</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">npm run dev        # 启动开发服务器</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">npm test           # 运行测试</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">npm run build      # 构建生产版本</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token title important punctuation" style="color:#C792EA">##</span><span class="token title important" style="color:#D6DEEB"> 编码规范</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> 文件名用 kebab-case</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> 组件名用 PascalCase</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> 提交信息遵循 Conventional Commits</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token title important punctuation" style="color:#C792EA">##</span><span class="token title important" style="color:#D6DEEB"> 禁止事项</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> 不要删除 config/production.json</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> 不要直接修改 database schema，先备份</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> 不要在代码中硬编码密钥</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token title important punctuation" style="color:#C792EA">##</span><span class="token title important" style="color:#D6DEEB"> 工作模式</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">每次任务完成后，将踩坑经验总结到 PROGRESS.md 中。同样的错误不要再犯。</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>写好 CLAUDE.md 的关键</div><div class="admonitionContent_BuS1"><p>"不要做什么" 比 "要做什么" 更重要。Claude Code 的自由度很高，明确边界比指导方向更有效。</p></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="progressmd--经验教训ai-的外部记忆">PROGRESS.md — 经验教训（AI 的外部记忆）<a href="https://luuman.github.io/claude-doc/blog/parallel-implementation#progressmd--%E7%BB%8F%E9%AA%8C%E6%95%99%E8%AE%ADai-%E7%9A%84%E5%A4%96%E9%83%A8%E8%AE%B0%E5%BF%86" class="hash-link" aria-label="PROGRESS.md — 经验教训（AI 的外部记忆）的直接链接" title="PROGRESS.md — 经验教训（AI 的外部记忆）的直接链接" translate="no">​</a></h3>
<div class="language-markdown codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-markdown codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token title important punctuation" style="color:#C792EA">#</span><span class="token title important" style="color:#D6DEEB"> 经验记录</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token title important punctuation" style="color:#C792EA">##</span><span class="token title important" style="color:#D6DEEB"> 2026-02-18</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> 问题：修改登录模块时忘记更新路由配置，导致页面 404</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> 教训：修改任何模块后必须检查相关路由是否同步更新</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> 解决：在测试中加入路由完整性检查</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token title important punctuation" style="color:#C792EA">##</span><span class="token title important" style="color:#D6DEEB"> 2026-02-17</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> 问题：数据库迁移脚本缺少回滚逻辑</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> 教训：每个 migration 必须包含 up 和 down</span><br></span></code></pre></div></div>
<p>在 CLAUDE.md 中加入引用：</p>
<div class="language-markdown codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-markdown codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">每次启动时阅读 PROGRESS.md，避免重复犯错。</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="自动生成-claudemd">自动生成 CLAUDE.md<a href="https://luuman.github.io/claude-doc/blog/parallel-implementation#%E8%87%AA%E5%8A%A8%E7%94%9F%E6%88%90-claudemd" class="hash-link" aria-label="自动生成 CLAUDE.md的直接链接" title="自动生成 CLAUDE.md的直接链接" translate="no">​</a></h3>
<p>如果不想手写，可以让 Claude Code 自动分析生成：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">claude -p "分析当前项目结构、package.json、README，生成一份 CLAUDE.md，包含技术栈、项目结构、常用命令、编码规范、禁止事项" --dangerously-skip-permissions</span><br></span></code></pre></div></div>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="阶段-3git-worktree-并行化效率-5">阶段 3：Git Worktree 并行化（效率 ×5）<a href="https://luuman.github.io/claude-doc/blog/parallel-implementation#%E9%98%B6%E6%AE%B5-3git-worktree-%E5%B9%B6%E8%A1%8C%E5%8C%96%E6%95%88%E7%8E%87-5" class="hash-link" aria-label="阶段 3：Git Worktree 并行化（效率 ×5）的直接链接" title="阶段 3：Git Worktree 并行化（效率 ×5）的直接链接" translate="no">​</a></h2>
<p>这是核心的并行化技术。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="git-worktree-原理">Git Worktree 原理<a href="https://luuman.github.io/claude-doc/blog/parallel-implementation#git-worktree-%E5%8E%9F%E7%90%86" class="hash-link" aria-label="Git Worktree 原理的直接链接" title="Git Worktree 原理的直接链接" translate="no">​</a></h3>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">主仓库 (.git)</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    ├── main 工作区 (原始目录)</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    ├── worktree-1 (feat/auth 分支) → Claude Code 实例 1</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    ├── worktree-2 (feat/ui 分支)   → Claude Code 实例 2</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    └── worktree-3 (feat/api 分支)  → Claude Code 实例 3</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">共享: Git 历史、远程配置、hooks</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">独立: 工作目录、分支、暂存区</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="操作步骤">操作步骤<a href="https://luuman.github.io/claude-doc/blog/parallel-implementation#%E6%93%8D%E4%BD%9C%E6%AD%A5%E9%AA%A4" class="hash-link" aria-label="操作步骤的直接链接" title="操作步骤的直接链接" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 1. 创建并行工作区</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">cd /your/project</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">git worktree add ../project-wt1 -b feat/task-1</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">git worktree add ../project-wt2 -b feat/task-2</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">git worktree add ../project-wt3 -b feat/task-3</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 2. 每个工作区启动独立的 Claude Code</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 方式一：多个终端标签页</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">cd ../project-wt1 &amp;&amp; claude --dangerously-skip-permissions</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 方式二：tmux 多窗格</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">tmux new-session -d -s cc1 "cd ../project-wt1 &amp;&amp; claude --dangerously-skip-permissions"</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">tmux new-session -d -s cc2 "cd ../project-wt2 &amp;&amp; claude --dangerously-skip-permissions"</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">tmux new-session -d -s cc3 "cd ../project-wt3 &amp;&amp; claude --dangerously-skip-permissions"</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 3. 任务完成后合并</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">cd /your/project</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">git merge feat/task-1</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">git merge feat/task-2</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">git merge feat/task-3</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 4. 清理工作区</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">git worktree remove ../project-wt1</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">git worktree remove ../project-wt2</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">git worktree remove ../project-wt3</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>并行注意事项</div><div class="admonitionContent_BuS1"><ul>
<li class="">任务之间必须尽量独立，避免同时修改同一文件导致合并冲突</li>
<li class="">每个 worktree 自动继承主仓库的 CLAUDE.md</li>
<li class="">建议并行数量 3~5 个，超过后管理成本上升</li>
<li class="">如需安装依赖，每个 worktree 都需要独立执行 <code>npm install</code></li>
</ul></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="合并冲突处理">合并冲突处理<a href="https://luuman.github.io/claude-doc/blog/parallel-implementation#%E5%90%88%E5%B9%B6%E5%86%B2%E7%AA%81%E5%A4%84%E7%90%86" class="hash-link" aria-label="合并冲突处理的直接链接" title="合并冲突处理的直接链接" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 如果合并出现冲突</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">git merge feat/task-2</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># CONFLICT detected</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 方式一：让 Claude Code 解决</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">claude -p "解决当前的 git merge 冲突，保留两边功能" --dangerously-skip-permissions</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 方式二：手动解决后继续</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">git add .</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">git merge --continue</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="实际效果">实际效果<a href="https://luuman.github.io/claude-doc/blog/parallel-implementation#%E5%AE%9E%E9%99%85%E6%95%88%E6%9E%9C" class="hash-link" aria-label="实际效果的直接链接" title="实际效果的直接链接" translate="no">​</a></h3>

























<table><thead><tr><th>并行数</th><th>预期 commit 频率</th><th>适用场景</th></tr></thead><tbody><tr><td>1 个</td><td>每 5-10 分钟 1 个</td><td>单一功能开发</td></tr><tr><td>3 个</td><td>每 2-3 分钟 1 个</td><td>中型项目，多模块并行</td></tr><tr><td>5 个</td><td>每分钟 1 个</td><td>大型项目，高度并行</td></tr></tbody></table>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="阶段-4ralph-loop--连续任务执行效率-8">阶段 4：Ralph Loop — 连续任务执行（效率 ×8）<a href="https://luuman.github.io/claude-doc/blog/parallel-implementation#%E9%98%B6%E6%AE%B5-4ralph-loop--%E8%BF%9E%E7%BB%AD%E4%BB%BB%E5%8A%A1%E6%89%A7%E8%A1%8C%E6%95%88%E7%8E%87-8" class="hash-link" aria-label="阶段 4：Ralph Loop — 连续任务执行（效率 ×8）的直接链接" title="阶段 4：Ralph Loop — 连续任务执行（效率 ×8）的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="任务文件-todomd">任务文件 TODO.md<a href="https://luuman.github.io/claude-doc/blog/parallel-implementation#%E4%BB%BB%E5%8A%A1%E6%96%87%E4%BB%B6-todomd" class="hash-link" aria-label="任务文件 TODO.md的直接链接" title="任务文件 TODO.md的直接链接" translate="no">​</a></h3>
<div class="language-markdown codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-markdown codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> [ ] 实现用户登录页面，包含表单验证</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> [ ] 添加 API 鉴权中间件（JWT）</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> [ ] 编写 auth 模块单元测试，覆盖率 &gt;80%</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> [ ] 实现用户资料编辑页面</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> [ ] 添加文件上传功能</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="claudemd-中的工作模式定义">CLAUDE.md 中的工作模式定义<a href="https://luuman.github.io/claude-doc/blog/parallel-implementation#claudemd-%E4%B8%AD%E7%9A%84%E5%B7%A5%E4%BD%9C%E6%A8%A1%E5%BC%8F%E5%AE%9A%E4%B9%89" class="hash-link" aria-label="CLAUDE.md 中的工作模式定义的直接链接" title="CLAUDE.md 中的工作模式定义的直接链接" translate="no">​</a></h3>
<div class="language-markdown codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-markdown codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token title important punctuation" style="color:#C792EA">##</span><span class="token title important" style="color:#D6DEEB"> Ralph Loop 工作模式</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">1.</span><span class="token plain"> 读取 TODO.md，找到第一个未完成的任务（</span><span class="token code-snippet code keyword" style="color:#C792EA">`- [ ]`</span><span class="token plain">）</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">2.</span><span class="token plain"> 执行该任务</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">3.</span><span class="token plain"> 运行测试确认通过</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">4.</span><span class="token plain"> 将其标记为 </span><span class="token code-snippet code keyword" style="color:#C792EA">`- [x]`</span><span class="token plain">，附上完成时间</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">5.</span><span class="token plain"> 将经验记录到 PROGRESS.md</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">6.</span><span class="token plain"> 如果还有未完成任务，继续下一个</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">7.</span><span class="token plain"> 所有任务完成后，输出总结报告</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="自动循环脚本">自动循环脚本<a href="https://luuman.github.io/claude-doc/blog/parallel-implementation#%E8%87%AA%E5%8A%A8%E5%BE%AA%E7%8E%AF%E8%84%9A%E6%9C%AC" class="hash-link" aria-label="自动循环脚本的直接链接" title="自动循环脚本的直接链接" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">#!/bin/bash</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># run-loop.sh — Ralph Loop 自动调度器</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">PROJECT_DIR="/your/project"</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">while true; do</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    # 检查是否还有未完成任务</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    if ! grep -q '\- \[ \]' "$PROJECT_DIR/TODO.md"; then</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        echo "✅ 所有任务已完成"</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        break</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    fi</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    echo "🔄 启动新一轮 Claude Code..."</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    claude -p "按照 CLAUDE.md 中的 Ralph Loop 工作模式执行下一个任务。完成后更新 TODO.md 和 PROGRESS.md。" \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        --dangerously-skip-permissions \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        --cwd "$PROJECT_DIR"</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    EXIT_CODE=$?</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    if [ $EXIT_CODE -ne 0 ]; then</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        echo "⚠️ Claude Code 异常退出（退出码: $EXIT_CODE），等待 10 秒后重试..."</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        sleep 10</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    else</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">        sleep 2</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    fi</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">done</span><br></span></code></pre></div></div>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">chmod +x run-loop.sh</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">./run-loop.sh</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>Ralph Loop + Worktree 组合</div><div class="admonitionContent_BuS1"><p>在每个 worktree 中放不同的 TODO.md，同时运行多个 Ralph Loop，就实现了"多线程持续开发"。</p></div></div>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="阶段-5程序化调度--p--stream-json效率-10">阶段 5：程序化调度 <code>-p</code> + <code>stream-json</code>（效率 ×10+）<a href="https://luuman.github.io/claude-doc/blog/parallel-implementation#%E9%98%B6%E6%AE%B5-5%E7%A8%8B%E5%BA%8F%E5%8C%96%E8%B0%83%E5%BA%A6--p--stream-json%E6%95%88%E7%8E%87-10" class="hash-link" aria-label="阶段-5程序化调度--p--stream-json效率-10的直接链接" title="阶段-5程序化调度--p--stream-json效率-10的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="核心命令">核心命令<a href="https://luuman.github.io/claude-doc/blog/parallel-implementation#%E6%A0%B8%E5%BF%83%E5%91%BD%E4%BB%A4" class="hash-link" aria-label="核心命令的直接链接" title="核心命令的直接链接" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 基础用法：执行一个任务并退出</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">claude -p "实现用户注册功能" --dangerously-skip-permissions</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 进阶：JSON 流式输出，方便程序解析</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">claude -p "实现用户注册功能" \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    --dangerously-skip-permissions \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    --output-format stream-json \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    --verbose</span><br></span></code></pre></div></div>
<p>这部分包含详细的 Python 调度器示例代码，可查看原文件获取完整实现。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="阶段-6plan-模式批量预审成功率-95">阶段 6：Plan 模式批量预审（成功率 95%+）<a href="https://luuman.github.io/claude-doc/blog/parallel-implementation#%E9%98%B6%E6%AE%B5-6plan-%E6%A8%A1%E5%BC%8F%E6%89%B9%E9%87%8F%E9%A2%84%E5%AE%A1%E6%88%90%E5%8A%9F%E7%8E%87-95" class="hash-link" aria-label="阶段 6：Plan 模式批量预审（成功率 95%+）的直接链接" title="阶段 6：Plan 模式批量预审（成功率 95%+）的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="先出计划后执行">先出计划后执行<a href="https://luuman.github.io/claude-doc/blog/parallel-implementation#%E5%85%88%E5%87%BA%E8%AE%A1%E5%88%92%E5%90%8E%E6%89%A7%E8%A1%8C" class="hash-link" aria-label="先出计划后执行的直接链接" title="先出计划后执行的直接链接" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain"># Step 1: 生成计划</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">claude -p "请为以下需求生成执行计划，列出步骤和涉及的文件，不要开始编码：</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">实现 OAuth2.0 第三方登录，支持 Google 和 GitHub" \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    --dangerously-skip-permissions &gt; plan.md</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># Step 2: 人工审阅 plan.md（关键！）</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">cat plan.md</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># Step 3: 确认后执行</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">claude -p "按照 plan.md 中的计划执行" \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    --dangerously-skip-permissions</span><br></span></code></pre></div></div>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="效率升级路径总结">效率升级路径总结<a href="https://luuman.github.io/claude-doc/blog/parallel-implementation#%E6%95%88%E7%8E%87%E5%8D%87%E7%BA%A7%E8%B7%AF%E5%BE%84%E6%80%BB%E7%BB%93" class="hash-link" aria-label="效率升级路径总结的直接链接" title="效率升级路径总结的直接链接" translate="no">​</a></h2>















































<table><thead><tr><th>阶段</th><th>关键技术</th><th>效率倍数</th><th>适用场景</th></tr></thead><tbody><tr><td>1</td><td><code>--dangerously-skip-permissions</code></td><td>×2</td><td>任何项目</td></tr><tr><td>2</td><td>CLAUDE.md + PROGRESS.md</td><td>×2（质量）</td><td>任何项目</td></tr><tr><td>3</td><td>Git Worktree</td><td>×5</td><td>多模块并行</td></tr><tr><td>4</td><td>Ralph Loop</td><td>×8</td><td>任务明确的项目</td></tr><tr><td>5</td><td>Python 调度 + stream-json</td><td>×10+</td><td>批量自动化</td></tr><tr><td>6</td><td>Plan 模式预审</td><td>成功率 95%+</td><td>复杂任务</td></tr></tbody></table>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="应用到新项目的标准流程">应用到新项目的标准流程<a href="https://luuman.github.io/claude-doc/blog/parallel-implementation#%E5%BA%94%E7%94%A8%E5%88%B0%E6%96%B0%E9%A1%B9%E7%9B%AE%E7%9A%84%E6%A0%87%E5%87%86%E6%B5%81%E7%A8%8B" class="hash-link" aria-label="应用到新项目的标准流程的直接链接" title="应用到新项目的标准流程的直接链接" translate="no">​</a></h2>
<ol>
<li class=""><code>git init</code> 或 clone 已有项目</li>
<li class="">创建 CLAUDE.md（手写或 <code>claude -p</code> 自动生成）</li>
<li class="">创建 PROGRESS.md（空文件即可）</li>
<li class="">编写 TODO.md 列出所有任务</li>
<li class="">评估任务独立性，决定并行数量</li>
<li class="">用 Git Worktree 创建工作区</li>
<li class="">启动 Claude Code 实例</li>
<li class="">监控执行，合并结果</li>
</ol>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>核心原则</div><div class="admonitionContent_BuS1"><ul>
<li class="">每一步都有 git 保底，随时可回滚</li>
<li class="">CLAUDE.md 写清楚"不要做什么"</li>
<li class="">不看代码，看测试结果 — 在 CLAUDE.md 里要求每个任务结束必须跑测试</li>
<li class="">任务拆得越细，并行效果越好，每个任务控制在 15-30 分钟能完成的粒度</li>
</ul></div></div>]]></content:encoded>
            <category>Claude Code</category>
            <category>教程</category>
            <category>并行开发</category>
        </item>
        <item>
            <title><![CDATA[大规模 Vibe Coding 实战：10 个 Claude Code 并行开发]]></title>
            <link>https://luuman.github.io/claude-doc/blog/vibe-coding-at-scale</link>
            <guid>https://luuman.github.io/claude-doc/blog/vibe-coding-at-scale</guid>
            <pubDate>Thu, 15 Jan 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Meshy AI 创始人胡渊鸣如何用 10 个 Claude Code 实例并行开发，并将成功率从 20% 提升至 95%]]></description>
            <content:encoded><![CDATA[<blockquote>
<p>本文整理自 Meshy AI 创始人胡渊鸣（Ethan Hu）的公开分享，记录了他从单机 Cursor Agent 到 10 个 Claude Code 实例并行运行的完整进化路径。这是目前最系统、最具工程深度的 Agentic Coding 实践案例之一。</p>
</blockquote>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="背景">背景<a href="https://luuman.github.io/claude-doc/blog/vibe-coding-at-scale#%E8%83%8C%E6%99%AF" class="hash-link" aria-label="背景的直接链接" title="背景的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="关于胡渊鸣">关于胡渊鸣<a href="https://luuman.github.io/claude-doc/blog/vibe-coding-at-scale#%E5%85%B3%E4%BA%8E%E8%83%A1%E6%B8%8A%E9%B8%A3" class="hash-link" aria-label="关于胡渊鸣的直接链接" title="关于胡渊鸣的直接链接" translate="no">​</a></h3>
<p>胡渊鸣（Ethan Hu）的经历堪称技术创业者的理想模板：</p>
<ul>
<li class="">清华大学<strong>姚班</strong>（计算机科学实验班）毕业</li>
<li class=""><strong>MIT</strong> 计算机图形学博士</li>
<li class=""><strong>太极图形语言</strong>（Taichi）创造者——一门面向图形与并行计算的高性能编程语言</li>
<li class=""><strong>Meshy AI</strong> 创始人兼 CEO——全球排名第一的 3D AI 生成平台，ARR 已达 <strong>3000 万美元</strong></li>
</ul>
<p>凭借深厚的技术背景，胡渊鸣对 AI 编程工具有着比普通开发者更敏锐的判断力。他选择用自己的亲身实践，系统性地探索 Claude Code 的吞吐量极限。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="目标给-ceo-造一套量身定制的软件">目标：给 CEO 造一套量身定制的软件<a href="https://luuman.github.io/claude-doc/blog/vibe-coding-at-scale#%E7%9B%AE%E6%A0%87%E7%BB%99-ceo-%E9%80%A0%E4%B8%80%E5%A5%97%E9%87%8F%E8%BA%AB%E5%AE%9A%E5%88%B6%E7%9A%84%E8%BD%AF%E4%BB%B6" class="hash-link" aria-label="目标：给 CEO 造一套量身定制的软件的直接链接" title="目标：给 CEO 造一套量身定制的软件的直接链接" translate="no">​</a></h3>
<p>作为公司 CEO，胡渊鸣的日常工作高度碎片化。他决定用 Vibe Coding 为自己开发一套"CEO 支持软件"，核心需求包括：</p>





































<table><thead><tr><th>需求</th><th>描述</th></tr></thead><tbody><tr><td>随时随地语音输入</td><td>走路、开会间隙均可</td></tr><tr><td>双端支持</td><td>iPhone + Mac 无缝切换</td></tr><tr><td>AI 辅助编辑</td><td>润色文档、补全内容</td></tr><tr><td>中英双语</td><td>内外部沟通均需覆盖</td></tr><tr><td>格式强迫症</td><td>精确控制排版与样式</td></tr><tr><td>文档校对</td><td>自动发现逻辑错误与歧义</td></tr><tr><td>思维导图</td><td>可视化思路整理</td></tr></tbody></table>
<p>这套软件没有现成产品可以替代——它需要完全匹配个人工作流。<strong>定制化软件的开发成本，正在被 AI 编程工具趋近于零。</strong></p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="提高-agentic-coding-吞吐量的-10-个阶段">提高 Agentic Coding 吞吐量的 10 个阶段<a href="https://luuman.github.io/claude-doc/blog/vibe-coding-at-scale#%E6%8F%90%E9%AB%98-agentic-coding-%E5%90%9E%E5%90%90%E9%87%8F%E7%9A%84-10-%E4%B8%AA%E9%98%B6%E6%AE%B5" class="hash-link" aria-label="提高 Agentic Coding 吞吐量的 10 个阶段的直接链接" title="提高 Agentic Coding 吞吐量的 10 个阶段的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-1从-cursor-agent-到-claude-code">Step 1：从 Cursor Agent 到 Claude Code<a href="https://luuman.github.io/claude-doc/blog/vibe-coding-at-scale#step-1%E4%BB%8E-cursor-agent-%E5%88%B0-claude-code" class="hash-link" aria-label="Step 1：从 Cursor Agent 到 Claude Code的直接链接" title="Step 1：从 Cursor Agent 到 Claude Code的直接链接" translate="no">​</a></h3>
<p>故事从一台 RTX 4090 的 Ubuntu 工作站开始。</p>
<p>胡渊鸣原本使用 <strong>Cursor Agent</strong>，并取得了令人印象深刻的成果——在工作站上用 3 小时完成了一个 GPU DSL（领域专用语言）的重新设计，而传统方式需要整整 3 周。</p>
<p>但问题随之而来：工作站只能在公司使用，灵感却随时随地都会出现。他需要远程操控（RustDesk），操作体验极差。</p>
<p>切换到 <strong>Claude Code</strong> 后，通过 SSH 在 iPhone 上直接访问服务器，可以 vibe coding 的时间窗口从每天 <strong>8 小时</strong>扩展到 <strong>24 小时</strong>。</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>关键洞察</div><div class="admonitionContent_BuS1"><p>工具的可及性决定了创造力的边界。能随时随地写代码，等于把每一个灵感闪现的瞬间都变成了生产力。</p></div></div>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-2找个-container">Step 2：找个 Container<a href="https://luuman.github.io/claude-doc/blog/vibe-coding-at-scale#step-2%E6%89%BE%E4%B8%AA-container" class="hash-link" aria-label="Step 2：找个 Container的直接链接" title="Step 2：找个 Container的直接链接" translate="no">​</a></h3>
<p>在本地工作站上操作仍然有局限。胡渊鸣将工作环境迁移到 <strong>AWS EC2</strong>，并启用了 Claude Code 的跳权模式：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">claude --dangerously-skip-permissions</span><br></span></code></pre></div></div>
<p>这个改变带来了质的飞跃：Claude Code 在单个 prompt 下可以持续工作 <strong>5 分钟甚至更长</strong>，无需频繁的人工确认，大幅提高了利用率。</p>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>温馨提示</div><div class="admonitionContent_BuS1"><p>在任何自动化场景下开启 <code>--dangerously-skip-permissions</code> 前，请务必先写好自动备份数据库的功能。AI 犯错不可避免，数据丢失才是真正的灾难。</p></div></div>
<p><strong>云端容器的优势：</strong></p>
<ul>
<li class="">资源弹性伸缩，可同时跑多个实例</li>
<li class="">网络稳定，无需担心本地断线</li>
<li class="">计费按需，成本可控</li>
<li class="">天然隔离，降低权限风险</li>
</ul>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-3ralph-loop让-claude-code-不停干活">Step 3：Ralph Loop，让 Claude Code 不停干活<a href="https://luuman.github.io/claude-doc/blog/vibe-coding-at-scale#step-3ralph-loop%E8%AE%A9-claude-code-%E4%B8%8D%E5%81%9C%E5%B9%B2%E6%B4%BB" class="hash-link" aria-label="Step 3：Ralph Loop，让 Claude Code 不停干活的直接链接" title="Step 3：Ralph Loop，让 Claude Code 不停干活的直接链接" translate="no">​</a></h3>
<p>有了容器之后，下一个瓶颈出现了：每次任务完成后，Claude Code 就停下来等待新指令。</p>
<p>胡渊鸣引入了 <strong>Ralph Loop</strong>——一种让 Claude Code 持续自驱工作的模式：</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">1. 从任务列表中取出下一个任务</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">2. 执行任务</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">3. 将结果记录到任务列表</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">4. 回到步骤 1，直到列表为空</span><br></span></code></pre></div></div>
<p>更妙的是，<strong>他用 Claude Code 开发了 Claude Code 的启动器</strong>——让 AI 管理 AI 的工作流。<code>CLAUDE.md</code> 文件定义了"干活"的具体内容和规则，Claude Code 启动后自动读取并开始循环执行。</p>
<p>这是一个典型的 <strong>meta-programming</strong> 思路：用 AI 编程工具来优化 AI 编程工具自身的使用效率。</p>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-4用-git-worktree-实现并行化">Step 4：用 Git Worktree 实现并行化<a href="https://luuman.github.io/claude-doc/blog/vibe-coding-at-scale#step-4%E7%94%A8-git-worktree-%E5%AE%9E%E7%8E%B0%E5%B9%B6%E8%A1%8C%E5%8C%96" class="hash-link" aria-label="Step 4：用 Git Worktree 实现并行化的直接链接" title="Step 4：用 Git Worktree 实现并行化的直接链接" translate="no">​</a></h3>
<p>Ralph Loop 解决了单个实例的连续性问题，但还不够。胡渊鸣开始思考：<strong>能否同时跑多个 Claude Code？</strong></p>
<p>答案是 <strong>Git Worktree</strong>。</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 为每个并行任务创建独立的工作树</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">git worktree add ../feature-auth feature/auth</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">git worktree add ../feature-ui feature/ui</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">git worktree add ../feature-api feature/api</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 在每个工作树中启动独立的 Claude Code 实例</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">cd ../feature-auth &amp;&amp; claude --dangerously-skip-permissions &amp;</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">cd ../feature-ui   &amp;&amp; claude --dangerously-skip-permissions &amp;</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">cd ../feature-api  &amp;&amp; claude --dangerously-skip-permissions &amp;</span><br></span></code></pre></div></div>
<p>Git Worktree 的核心优势是：多个工作区共享同一个 Git 仓库历史，但拥有各自独立的工作目录和分支，互不干扰。</p>
<p><strong>实际效果：5 个 Claude Code 实例并行运行，达到了每分钟 1 个 commit 的速度。</strong></p>
<p>GitHub 成为整个并行开发的调度中心：任务分支、进度追踪、代码合并全部通过 Git 管理。</p>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-5用好-claudemd-和-progressmd">Step 5：用好 CLAUDE.md 和 PROGRESS.md<a href="https://luuman.github.io/claude-doc/blog/vibe-coding-at-scale#step-5%E7%94%A8%E5%A5%BD-claudemd-%E5%92%8C-progressmd" class="hash-link" aria-label="Step 5：用好 CLAUDE.md 和 PROGRESS.md的直接链接" title="Step 5：用好 CLAUDE.md 和 PROGRESS.md的直接链接" translate="no">​</a></h3>
<p>随着并行实例增多，如何保持 AI 行为一致性成为新挑战。胡渊鸣总结了两类关键文件的最佳实践：</p>
<p><strong>CLAUDE.md（项目规范）：</strong></p>
<ul>
<li class="">定义编码规范、架构约定、禁止行为</li>
<li class="">不宜频繁修改——频繁变动会让 Claude Code 产生混乱的行为</li>
<li class="">写清楚"什么情况下不该做什么"，比"应该做什么"更重要</li>
</ul>
<p><strong>PROGRESS.md（经验积累）：</strong></p>
<ul>
<li class="">记录每次踩坑的教训</li>
<li class="">关键原则：<strong>"同样的错误下次不要再犯"</strong></li>
<li class="">在 CLAUDE.md 中引用 PROGRESS.md，让 AI 在每次启动时复习历史教训</li>
</ul>
<div class="language-markdown codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-markdown codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token comment" style="color:#637777;font-style:italic">&lt;!-- CLAUDE.md 中的典型写法 --&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token title important punctuation" style="color:#C792EA">##</span><span class="token title important" style="color:#D6DEEB"> 重要约束</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> 修改数据库 schema 前必须先备份，参见 PROGRESS.md#数据库事故-2024-03</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain"></span><span class="token list punctuation" style="color:#C792EA">-</span><span class="token plain"> 不要直接修改 config/production.json，所有生产配置通过环境变量注入</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>关于 AI 的"记忆"</div><div class="admonitionContent_BuS1"><p>Claude Code 本身没有跨会话记忆。CLAUDE.md 和 PROGRESS.md 是当前最实用的"外部记忆"机制，将组织知识持久化到文件中，让每个新会话都能继承历史经验。</p></div></div>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-6干掉-ssh开发界面变手机网页">Step 6：干掉 SSH，开发界面变手机网页<a href="https://luuman.github.io/claude-doc/blog/vibe-coding-at-scale#step-6%E5%B9%B2%E6%8E%89-ssh%E5%BC%80%E5%8F%91%E7%95%8C%E9%9D%A2%E5%8F%98%E6%89%8B%E6%9C%BA%E7%BD%91%E9%A1%B5" class="hash-link" aria-label="Step 6：干掉 SSH，开发界面变手机网页的直接链接" title="Step 6：干掉 SSH，开发界面变手机网页的直接链接" translate="no">​</a></h3>
<p>SSH 下的 Claude Code 有一个令人抓狂的问题：<strong>在 iPhone Safari 中刷新 terminal 时，延迟巨大、体验极差。</strong></p>
<p>胡渊鸣的解决方案：<strong>自己写一个 Claude Code Web Manager</strong>。</p>
<p>核心架构：</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">iPhone Safari</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    ↓ HTTP 请求</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">Web Manager（Python Flask）</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    ↓ subprocess</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">Claude Code（-p 非交互模式）</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    ↓ JSON 输出</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">Web Manager 解析展示</span><br></span></code></pre></div></div>
<p>关键命令：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 非交互模式，适合被程序调度</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">claude -p "执行任务描述" \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  --dangerously-skip-permissions \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  --output-format stream-json \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  --verbose</span><br></span></code></pre></div></div>
<p>最终，这个 Web Manager 被包装成 iPhone 的 PWA（Progressive Web App），添加到桌面后与原生 App 无异。<strong>走在马路上打开手机，就能查看和调度所有 Claude Code 实例的状态。</strong></p>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-7有效编写管理-claude-code-的程序">Step 7：有效编写管理 Claude Code 的程序<a href="https://luuman.github.io/claude-doc/blog/vibe-coding-at-scale#step-7%E6%9C%89%E6%95%88%E7%BC%96%E5%86%99%E7%AE%A1%E7%90%86-claude-code-%E7%9A%84%E7%A8%8B%E5%BA%8F" class="hash-link" aria-label="Step 7：有效编写管理 Claude Code 的程序的直接链接" title="Step 7：有效编写管理 Claude Code 的程序的直接链接" translate="no">​</a></h3>
<p>Web Manager 只是开始。随着管理复杂度上升，胡渊鸣开始系统性地优化管理程序的设计。</p>
<p><strong>关键洞察：Claude Code 的成功率取决于闭环是否完整。</strong></p>
<p>一个完整的闭环包括：</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">写代码 → 运行代码 → 检查输出 → 发现问题 → 调试修复 → 重新运行</span><br></span></code></pre></div></div>
<p>如果任何一个环节断开，Claude Code 就会陷入"以为成功"的假象。</p>
<p><strong>实现方式：</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain"># 使用 stream-json 格式捕获完整执行过程</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">claude -p "完成任务 X，运行测试，确认全部通过后才算完成" \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  --dangerously-skip-permissions \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  --output-format stream-json \</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">  --verbose 2&gt;&amp;1 | python manager.py parse-and-monitor</span><br></span></code></pre></div></div>
<p>Manager 程序通过解析 JSON 日志：</p>
<ul>
<li class="">检测测试是否真正运行并通过</li>
<li class="">发现运行时错误并自动重试</li>
<li class="">超时保护，防止无限循环</li>
<li class="">统计成功率，持续优化提示词</li>
</ul>
<p><strong>效果：任务成功率从 20% 提升到 95%。</strong></p>
<p>这个数字揭示了一个重要事实：<strong>Agentic Coding 的成功率很大程度上取决于管理层的设计，而不仅仅是 AI 本身的能力。</strong></p>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-8自然语言编程">Step 8：自然语言编程<a href="https://luuman.github.io/claude-doc/blog/vibe-coding-at-scale#step-8%E8%87%AA%E7%84%B6%E8%AF%AD%E8%A8%80%E7%BC%96%E7%A8%8B" class="hash-link" aria-label="Step 8：自然语言编程的直接链接" title="Step 8：自然语言编程的直接链接" translate="no">​</a></h3>
<p>有了 Web Manager，下一步是让输入更自然。</p>
<p>胡渊鸣在输入框中集成了<strong>语音识别 API</strong>，实现了真正的"语音 vibe coding"：</p>
<ul>
<li class="">打开手机，对着麦克风说需求</li>
<li class="">语音转文字，自动发送给 Claude Code</li>
<li class="">Claude Code 开始执行，结果实时推送到手机</li>
</ul>
<p><strong>走在马路上都可以 vibe coding。</strong> 这不是比喻，是字面意义上的随时随地编程。</p>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-9添加-plan-mode">Step 9：添加 Plan Mode<a href="https://luuman.github.io/claude-doc/blog/vibe-coding-at-scale#step-9%E6%B7%BB%E5%8A%A0-plan-mode" class="hash-link" aria-label="Step 9：添加 Plan Mode的直接链接" title="Step 9：添加 Plan Mode的直接链接" translate="no">​</a></h3>
<p>在大量并行任务场景中，"先执行后发现方向错了"的成本极高。胡渊鸣封装了 Claude Code 的 <strong>Plan 模式</strong>：</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D6DEEB;--prism-background-color:#001122"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D6DEEB;background-color:#001122"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D6DEEB"><span class="token plain">用户提交需求</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    ↓</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">Claude Code 生成执行计划（不执行）</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    ↓</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">统一展示所有待处理实例的计划</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    ↓</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">用户批量 review，修改或确认</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">    ↓</span><br></span><span class="token-line" style="color:#D6DEEB"><span class="token plain">批量 kick off 执行</span><br></span></code></pre></div></div>
<p>这个模式的价值在于：<strong>用极低的成本（看一眼计划）过滤掉方向性错误，避免浪费几十分钟的执行时间。</strong></p>
<p>当同时有 10 个 Claude Code 在工作时，每个实例节省一次错误方向的执行，累计节省的时间相当可观。</p>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-10坚持不看代码">Step 10：坚持不看代码<a href="https://luuman.github.io/claude-doc/blog/vibe-coding-at-scale#step-10%E5%9D%9A%E6%8C%81%E4%B8%8D%E7%9C%8B%E4%BB%A3%E7%A0%81" class="hash-link" aria-label="Step 10：坚持不看代码的直接链接" title="Step 10：坚持不看代码的直接链接" translate="no">​</a></h3>
<p>这是最反直觉，也最重要的一步。</p>
<p>胡渊鸣制定了一条铁律：<strong>坚决不看 Claude Code 生成的具体代码。</strong></p>
<p>这不是懒惰，而是一种刻意的管理哲学：</p>
<blockquote>
<p>"Context, not control."（提供上下文，而不是微观管理。）</p>
</blockquote>
<p><strong>他真正关注的事情：</strong></p>





























<table><thead><tr><th>关注点</th><th>具体行动</th></tr></thead><tbody><tr><td>更好地提问</td><td>把需求描述得更精确、约束条件更清晰</td></tr><tr><td>第一性原理</td><td>质疑任务本身是否必要，而不是优化执行方式</td></tr><tr><td>给 AI 铺路</td><td>提前准备好 API 文档、架构说明、测试数据</td></tr><tr><td>科学版本控制</td><td>用 Git 记录一切，随时可以回滚</td></tr><tr><td>提高杠杆</td><td>思考如何让一个 Claude Code 的工作抵得上十个</td></tr></tbody></table>
<p><strong>杜绝 micromanagement 的本质是：相信系统，而不是相信单次执行的细节。</strong></p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="关键启示">关键启示<a href="https://luuman.github.io/claude-doc/blog/vibe-coding-at-scale#%E5%85%B3%E9%94%AE%E5%90%AF%E7%A4%BA" class="hash-link" aria-label="关键启示的直接链接" title="关键启示的直接链接" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="启示一标准化软件的终结">启示一：标准化软件的终结<a href="https://luuman.github.io/claude-doc/blog/vibe-coding-at-scale#%E5%90%AF%E7%A4%BA%E4%B8%80%E6%A0%87%E5%87%86%E5%8C%96%E8%BD%AF%E4%BB%B6%E7%9A%84%E7%BB%88%E7%BB%93" class="hash-link" aria-label="启示一：标准化软件的终结的直接链接" title="启示一：标准化软件的终结的直接链接" translate="no">​</a></h3>
<p>当一个 CEO 可以在手机上用语音随时指挥 10 个 AI 实例并行开发软件，<strong>软件开发的成本正在趋近于零</strong>。</p>
<p>这意味着：</p>
<ul>
<li class="">任何人都可以拥有完全匹配自己工作流的定制化工具</li>
<li class="">标准化 SaaS 软件的竞争优势将持续减弱</li>
<li class="">未来的软件可能不再是"产品"，而是"实时生成的工具"</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="启示二管理-ai-比管人更能提高领导力">启示二：管理 AI 比管人更能提高领导力<a href="https://luuman.github.io/claude-doc/blog/vibe-coding-at-scale#%E5%90%AF%E7%A4%BA%E4%BA%8C%E7%AE%A1%E7%90%86-ai-%E6%AF%94%E7%AE%A1%E4%BA%BA%E6%9B%B4%E8%83%BD%E6%8F%90%E9%AB%98%E9%A2%86%E5%AF%BC%E5%8A%9B" class="hash-link" aria-label="启示二：管理 AI 比管人更能提高领导力的直接链接" title="启示二：管理 AI 比管人更能提高领导力的直接链接" translate="no">​</a></h3>
<p>在传统管理中，给一个下属安排任务后，你需要等待数天才能得到反馈。而管理 Claude Code：</p>
<ul>
<li class=""><strong>反馈周期：5 分钟</strong></li>
<li class=""><strong>并发数量：理论上无限</strong></li>
<li class=""><strong>成长速度：每天迭代数十次，是人类的 100 倍</strong></li>
</ul>
<p>这意味着 AI 时代的领导力核心技能发生了根本性转变：<strong>从"如何做"转向"做什么"，从执行优化转向方向判断</strong>。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="启示三重新审视学习的意义">启示三：重新审视"学习"的意义<a href="https://luuman.github.io/claude-doc/blog/vibe-coding-at-scale#%E5%90%AF%E7%A4%BA%E4%B8%89%E9%87%8D%E6%96%B0%E5%AE%A1%E8%A7%86%E5%AD%A6%E4%B9%A0%E7%9A%84%E6%84%8F%E4%B9%89" class="hash-link" aria-label="启示三：重新审视&quot;学习&quot;的意义的直接链接" title="启示三：重新审视&quot;学习&quot;的意义的直接链接" translate="no">​</a></h3>
<p>如果 AI 可以完成大量的执行性工作，人类的学习目标也需要重新定义：</p>
<p>不是学习如何编写更好的代码，而是学习<strong>如何提出更好的问题</strong>。不是积累技术细节，而是建立<strong>跨领域的第一性原理思维</strong>。</p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="核心技术栈总结">核心技术栈总结<a href="https://luuman.github.io/claude-doc/blog/vibe-coding-at-scale#%E6%A0%B8%E5%BF%83%E6%8A%80%E6%9C%AF%E6%A0%88%E6%80%BB%E7%BB%93" class="hash-link" aria-label="核心技术栈总结的直接链接" title="核心技术栈总结的直接链接" translate="no">​</a></h2>

































































<table><thead><tr><th>技术/工具</th><th>用途</th><th>对应阶段</th></tr></thead><tbody><tr><td><code>claude --dangerously-skip-permissions</code></td><td>无人值守自动执行</td><td>Step 2</td></tr><tr><td>AWS EC2</td><td>云端弹性计算容器</td><td>Step 2</td></tr><tr><td>Ralph Loop</td><td>持续任务调度机制</td><td>Step 3</td></tr><tr><td>CLAUDE.md</td><td>项目规范与约束定义</td><td>Step 3、5</td></tr><tr><td>PROGRESS.md</td><td>经验教训持久化</td><td>Step 5</td></tr><tr><td>Git Worktree</td><td>多实例并行隔离</td><td>Step 4</td></tr><tr><td><code>claude -p --output-format stream-json</code></td><td>程序化调用与监控</td><td>Step 6、7</td></tr><tr><td>Python subprocess</td><td>Claude Code 进程管理</td><td>Step 6</td></tr><tr><td>Web Manager + PWA</td><td>手机端管理界面</td><td>Step 6</td></tr><tr><td>语音识别 API</td><td>自然语言输入</td><td>Step 8</td></tr><tr><td>Plan Mode 封装</td><td>批量任务预审</td><td>Step 9</td></tr></tbody></table>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="可复用的行动清单">可复用的行动清单<a href="https://luuman.github.io/claude-doc/blog/vibe-coding-at-scale#%E5%8F%AF%E5%A4%8D%E7%94%A8%E7%9A%84%E8%A1%8C%E5%8A%A8%E6%B8%85%E5%8D%95" class="hash-link" aria-label="可复用的行动清单的直接链接" title="可复用的行动清单的直接链接" translate="no">​</a></h2>
<p>如果你想复刻胡渊鸣的部分实践，可以按以下顺序逐步推进：</p>
<ul class="contains-task-list containsTaskList_mC6p">
<li class="task-list-item"><input type="checkbox" disabled=""> <strong>起点</strong>：在本地用 <code>claude --dangerously-skip-permissions</code> 跑一个完整任务，感受无打断的体验</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <strong>容器化</strong>：将工作环境迁移到云端 EC2，确保 24 小时可访问</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <strong>任务列表</strong>：建立 PROGRESS.md，记录第一个踩坑经验</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <strong>并行化</strong>：用 Git Worktree 同时开两个 Claude Code 处理不同功能分支</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <strong>监控闭环</strong>：用 <code>stream-json</code> 输出接入简单的监控脚本，检测任务真实成功率</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <strong>Plan 先行</strong>：对所有超过 30 分钟的任务，强制先用 Plan 模式审查方向</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <strong>不看代码</strong>：连续一周只看测试结果和功能演示，训练自己放弃 micromanagement</li>
</ul>]]></content:encoded>
            <category>Claude Code</category>
            <category>教程</category>
            <category>并行开发</category>
            <category>效率提升</category>
        </item>
    </channel>
</rss>