# 把代码仓库变成 AI 可用的智能工作区：Repowise 实战教程

> 来源：MarkTechPost《How to Build Repository-Level Code Intelligence with Repowise Using Graph Analysis, Dead-Code Detection, Decisions, and AI Context》  
> 原文链接：https://www.marktechpost.com/2026/05/15/how-to-build-repository-level-code-intelligence-with-repowise-using-graph-analysis-dead-code-detection-decisions-and-ai-context/  
> 提炼目标：不是复刻原文脚本，而是整理成一套可分享、可执行、可迁移到真实项目的仓库智能工作流。

## 0. 这篇教程解决什么问题？

很多团队让 AI 编程助手理解项目时，默认做法是：

- 把一堆文件塞进上下文；
- 让 agent 自己全仓搜索；
- 人工口头解释项目结构；
- 生成很长但不稳定的 `CLAUDE.md` / `AGENTS.md`。

问题是：这种方式噪音高、不可复用，也很难判断 AI 到底理解了哪些关键结构。

更好的做法是：**先把代码仓库转成结构化信号，再把高价值信号交给 AI。**

Repowise 的价值就在这里：它把仓库索引、依赖图、核心文件排序、Git 信息、死代码候选、架构决策和 AI 上下文生成串起来，让普通代码仓库变成一个 repository-level code intelligence 系统。

一句话：**不要让 AI 直接“读整个仓库”，先让工具把仓库压缩成可分析、可查询、可验证的工程地图。**

---

## 1. 最终你会得到什么？

跑完这套流程后，你至少能得到 6 类结果：

1. `.repowise/` 仓库索引与图谱文件；
2. 高影响文件列表，例如 PageRank Top 10；
3. 模块社区划分，帮助理解代码边界；
4. Git / 维护风险信息；
5. 死代码候选列表；
6. 面向 AI 编程助手的 `CLAUDE.md` 项目上下文。

这些产物可以用于：

- 接手陌生项目；
- 重构前做风险扫描；
- 给 Claude Code / Codex / Gemini CLI 准备项目上下文；
- 建立团队架构决策记录；
- 缩短新人 onboarding 时间。

---

## 2. 适用场景与不适用场景

### 适合

- Python / Node / 常规源码仓库；
- 中小型项目的首次结构梳理；
- 准备让 AI agent 修改代码前的上下文准备；
- 需要识别核心文件、模块边界、潜在死代码的项目；
- 想把架构决策沉淀到代码附近的团队。

### 不适合直接照搬

- 超大型 monorepo；
- 插件入口、反射调用、动态加载很多的项目；
- 测试覆盖很低、删除风险很高的生产仓库；
- 希望工具自动决定“哪些代码可以删”的场景。

注意：**死代码检测只能当候选发现，不能当自动删除依据。**

---

## 3. 准备环境

本文以一个 Python 项目为例。你可以先用 demo 仓库练手，再迁移到自己的项目。

```bash
# 建议在临时目录练习
mkdir -p ~/tmp/repo-intelligence-demo
cd ~/tmp/repo-intelligence-demo

# 克隆示例项目
git clone https://github.com/pallets/itsdangerous.git
cd itsdangerous

# 建议先建虚拟环境
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -U pip
```

安装 Repowise：

```bash
pip install -U repowise
repowise --version
repowise init --help
```

如果你只想生成基础索引，可以先不配置 LLM API key。  
如果你要使用自然语言查询、架构解释等能力，再设置相关环境变量：

```bash
# 二选一即可；不要把 key 写进代码或仓库
export ANTHROPIC_API_KEY="你的 key"
# 或
export OPENAI_API_KEY="你的 key"
```

---

## 4. 第一步：初始化仓库智能索引

先在目标仓库根目录创建 Repowise 配置：

```bash
mkdir -p .repowise
cat > .repowise/config.yaml <<'YAML'
provider: mock
model: mock
embedding_model: voyage-3
reasoning: auto

git:
  co_change_commit_limit: 200
  blame_enabled: true

dead_code:
  enabled: true
  safe_to_delete_threshold: 0.7

maintenance:
  cascade_budget: 10
YAML
```

