shahilseth/codesheriff

GitHub: shahilseth/codesheriff

一个基于多 Agent 架构的 AI 代码问答系统,支持用自然语言提问任意 GitHub 仓库并给出带置信度评分和引用的答案。

Stars: 0 | Forks: 0

# CodeSheriff CodeSheriff —— 用简单的英语提问关于 GitHub 仓库的问题。这是一个多 agent 系统,能够进行检索、推理、审查和综合,并提供置信度分数以及引用的源代码文件。 当你加入一个新的代码库(或者六个月后回头看自己的代码)时,最耗时的部分不是阅读代码,而是弄清楚*应该*阅读*哪些*代码,以及你对代码为何如此构建的初步猜测有多大的可信度。CodeSheriff 会检索相关的代码块,推理其设计意图,让第二个模型以对抗性的方式检查该推理是否存在漏洞,最后为你提供一个带有置信度分数和所依据的确切文件的最终答案。 ![CodeSheriff UI](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/3bb4394d55094747.png) ## 架构 CodeSheriff 通过一个固定的四 agent pipeline 处理每一个问题,并由一个纯 Python 的 orchestrator 进行协调(没有任何 agent 来决定 pipeline 的顺序——请参阅下文的“设计决策”)。 | Agent | 模型 | 任务 | 为何分离 | |---|---|---|---| | Navigator | `llama-3.1-8b-instant`(轻量级、可选的 LLM 步骤) | 在 ChromaDB 上对相关代码块进行语义搜索,并通过 `git log` 获取相关的 commit | 检索是一个搜索问题,而不是推理问题——将其独立出来意味着推理 agent 可以基于一个固定且可检查的证据集合进行工作,而不是在思考过程中重新检索 | | Analyst | `llama-3.1-8b-instant` | 推理检索到的代码背后的*设计意图*——为什么它是这样构建的,而不仅仅是它的功能是什么——并自我评估出一个 `confidence_hint` | 一个既提出答案又对自己的答案进行评分的模型往往会过于自信;将提出和审查分开正是核心目的所在 | | Critic | `llama-3.1-8b-instant` | 以对抗性的方式审查 Analyst 的假设:遗漏的文件、未经证实的假设、不完整的检索、相互矛盾的证据 | 只从 Navigator 接收文件/代码块的*名称*,而不是它们的内容——它不能只是简单地附和 Analyst 对代码的解读,而是必须推理出覆盖范围的盲区(请参阅“设计决策”) | | Synthesiser | `llama-3.3-70b-versatile` | 将 Analyst 的推理与 Critic 的质疑调和成最终答案,仅引用 Analyst 已经提及的证据 | 这是用户能看到的唯一输出,它必须解决两个潜在冲突的上游观点——因此值得使用更大的模型 | ## 评估结果 | 指标 | 分数 | |---|---| | 检索召回率 | 0.80 | | 置信度校准 | 0.90 | | 平均置信度 | 0.51 | - **检索召回率 (0.80)** —— 在评估问题集中,正确答案应该引用的文件中有 80% 被实际检索并引用了。 - **置信度校准 (0.90)** —— 90% 的答案达到了为该问题定义的最低置信度阈值,这意味着系统自我报告的置信度大致反映了其证据的实际完整程度。 - **平均置信度 (0.51)** —— 平均而言,pipeline 报告的是“中等”置信度,这与 Analyst 自身的指导原则相符,即基于部分检索得出的大多数诚实答案应该落在 0.5–0.75 的范围内,而不是接近确定。 ## 技术栈 | 后端 | 前端 | |---|---| | FastAPI | React (Vite) | | Groq API (`llama-3.1-8b-instant`, `llama-3.3-70b-versatile`) | 纯 CSS | | ChromaDB(本地持久化向量存储) | 针对 FastAPI 后端的 `fetch` | | `sentence-transformers` (`all-MiniLM-L6-v2`) | | | `tree-sitter` / `tree-sitter-python`(分块) | | | PostgreSQL + SQLAlchemy(异步、trace logging) | | | Pydantic(agent I/O 契约) | | ## 快速开始 ``` # a. 克隆并创建虚拟环境 git clone codesheriff cd codesheriff python3.11 -m venv .venv # b. 安装依赖项 .venv/bin/pip install -r requirements.txt # c. 设置环境变量 cp .env.example .env # 然后编辑 .env 并填写 GROQ_API_KEY(如果不使用默认值,还需填写 CODESHERIFF_DB_URL) # d. 启动 PostgreSQL(如果本地已有 Postgres 在运行,则跳过此步) docker run --name codesheriff-db -e POSTGRES_PASSWORD=password \ -e POSTGRES_DB=codesheriff -p 5432:5432 -d postgres # e. 索引仓库(默认索引 CodeSheriff 自身) .venv/bin/python scripts/index_repo.py --repo_path . --repo_name codesheriff # f. 启动后端 .venv/bin/uvicorn backend.main:app --reload # g. 启动前端(在单独的终端中) cd frontend npm install npm run dev ``` 然后打开 `http://localhost:5173`。UI 会引导你完成两个步骤——索引一个仓库(GitHub URL 或本地路径,自动检测),然后提出一个问题——并展示综合后的答案,包含置信度条、引用的文件、已知的盲区,以及所有四个 agent 的可折叠 trace 和延迟分析。 ## 项目结构 ``` codesheriff/ backend/ agents/ # Navigator, Analyst, Critic, Synthesiser agent implementations db/ # ChromaDB and PostgreSQL clients + trace logging indexer/ # Repo walking, tree-sitter chunking, embedding pipeline models/ # Pydantic schemas shared between agents and the API orchestrator/ # Pure Python coordination of the agent pipeline utils/ # Git log parsing for commit-based retrieval main.py # FastAPI app: /api/index, /api/query, /api/trace/{id} evals/ ground_truth.json # Eval question set with expected files/keywords/confidence eval_runner.py # Runs the eval set against a live backend, scores results eval_results/ # Timestamped eval run reports (gitignored) frontend/ src/ components/ # Header, IndexForm, AskForm, AnswerView, TraceViewer, icons api.js # fetch wrappers for /api/index, /api/query, /api/trace, /health App.jsx # state machine: setup -> indexing -> ready -> asking -> result scripts/ # CLI entry points and integration tests out/ # Generated ChromaDB persistence (gitignored) ``` ## 设计决策 - **Critic 接收代码块名称但不接收代码块内容。** 如果 Critic 看到了与 Analyst 相同的代码,它往往会以相同的方式解读并很大程度上表示赞同——这不是对抗性审查,而是基于相同证据的二次意见。通过仅向其提供*覆盖范围*(检索到了哪些文件和代码块,而不是它们的内容),在结构上迫使 Critic 去推理缺失或未经证实的内容,而不是重新推导 Analyst 的结论。 - **置信度是在 Python 中计算的,而不是询问模型的。** 最终的置信度分数是 `clamp(analyst.confidence_hint + critic.confidence_adjustment, 0, 1)` ——这是两个模型输出的确定性函数,而不是要求模型生成的第三个数字。要求 LLM“根据以上所有内容评估你的总体置信度”往往会产生一个基于语气的数字,而不是基于 Critic 刚刚指出的特定盲区;通过这两个结构化信号来计算,可以确保最终分数的溯源,让你明白它*为什么*是这个值。 - **Orchestrator 是纯 Python 的协调过程,而不是 LLM agent。** pipeline 的顺序(Navigator → Analyst → Critic → Synthesiser)是预先固定的——这里不需要模型来做决定,使用 LLM 来“决定下一步做什么”只会增加延迟、成本和一种故障模式(步骤路由错误),而没有任何好处。Agent 应保留给那些真正需要判断的步骤。 ## 已知限制 - 当前的设置具有有限的 git 历史记录,这限制了 Navigator 基于 commit 的检索在解答“为什么这段代码要以这种方式编写”的问题上能提供的帮助——目前大多数的推理仅仅依赖于代码结构本身。 - 检索是对仓库中所有代码块进行的扁平化 ChromaDB 相似性搜索。这在目前测试的规模下运行良好,但随着代码库的增长性能会下降——因为没有模块级别的预过滤,当代码块数量增长到数万个时,准确率会下降。 - 对于同一个问题,置信度分数在不同运行中具有大约 ±0.05 的方差,因为 Analyst 和 Critic 在 temperature 为 0.2 下运行——同一个问题在不同的运行中可能会刚好落在某个给定阈值的上方或下方。 作为结构化 AI 工程学习路线图的一部分而构建。
标签:AI, LLM, RAG, SOC Prime, Sysdig, Unmanaged PE, 代码理解, 多智能体, 开发工具, 测试用例, 自动化代码审查, 逆向工具