内容
DevRAG
适用于开发团队的本地 RAG 系统,可索引 **代码**、**GitHub 拉取请求**、**GitHub 问题**、**Jira Cloud 工单**、**Slite 页面**、**Slack 对话**、**文档**和aude Code 会话日志通过 Claude Code 斜杠命令和独立的 CLI 提供支持。设计用于零摩擦采用:索引您的仓库,立即搜索。
## 为什么选择 DevRAG?
大多数代码搜索工具将源文件视为纯文本。DevRAG 使用 **tree-sitter AST 解析**,按照语义边界(函数、类、方法)分割代码,以便有意义的单元,而不是在函数中间分割的片段。
它将 **向量搜索**(语义)与25**(关键词)相结合,通过 Qdrant 的服务器端 Reciprocal Rank Fusion,这是代码所必需的,因为像 `refreshToken` 这样的确切标识符与“令牌概念一样重要。两个信号都作为命名向量存储在 Qdrant 中(`dense` + `bm25`),因此搜索对于每个集合都是一次性旅程,并且元数据过滤器同样适用于两条腿。
PR 历史、问题、Jira 工单和 Slite wiki 页面是一流的数据源,编码了 *为什么* 代码更改、跟踪了哪些错误和功能、存在什么项目管理上下文以及内部知识库内容。
## 快速入门
### 安装
直接Hub 安装(无需克隆):
```bash
# 作为全局 CLI 工具(推荐)
uv tool install git+https://github.com/tomharris/dev-rag.git
# 或在不安装的情况下运行
uvx --from git+https://github.com/tomharris/dev-rag.git devrag --help
# 或作为项目依赖项添加
uv add git+https://github.com/tomharris/dev-rag.git
# pip install git+https://github.com/tomharrisrag.git
```
(从源代码):
```bash
git clone https://github.com/tomharrisrag.git
cd dev
uv sync
devrag --help
索引和搜索
```bash
# 当前仓库
dev repo .
# 跨PR、问题和
devrag search "身份验证"
# 检查的内容
devrag status
要求
- Python 3.12 [Ollama](ama.com/)运行,并拉取 `nomic-embed-text`:
```bash
ollomic-embed-text
```
### 网络阻止 Hugging Face 的模型
AG 的重新排序器25 模型来自 Hugging Face。在首次使用时从 dev-rag Git中下载一个自包(即使face.co 被阻止),本地缓存;后续运行将离线加载。要显
```bash
devrag download-models # 获取/刷新模型包
devrag download-models --force # 重新下载,即使已缓存
```
覆盖(在 `~/.config/devrag/devrag.yaml` 或 `.devrag.yaml` 中):
```yaml
network:
auto_download_models: true # false 以禁用自动获取(CI/隔离 model_bundle_url: "" 内部/镜像的模型包
model_bundle_sha256: "" # 自定义 model 的预期校验_embedding:
cache_dir: "" # 缓存;"" = ~/.cache/devrag/fastembed
```
注意:该包携带 **默认** 模型名称。如果您覆盖 `retrieval.reranker_model` 或 `sparse_embedding.model`,则需要 Hugging Face(或忠实的镜像)访问您选择的模型。
## CLI 参考
搜索
```bash
dev "查询" # 搜索所有来源
devrag search "查询" --scope code # 仅代码
devrag search " --scope prs 仅 PR 历史rag search "查询" issues #
devrag search "查询" --scope slite 仅 Sliterag search "查询scope slack # Slack 对话
devrag search "查询" --scope docs # 仅文档
devrag search "查询" --scope sessions # Code 会话日志
devrag search "查询" --top-k 10 结果
# 使用元数据过滤器缩小范围可选,AND devrag search "身份验证" --repo myrepo --chunk-type diff
devrag search "错误" --pr-number 1234
devrag search "退款流程"-key PROJ-123
devrag search "部署" --session-id <uuid>
devrag search "事件" --channel C0123ABCD Slack 频道 ID
```
查询路由器自动分类意图并定位相关集合。“为什么我们切换到 Redis?”路由到 PR 历史;“登录是否有错误?”路由到问题和 Jira 工单;“身份验证在哪个冲刺阶段?”路由到 Jira关于部署,wiki什么?”路由到 页面和文档;“中间件如何工作到代码。
###引
```bash
# 代码(AST 感知增量;也的文档)
devrag index repo . # 当前目录(代码 + 文档)
index repo /path/to # 指定路径
devrag index repo . -- # 强制索引
devrag index repo . --name my-repo # 多仓库支持的名称
devrag index repo . --no-docs # 仅代码,跳过仓库的文档
devrag index remove-repo my-repo # 从索引中删除仓库(代码 + 文档)
index refresh 重新索引所有已注册的仓库(增代码 + 文档)
devrag index refresh --full 每个已注册仓库的完全重建(外部)
# `index repo` 也会索引仓库自己的文档(md/mdx/txt/rst/html/ad到
# 文档集合中,并使用仓库名称因此 `search --repo <name>`
# 缩它们)。使用 `index docs` 仅用于文档树。
# 文档(部分感知的分割目录,不绑定到仓库)
devrag index docs ./ # 默认:**/*.md
devrag ./docs --glob "**/*.txt,**/*.rst"
# 拉取请求(增量,带有光标跟踪)
export GITHUB_TOKEN=ghp_xxx
devrag index prs owner/repo # 从光标增量(首次运行 90 天)
devrags owner/repo 180d # 覆盖光标以回 GitHub 问题,跳过 PR)
devrag index issues # 最近 天
devrag index issues owner/repo --since 30d # 自定义回溯
# Jira Cloud(通过 JQL量)
export JIRA_EMAIL=you@companyexport JIRA_TOKEN-api-token
devrag index jira # 使用 .devrag.yaml 中的 JQLrag index jira --since 180d # 自定义回溯
# Slite 页面(增量,部分感知的分块)
export SLITE_TOKEN=your-api-token
devrag index slite # 最近 90 天,所有频道
devrag index slite --since 30d # 自定义回溯
# Slack 对话 — 无需 Slack 应用(使用您的浏览器会话)
export SLACKXC_TOKEN=xoxc- #客户端令牌(无应用的 Slack”)
export SLACK_XOXD_COOKIE=xoxd-... # `d`
devrag # 您所在的,最后 90 天
devrag index slack --d #同步回溯
Code 会话日志 JSONL,文件 mtime 增量)
devrag index sessions # 从光标增量(首次运行 60 天)
devrag index sessions --since 30d # 覆盖光标
devrag index sessions --logs-dir /custom/path
```
#### 无应用的 Slack
大多数 Slack 集成需要创建 Slack 应用并管理员使用 OAuth安装。DevR过了这一点:它** 的登录身份验证,使用与浏览器相同的凭证——因此无需管理员批准,并且索引您已经可以看到相同。
**自动获取凭证**(推荐;您 Slack 桌面应用或浏览器):
```eval "$(devrag auth slack --workspace mycorp # mycorp =<x>.slack.com 中的 <x>
slack
```
`devrag auth slack` **Slack 桌面应用两个凭证——` 从其 cookie`xoxc` 令牌从其(Slack 现在在其中存储令牌;它任何网页上)并打印两个` 行,以便 "$(…)"` shell 中设置 `_XOXC_TOKEN`SLACK_X_COOKIE`。桌面应用是一个 Chromium 应用,因此其 cookie 存储使用与浏览器解密(无需额外 localStorage 使用的纯 Python LevelDB 读取器读取——在 Slack 运行时(存储首先被向磁盘写入任何内容)。在 `.dev` 中设置 `` 以跳的 `--workspace--browser`式选择源:`(桌面应用)或 `chrome`fox`/`bra/`edge`/`/`brave`。如果没有 `--browserrag 首先尝试桌面应用,然后扫描每个支持的浏览器,跳过任何其无法读取的配置文件——因此不支持/或浏览器不会中止搜索。cookie 必须位于命令的机器上您仅在上登录,或者您的浏览器将配置文件存储标准位置,请` 或手动<details>
<summary>手动备用</ — 如果 cookie 解锁定密钥环 / Chrome 应用绑定加密)</summary>
从浏览器中提取两个凭证(在网页):
1. 打开 Slack → 开发工具(F12)→ **控制台**。
2. 令牌(`xoxc-…`):运行
`JSON.parse(localStorage.localConfig_v2).teams[Object.keys(JSON.parse(localStorage.localConfig_v2).teams)[0]].token`
(或在应用程序 → 本地存储中找到 `xoxc-`)。
3. Cookie(`xoxd-…` → ** Cookie → `https://app.slack.com`** → 复制
名称为 **`d`** 值(如果需要码 `%2 `/` 等)。
`export SLACK_XOXC_TOKEN-…`export SLACK_XOKIE=xox…`,然后devrag`。
</details范围:** 默认情况下,您所属的公共频道索引特定频道(),请在 `..yaml` 下的ack.channel_ids`允许列表。线程作为单个块索引;的频道聊天被分组到时间窗口块中 ⚠️ **** 这些是个人官方 API ,并且使用 Slack 的 与严格阅读 Slack 服务条款相矛盾 —有权读取内容中使用风险自负牌/cookie ** 当您的浏览器会话或您注销时这种情况时,rag index slack`,并出现明确的浏览器重新提取”错误,而不是静默索引。
是 **增量的** — 文件内容哈希 SQLite 中,因此在时跳过未。
### 其他命令bash
dev # 显示索引
devrag serve 为 Claude Code 启动 MCP 服务器
devrag reindex --all #所有索引并重新仓库 + 它们的同步 PR//Slitedevrag rename my_project 重新索引单个仓库 文档(保留外部源)
devrag config set embedding.model nomic-embed-text
devrag config get vector_store.backend
```
### 评估
使用查询和预期结果的 JSONL 文件测试检索质量:
```devrag eval run test_queries.jsonl --output results.jsonl --top-k 5
devrag eval compare results_v1.jsonl results_v2.jsonl
```
查询文件格式:
```jsonl
{"query": "速率限制如何工作?", "expected_files": ["src/middleware/rate_limit.ts"]}
{"query": "为什么我们迁移到 Redis?", "expected_prs": [1234, 1301]}
```
指标:精度@k、召回率@k 和 MRR(平均倒数排名)。
## Claude Code 集成
DevRAG 附带一个 [FastMCP](https://github.com/jlowin/fastmcp) 服务器,直接与 Claude Code 集成。
### 设置
```bash
# 如果通过 `uv tool install` 全局安装:
claude mcp add devrag -- devrag serve
# 或在不安装的情况下按需运行:
claude mcp add devrag -- uvx --from git+https://github.com/tomharris/dev-rag.git devrag serve
```
### 技能
存储库在 `.claude/skills/` 中包含 Claude Code 技能:
| 技能 | 描述 |
|-------|-------------|
| `/rag-search <query>` | 搜索代码、PR 和文档,结果按来源类型分组 |
| `/rag-index [path]` | 索引仓库、文档目录或同步 PR |
| `/rag-pr <query>` | 搜索 PR 历史记录以了解代码更改原因 |
| `rag-first` (自动)| 自动触发于代码库问题,以在 Grep/Glob/Explore 之前搜索 DevRAG |
`rag-first` 技能在 Claude 检测到代码库问题时自动触发 — 无需斜杠命令。
为了确保安全,存储库附带 `.claude/hooks/rag_first_gate.py` — 一个每轮阻塞门,**拒绝** 轮中的第一个 `Grep`、`Glob` 或 `Agent`(`Explore` / 通用目的)调用,直到运行 `mcp__devrag__search`,然后释放轮的其余部分。脚本被跟踪,但钩子注册因用户而异。要启用它,请将此 `hooks` 块添加到您的 `.claude/settings.local.json`(与 `permissions` 放在一起):
```jsonc
"hooks": {
"PreToolUse": [
{
"matcher": "Grep|Glob|Agent",
"hooks": [{
"type": "command",
"command": "python3 ${CLAUDE_PROJECT_DIR}/.claude/hooks/rag_first_gate.py",
"timeout": 5
}]
}
],
"PostTool [
{
"matcher": "mcp__devrag__search",
"hooks": [{
"type": "command",
"command": "python3 ${CLAUDE_PROJECT_DIR}/.claude/hooks/rag_first_gate.py",
"timeout": 5
}]
}
],
"UserPromptSubmit": [
matcher": "",
"hooks": [{
"type": "command",
"command": "python3 ${CLAUDE_PROJECT_DIR}/.claude/hooks/rag_first_gate.py",
"timeout": 5
}]
}
]
}
```
编辑后重启您的 Claude Code 会话,以便钩子注册。
## 架构
```
┌─────────────────────────────────────────────────────────────────────┐
开发人员接口 │
│ CLI() MCP 服务器(FastMCP)│ devragindex|status Code 斜杠命令 │
└────────────┬───────────────────────────────────────┘ │ │
▼
─────────────────────────────────────┐ 检索层 │
│ 查询路由器 ──→ 混合搜索(服务器端密集 + BM25 RRF) ──→ 重新排序器│
│ (意图 → 集合) (跨编码器) │
│ └─→ 仓库偏好提升 ──→ 每个来源去重 ──→ 最终 k │
└────────────┬────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 存储层 │
│ QdrantStore(HTTP 或嵌入式本地路径) │
│ 点携带命名向量:{dense, bm25 sparse} │
│ SQLite:文件哈希、块映射、同步光标、指标 │
└────────────┬────────────────────────────────────────────────────────┘
▼
┌─────┐ ingestion │
│ 问题 Jira Slite │
│ 索引器 器 索引器 索引器 索引器 索引器 │
│ (AST) (GitHub) (GitHub) (部分) │
│ Ollama nomic-embed-text,768d │
└─────────────────────────────────────────────────────────────────────┘
```
### 集合 集合 | 来源 | 内容 |
|-----------|--------|----------|
| `code_chunks` | 代码索引器 | AST 提取的函数、类、方法 |
| `pr_diffs` | PR 索引器 | PR 描述和文件级差异块 |
|_discussions` |索引器 | 审查评论和线程 |
| `issue_descriptions` | 问题索引器 | 问题标题和正文 |
| `issue_discussions` | 问题索引器 | 问题评论 |
| `jira_descriptions` | Jira 索引 Jira 工单摘要和描述 `jira_discussions` | 索引器 | Jira评论 |
| `slite_pages` | Slite 索引器 | Slite 页面部分(markdown) |
| `_messages` | Slack 索引器 | Slack 线程和时间 |
documents` | 文档索引器 | Markdown/文本部分 |
| `session_logs` | 会话索引器 | 来自本地 JSONL 的 Claude Code 用户 ↔ 助手交换 |
## 配置
DevRAG 使用 YAML 配置文件,具有两层结构(项目配置覆盖用户配置):
- **用户配置:** `~/.config/devrag/devrag.yaml`
- **项目配置:** `.devrag.yaml` (提交此文件以便与团队共享)
```yaml
embedding:
model: nomic-embed-text # 嵌入模型名称
provider: ollama # ollama 或 sentence-transformers
ollama_url: http://localhost:11434
batch_size: 64
max_tokens: 8192 # 嵌入上下文截断限制
vector_store:
qdrant_url: http://localhost:6333 # Qdrant HTTP 端点
qdrant_path: "" # 可选:嵌入模式下的本地文件系统路径(无需服务器)
embedding_dim: 768 # 向量维度
retrieval:
top_k: 20 # 重新排序前的候选数量
final_k: 5 # 重新排序后的结果数量(在整个池中进行重复数据删除)
rerank: true
reranker_model: cross-encoder/ms-marco-MiniLM-L-6-v2
reranker_max_length: 512 # 交叉编码器 token 限制;提高以支持更长的块
max_per_source: 2 # 每个文件/PR/问题等的最大结果数
repo_boost: 0.15 # 当前工作目录仓库的软优先级(分数范围的分数;0 = 关闭)
code:
chunk_max_tokens: 512
respect_gitignore: true
exclude_patterns:
- "*.min.js"
- "vendor/**"
- "node_modules/**"
- "*.lock"
- "*.generated.*"
prs:
github_token_env: GITHUB_TOKEN # 环境变量名称(令牌从不存储在配置中)
backfill_days: 90
include_draft: false
chunk_max_tokens: 512 # 每个 PR 分块的最大 token 数
issues:
github_token_env: GITHUB_TOKEN # 与 PR 重用相同的令牌
backfill_days: 90
chunk_max_tokens: 512
include_labels: [] # 仅索引带有这些标签的问题(空 = 所有)
exclude_labels: ["wontfix"] # 跳过带有这些标签的问题
jira:
jira_token_env: JIRA_TOKEN # API 令牌的环境变量
jira_email_env: JIRA_EMAIL # 电子邮件的环境变量(基本身份验证)
instance_url: https://yoursite.atlassian.net
jql: "project = DEV" # 用于范围 tickets 的 JQL 过滤器
backfill_days: 90
chunk_max_tokens: 512
slite:
slite_token_env: SLITE_TOKEN # API 令牌的环境变量
channel_ids: [] # 过滤到特定频道(空 = 所有)
backfill_days: 90
chunk_max_tokens: 512
chunk_overlap_tokens: 50
slack:
slack_token_env: SLACK_XOXC_TOKEN # xoxc web 客户端令牌的环境变量
slack_cookie_env: SLACK_XOXD_COOKIE # xoxd `d` cookie 的环境变量
channel_ids: [] # 允许的频道 ID 列表(空 = 所有公共频道)
gap_minutes: 30 # 开始新对话窗口的静默间隔
backfill_days: 90
chunk_max_tokens: 512
chunk_overlap_tokens: 50
sessions:
logs_dir: ~/.claude/projects # Claude Code JSONL 日志目录
backfill_days: 60
chunk_max_tokens: 512
documents:
glob_patterns: ["**/*.md", "**/*.mdx", "**/*.txt", "**/*.rst", "**/*.html", "**/*.adoc"]
chunk_max_tokens: 512
chunk_overlap_tokens: 50
network:
ca_bundle: "" # 所有出站 HTTPS 的 PEM CA 捆绑(Slack/Jira/Slite/GitHub)
```
### 企业代理(TLS 拦截)
如果您位于 TLS 拦截企业代理后面,则 `devrag auth slack`、`index prs/issues/jira/slite/slack` 及其 MCP 等效项可能会失败,并出现:
```
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain
```
`httpx` 验证捆绑的 `certifi` CA 列表,不会咨询 macOS 密钥链或独立验证 `SSL_CERT_FILE`,因此代理注入的根 CA 对其未知。将 DevRAG 指向包含该根 CA 的 PEM 捆绑,可以通过配置:
```yaml
network:
ca_bundle: ~/corp-ca.pem
```
或通过标准环境变量(当 `ca_bundle` 为空时作为回退):
```bash
export REQUESTS_CA_BUNDLE=~/corp-ca.pem # 或 SSL_CERT_FILE
```
要将代理的根 CA 从 macOS 密钥链导出到 PEM:
```bash
security find-certificate -a -p -c "<your proxy CA name>" \
/Library/Keychains/System.keychain > ~/corp-ca.pem
```
(或在 Keychain Access 中选择根 CA → 文件 → 导出项目 → `.pem`)。Ollama 嵌入程序与 localhost 通信,不受影响。
### 文件排除
DevRAG 默认情况下会遵循 `.gitignore`。对于索引特定的其他排除项,请创建 `.devragignore` 文件。它使用完整的 `.gitignore` 语法 — 目录模式 (`docs/internal/`)、锚定、`**` 和 `!` 否定全部有效 — 并且适用于代码和文档索引。与 `.gitignore` 不同,它还可以排除被 git 跟踪的文件。
## 部署模式
DevRAG 使用 Qdrant 作为其向量存储。您可以将其运行在嵌入模式(本地文件系统,无需服务器)或 Qdrant 服务器上。
**嵌入模式**(单用户,无服务器):
```yaml
vector_store:
qdrant_path: ~/.local/share/devrag/qdrant
```
**服务器模式**(共享,水平扩展):
```bash
docker run -d -p 6333:6333 -v qdrant_data:/qdrant/storage qdrant/qdrant
```
```yaml
vector_store:
qdrant_url: http://localhost:6333
```
切换模式是配置更改;在切换后使用 `devrag reindex --all` 重新索引。
## 开发
```bash
git clone https://github.com/tomharris/dev-rag.git
cd dev-rag
uv sync --extra dev
# 运行测试
uv run pytest tests/
# 运行单个测试
uv run pytest tests/test_config.py::test_load_config -v
# 集成测试(需要 Ollama 运行 nomic-embed-text)
SKIP_INTEGRATION=0 uv run pytest tests/test_integration.py -v
```
## 许可证
MIT
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器