如果你已经设置了 Anthropic 或 OpenAI key，可以把 provider/model 改成真实模型，例如：

```yaml
provider: anthropic
model: claude-sonnet-4-5
```

或：

```yaml
provider: openai
model: gpt-4o-mini
```

然后初始化：

```bash
# 无 LLM key 时，优先只建索引
repowise init . --index-only

# 有 LLM key 时，可以运行完整初始化
# repowise init .
```

检查生成物：

```bash
find .repowise -maxdepth 3 -type f -print
```

你要确认至少有索引、图谱或元数据类文件生成。不同版本文件名可能不同，不要死记文件名，重点是确认 `.repowise/` 下面有可分析产物。

---

## 5. 第二步：把仓库看成一张依赖图

目录树只能告诉你“文件放在哪里”，图谱才能告诉你“文件之间如何连接”。

安装分析依赖：

```bash
pip install networkx matplotlib
```

创建脚本 `analyze_repo_graph.py`：

```python
from pathlib import Path
import json

import networkx as nx

ROOT = Path.cwd()
REPOWISE_DIR = ROOT / ".repowise"


def load_graph() -> nx.Graph | None:
    for path in REPOWISE_DIR.rglob("*"):
        if not path.is_file():
            continue
        if "graph" not in path.name.lower():
            continue

        try:
            if path.suffix == ".json":
                data = json.loads(path.read_text())
                if isinstance(data, dict) and "nodes" in data:
                    return nx.node_link_graph(data)
            if path.suffix == ".gml":
                return nx.read_gml(path)
            if path.suffix == ".graphml":
                return nx.read_graphml(path)
        except Exception as exc:
            print(f"skip {path}: {exc}")

    return None


def main() -> None:
    graph = load_graph()
    if graph is None:
        print("没有找到 graph artifact；请先检查 .repowise/ 文件树。")
        return

    print(f"nodes={graph.number_of_nodes()} edges={graph.number_of_edges()}")

    pagerank = nx.pagerank(graph)
    print("\nTop 10 files/modules by PageRank:")
    for node, score in sorted(pagerank.items(), key=lambda item: -item[1])[:10]:
        print(f"{score:.4f}\t{node}")

    try:
        from networkx.algorithms.community import greedy_modularity_communities

        communities = list(greedy_modularity_communities(graph.to_undirected()))
        print(f"\ncommunities={len(communities)}")
        print("top community sizes:", [len(c) for c in communities[:8]])
    except Exception as exc:
        print(f"community detection skipped: {exc}")


if __name__ == "__main__":
    main()
```

运行：

```bash
python analyze_repo_graph.py
```

你要看三个结果：

- `nodes / edges`：图谱规模；
- PageRank Top 10：优先阅读和高风险修改的候选文件；
- communities：代码自然聚类，可能对应模块边界。

---

## 6. 第三步：用 PageRank 找核心文件

PageRank 原本用于网页排序，放在代码仓库里可以粗略回答：

> 哪些文件处在依赖网络的关键位置？

使用方式：

1. 新人接手项目时，先读 PageRank Top 5；
2. 修改核心文件前，要求更严格的测试；
3. 让 AI agent 从高影响文件开始理解项目；
4. 如果某个低层工具文件 PageRank 很高，说明它可能是全局风险点。

但不要误用：

- PageRank 高 ≠ 业务价值最高；
- PageRank 低 ≠ 可以忽略；
- 动态调用、插件入口、配置驱动逻辑可能不会被图谱完整捕捉；
- 最终判断必须结合测试、Git 历史和人工理解。

---

## 7. 第四步：用社区检测理解模块边界

社区检测可以帮你发现：

- 哪些文件天然成组；
- 目录结构和真实依赖结构是否一致；
- 哪些模块边界模糊；
- 重构时应该按什么边界拆任务。

可落地用法：

```text
如果一个目录里的文件被分进多个社区：
  可能说明目录命名过粗，或职责混杂。

如果多个目录的文件长期聚在同一社区：
  可能说明它们实际属于同一个功能模块。

如果某个文件连接多个社区：
  它可能是 glue code，也可能是过度耦合点。
```

这类信息很适合放进 AI 任务提示：

```text
请优先阅读 PageRank Top 5 文件，并注意 graph community 2 与 community 4 之间的交叉依赖。不要直接重构跨社区接口，先给出影响面分析。
```

---

## 8. 第五步：检查 Git 与维护风险

运行：

```bash
repowise status
```

如果工具支持 Git 共变分析，你要重点看：

- 哪些文件经常一起改；
- 哪些文件最近改动频繁；
- 哪些文件长期无人维护；
- 哪些结构依赖和 Git 共变关系不一致。

结构依赖回答的是：

> 代码上谁依赖谁？

Git 共变回答的是：

> 维护时哪些文件经常一起动？

这两个信号结合起来，才更适合判断修改风险。

---

## 9. 第六步：运行死代码检测，但不要自动删除

运行：

```bash
repowise dead-code
repowise dead-code --safe-only
```

正确姿势：把输出当成候选清单，再进入人工审查。

建议使用这张检查表：

```text
死代码候选审查 checklist：
[ ] 是否有测试覆盖？
[ ] 是否可能被 CLI 入口调用？
[ ] 是否可能被插件系统调用？
[ ] 是否可能通过反射、字符串、配置动态调用？
[ ] 是否是外部用户依赖的 public API？
[ ] 删除后是否能跑完整测试？
[ ] 是否可以先 deprecate，而不是直接删除？
```

安全原则：**工具只能提出“可能没用”，不能替你承担删除责任。**

---

## 10. 第七步：把架构决策写到代码附近

原文演示了在源码里写入类似注释：

```python
# DECISION: Signers are stateless by design — secrets are passed at
# construction so signing can be parallelised safely.
```

这个思路值得保留：架构决策越靠近相关代码，越不容易过期。

你可以在团队里约定三类标签：

```python
# DECISION: 为什么这里这样设计，不采用另一种方案？
# TECH_DEBT: 已知技术债是什么？什么时候必须处理？
# SAFETY: 这里的安全边界是什么？哪些行为禁止修改？
```

然后让工具汇总：

```bash
repowise update .
repowise decision list
repowise decision health
```

如果你的团队暂时不用 Repowise，也可以先用简单命令建立习惯：

```bash
grep -R "DECISION:\|TECH_DEBT:\|SAFETY:" -n src tests > architecture-notes.txt
```

---

## 11. 第八步：生成 AI 编程助手上下文

运行：

```bash
repowise generate-claude-md
```

生成后，不要直接盲信。你需要人工审查 `CLAUDE.md` 是否满足这几个要求：

```text
AI 上下文文件审查 checklist：
[ ] 是否说明项目用途？
[ ] 是否列出入口文件和核心模块？
[ ] 是否包含构建、测试、格式化命令？
[ ] 是否标明高风险文件或禁止修改区域？
[ ] 是否保留关键架构决策？
[ ] 是否短到 agent 能真正使用？
[ ] 是否没有泄露密钥、内部地址、token？
[ ] 是否没有把死代码候选写成“可以删除”？
```

一个好的 `CLAUDE.md` / `AGENTS.md` 不应该是项目百科，而应该是 **agent 的导航图**。

---

## 12. 第九步：如果有 LLM key，做自然语言查询

有 LLM 配置时，可以尝试：

```bash
repowise search "URL-safe token signing"
repowise query "How does Signer detect tampered payloads?"
repowise query "What is risky about changing signer.py?"
repowise query "Produce a Mermaid diagram of the package"
```

查询结果不要当结论，应该当“带引用的候选解释”。

建议要求 AI 输出：

```text
请回答这个模块的作用，并列出你依据的文件路径。
如果缺少证据，请明确说不知道，不要猜。
```

---

## 13. 推荐落地流程：从 demo 到真实项目

### 第 1 天：只读试跑

目标：不改代码，只生成索引和图谱。

```bash
repowise init . --index-only
find .repowise -maxdepth 3 -type f -print
python analyze_repo_graph.py
```

产出：

- PageRank Top 10；
- 社区数量与主要模块；
- 初步风险观察。

### 第 2 天：维护信号试跑

目标：识别风险，不做删除。

```bash
repowise status
repowise dead-code
repowise dead-code --safe-only
```

产出：

- Git 风险线索；
- 死代码候选；
- “需要人工确认”的列表。

### 第 3 天：AI 上下文试生成

目标：生成但不直接采用。

```bash
repowise generate-claude-md
```

产出：

- `CLAUDE.md` 草稿；
- 人工审查后的短版项目上下文；
- 给 Claude Code / Codex 的起始文件清单。

---

## 14. 可复制的 agent 提示词

当你拿到仓库智能结果后，可以这样给 coding agent 下任务：

```text
你要先阅读仓库智能摘要，不要全仓盲搜。

已知信息：
- PageRank Top 10 文件：<粘贴列表>
- 主要社区/模块：<粘贴模块边界>
- Git 共变风险：<粘贴风险文件>
- 死代码候选：<粘贴候选，但不要删除>

任务：
1. 先解释你认为的项目结构。
2. 标出本次修改可能影响的文件。
3. 给出验证命令。
4. 未经确认，不要删除死代码候选。
5. 如果证据不足，明确说需要继续检查哪些文件。
```

---

## 15. 最小可落地版本

如果你不想一开始就引入完整工具链，可以先做这 4 件事：

1. 生成依赖图；
2. 算 PageRank，找核心文件；
3. 用 `DECISION:` / `TECH_DEBT:` / `SAFETY:` 写近代码注释；
4. 把结果整理成 1 页 `AGENTS.md` 或 `CLAUDE.md`。

最小产物模板：

```markdown
# Project Context for AI Agents

## Project purpose
一句话说明项目做什么。

## Start here
- path/to/core_file.py — 为什么重要
- path/to/entrypoint.py — 为什么重要

## High-risk areas
- path/to/risky_module.py — 修改前必须跑哪些测试

## Architecture decisions
- DECISION: xxx
- SAFETY: xxx

## Commands
- test: `...`
- lint: `...`
- run: `...`

## Do not
- 不要自动删除 dead-code 候选
- 不要修改安全边界文件，除非任务明确要求
```

---

## 16. 常见坑

### 坑 1：把工具输出当真理

图谱、PageRank、死代码检测都是信号，不是裁决。

### 坑 2：生成过长的 AI 上下文文件

AI 上下文文件越长，越容易变成噪音。保留入口、风险、命令和决策就够了。

### 坑 3：忽略动态入口

CLI、插件、反射、配置加载、外部 API 调用，可能不会完整出现在静态图谱里。

### 坑 4：把 demo 阈值当通用标准

例如 `safe_to_delete_threshold: 0.7` 只能看作工具示例，不应变成团队统一规则。

### 坑 5：把 Repowise 直接塞进生产流程

先用只读方式试跑，确认输出有用，再考虑接入 CI 或团队流程。

---

## 17. 总结

这篇文章真正值得带走的不是某条 Repowise 命令，而是一种工作流：

> 先把仓库结构化，再让 AI 使用结构化结果。

可执行路径是：

1. 建索引；
2. 读依赖图；
3. 用 PageRank 找核心文件；
4. 用社区检测看模块边界；
5. 用 Git 信号判断维护风险；
6. 把死代码当候选，不自动删除；
7. 用代码邻近注释记录架构决策；
8. 生成短小、可审查的 AI 上下文文件。

如果你经常让 AI agent 处理陌生仓库，这套流程能显著减少“让模型自己乱翻项目”的成本。它的核心原则很简单：**AI 不缺读取能力，缺的是干净、排序过、可验证的上下文入口。**
