内容
<p align="center">
<img src="https://em-content.zobj.net/source/apple/391/eye_1f441-fe0f.png" width="110" alt="Argus" />
</p>
<h1 align="center">Argus</h1>
<p align="center">
<strong>掌控智能代理循环,而非框架。</strong>
</p>
<p align="center">
一个无框架、多智能体、深度研究的搜索引擎 — 计划器将问题分解成子问题,多个搜索智能体并行搜索互联网和本地文档库,合成器撰写引用答案。<br/>
</p>
<p align="center">
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue?style=flat" alt="许可证:MIT"></a>
<img src="https://img.shields.io/badge/python-3.12%2B-blue?style=flat" alt="Python 3.12+">
<img src="https://img.shields.io/badge/tests-150%20passing-brightgreen?style=flat" alt="测试:150 通过">
<img src="https://img.shields.io/badge/local--first-Ollama-orange?style=flat" alt="本地优先">
</p>
<!-- Once the repo is PUBLIC, add the live GitHub badges below (they show "repo not found" while private):
<p align="center">
<a href="https://github.com/subratamondal1/argus/actions/workflows/ci.yml"><img src="https://github.com/subratamondal1/argus/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
<a href="https://github.com/subratamondal1/argus/stargazers"><img src="https://img.shields.io/github/stars/subratamondal1/argus?style=flat&color=yellow" alt="星星"></a>
<a href="https://github.com/subratamondal1/argus/commits/main"><img src="https://img.shields.io/github/last-commit/subratamondal1/argus?style=flat" alt="最近提交"></a>
</p>
-->
<p align="center">
<a href="#features">功能</a> •
<a href="#quickstart">快速开始</a> •
<a href="#how-it-works">工作原理</a> •
<a href="#eval-gate">评估门</a> •
<a href="#configuration">配置</a> •
<a href="#development">开发</a>
</p>
---
Argus 以研究团队的方式回答难题:**计划器** 将问题分解成子问题,多个 **搜索智能体** 并行搜索互联网和本地文档库,**合成器** 撰写引用答案。通过 **评估门** 强制检索质量,防止回归,搜索智能体 **自动扩展**,在 Kubernetes 上从零开始,运行可 **恢复**。
构建于 Python 3.12 · LiteLLM · PostgreSQL + pgvector · FastAPI · Next.js — **无智能体框架**(无 LangChain/LangGraph):直接掌控循环、预算和故障处理。**本地优先** — 在 Ollama 上零成本运行;OpenAI 和 Anthropic 是可选的。
<p align="center">
<img src="docs/assets/argus-demo.gif" width="100%" alt="Argus 深度研究运行:计划器分解问题,四个搜索智能体并行运行,合成器撰写引用答案 — 流式传输直播。" />
</p>
<p align="center">
<em>一次 <strong>深度研究</strong> 运行,端到端:计划器分解问题,四个搜索智能体并行运行,合成器流式传输引用答案 — 在 Ollama 上本地零成本运行。</em>
</p>
## 功能
| 能力 | 详情 |
|---|---|
| **无框架智能体循环** | 使用 LiteLLM 的手写工具使用循环,具有 3 轴预算(回合/令牌/时钟)+ 硬成本上限,重试/回退梯度和自注册、权限控制的工具注册表。 |
| **多智能体编排** | 计划器 → 并行搜索智能体(隔离上下文)→ 合成器 → 反思/重新计划。 |
| **上下文 RAG** | 类似 Anthropic 的上下文分块;混合密集-HNSW + 词法-FTS 检索与相互排名融合;可选 `bge-reranker-v2-m3` 跨编码器 — 所有在单个 pgvector 存储上。 |
| **评估门** | 精心策划的、以来源为基础的基准,具有 RAGAS 风格的指标(上下文精度/召回率、忠实度、答案相关性)+ Cohen's-κ 校准的 LLM 评判员;如果低于提交的阈值,则失败构建。 |
| **水平扩展** | 搜索智能体分发到 ARQ-on-Redis 队列;Kubernetes + KEDA 根据队列深度将搜索 Pod 缩放为零。 |
| **持久执行** | 可选的 DBOS 工作流 — 崩溃的研究运行从其最后一个检查点步骤恢复(Postgres 支持)。 |
| **MCP 服务器** | 工具注册表通过模型上下文协议 (`argus mcp`) 公开给任何 MCP 主机。 |
| **多租户 + 身份验证** | 电子邮件/密码 → argon2id + HS256 JWT 在 httpOnly cookie 中,带有签名双提交 CSRF;每个租户的数据隔离。 |
| **流式 UI** | FastAPI 服务器发送事件,将实时多智能体进度流式传输到 Next.js 16 / React 19 客户端。 |
| **沙盒代码执行** | `execute_python` 在权限门后,在子进程沙盒(rlimits、超时、无网络)中运行模型生成的代码。 |
## 快速开始
```bash
# 1. 安装(uv 管理 Python 3.12 工具链和 venv)。
uv sync
# 2. 启动本地支持栈(Postgres + pgvector,SearXNG)。
make up
# 3. 在 Ollama 上本地运行 LLM 和嵌入 — 零成本,无 API 密钥。
ollama pull qwen2.5:3b && ollama pull nomic-embed-text
# 4. 提问。
uv run argus "What changed in the EU AI Act timeline in 2026?" # 或:make ask Q="..."
```
如果您想覆盖默认值,请先执行 `cp .env.example .env`。要使用托管模型,请在 `.env` 中设置 `OPENAI_API_KEY` 和 `ARGUS_MODEL=openai/...`(参见[配置](#configuration))。堆栈控制:`make status` / `make down`。
## 工作原理
```
问题
│ 计划器(LLM)
▼
子问题 ──► 搜索智能体 ─┐ 每个:自己的工具使用循环 + 预算,
──► 搜索智能体 ─┤ 在 corpus + web_search 上进行 rag_search,
──► 搜索智能体 ─┘ 并行运行(asyncio / ARQ+KEDA)
│ 查找结果
▼
合成器(LLM) ──► 反思/重新计划 ──► 引用答案
```
每个 LLM 调用都经过结构化记录和成本归因;当达到其回合/令牌/时钟/成本限制时,智能体循环停止。RAG 路径使用 LLM 编写的上下文前缀摄取文档,对它们进行嵌入(在 Ollama 上本地),并为密集(HNSW)和词法(全文)搜索编制索引;查询将这两个索引融合,并使用相互排名融合。设计决策作为 ADR 记录在 [`docs/adr/`](docs/adr/) 中(例如 [为什么使用单个 pgvector 存储](docs/adr/0001-datastore-postgres-pgvector.md))。
## 评估门
检索质量是一个数字,而不是一种感觉。`argus eval` 摄取一个精心策划的 RAG/矢量搜索文档库([`eval/corpus/`](eval/corpus/)),运行一个已提交的黄金标准集([`eval/golden.jsonl`](eval/golden.jsonl))— 48 个问题,包括负面/无法回答的情况 — 通过实际检索和智能体评估答案,当任何指标低于 [`eval/thresholds.json`](eval/thresholds.json) 时,退出非零。
```bash
make eval # 门(仅限 corpus;报告以下指标)
make eval-calibrate # 证明评判员与人类一致(Cohen's κ ≥ 阈值)
```
最新运行(`make eval`,48 项基准,仅限 corpus):
| 指标(RAGAS 词汇) | gpt-5.4-mini | qwen3.5:4b(本地) | qwen2.5:3b(本地) | 阈值 |
|---|---|---|---|---|
| 上下文召回率(hit@k) | 1.000 | 0.976 | 0.976 | ≥ 0.80 |
| 上下文精度 | 0.662 | 0.676 | 0.624 | ≥ 0.20 |
| mrr | 0.948 | 0.952 | 0.952 | ≥ 0.60 |
| 忠实度 | 0.976 | 0.976 | 1.000 | ≥ 0.70 |
| 答案相关性 | 1.000 | 0.976 | 0.690 | — |
| 评判员通过率 | 0.976 | 0.643 | 0.000 | ≥ 0.70 |
| 关键词通过率 | 0.881 | 0.833 | 0.190 | ≥ 0.60 |
| 放弃率(负面拒绝) | 1.000 | 0.833 | 0.000 | ≥ 0.70 |
| **门** | **通过** | 失败(1 个指标,偏差 0.057) | 失败 | |
指标在存储库中实现([`eval/`](src/argus/eval/)),而不是通过 RAGAS,以保持依赖轻量和离线。检索和生成信号独立控制,负面由放弃率评估(一个忠实的系统必须拒绝 corpus 无法回答的内容)。阈值针对前沿模型调整;托管的 gpt-5.4-mini 通过门,而 **完全本地的 $0 堆栈**(qwen3.5:4b 答案禁用思考,nomic 嵌入,非推理 qwen2.5:7b 评判员在 κ=1.0)通过七个指标中的七个,仅在 `judge_pass_rate` 上偏差 0.057 — 相差一个推理层次,检索/忠实度/放弃率均为绿色。qwen2.5:3b 列显示较小型模型何时崩溃(它在每个负面实例上构造,放弃率为 0.000)。让本地推理模型通过门需要禁用 Qwen3 的默认思考(`reasoning_effort="disable"` → Ollama `think:false`,~84s→~2s/调用),同时保持结构化评判输出,Ollama 在思考关闭时丢弃。
## 文档摄取(RAG)
```bash
ollama pull nomic-embed-text # 一次性,本地嵌入
uv run argus ingest ./notes/architecture.md # 一个文件
uv run argus ingest https://example.com/post # 或 URL
uv run argus --deep "How does our system handle retries?"
```
嵌入和重排序在本地运行,因此文档文本永远不会离开机器。PDF/DOCX/PPTX 摄取需要 `uv sync --extra parse`;交叉编码器重排序阶段需要 `uv sync --extra rerank` 和 `ARGUS_RERANK_ENABLED=true`。
## Web UI
```bash
make web-install # 仅限首次:安装前端依赖(bun)
make web # FastAPI 在 :8000 + Next.js 在 :3000 → http://localhost:3000
```
UI 流式传输多智能体流程(计划 → 并行搜索 → 工具调用 → 合成 → 反思)并渲染引用 Markdown 答案,带有文档上传和深度研究切换。后端独立 — `make serve` 单独运行 API,CLI 无需 UI。
## 配置
设置由 [Pydantic 设置](src/argus/config.py) 从环境(`ARGUS_` 前缀)或 `.env` 读取。默认设置完全本地且免费。常见覆盖:
| 变量 | 默认值 | 目的 |
|---|---|---|
| `ARGUS_MODEL` | `ollama_chat/qwen2.5:3b` | 智能体 / 上下文化 / 评判员 LLM(`openai/...` 用于托管)。 |
| `ARGUS_EMBEDDING_MODEL` | `ollama/nomic-embed-text` | 嵌入模型(768-d;必须匹配列)。 |
| `ARGUS_USE_QUEUE` | `false` | 将搜索智能体放到 ARQ-on-Redis 队列(KEDA 自动扩展)。 |
| `ARGUS_USE_DURABLE` | `false` | 以可恢复的 DBOS 工作流运行深度研究(`--extra durable`)。 |
| `ARGUS_RERANK_ENABLED` | `false` | 启用交叉编码器重排序阶段(`--extra rerank`)。 |
可选额外功能:`parse`(文档解析),`rerank`(交叉编码器),`otel`(OpenTelemetry),`durable`(DBOS),`mcp`(MCP 服务器)。
## 开发
```bash
make ci # 格式检查 + lint(ruff)+ 类型检查(ty)+ 测试(pytest)
make test # 仅限测试 — 密封(LLM、DB 和搜索被伪造/标记门控)
make mcp # 将工具注册表作为 MCP 服务器通过 stdio 运行(或:argus mcp)
```
CI 运行密封套件以及 Postgres + Redis 集成作业和带有 KEDA 自动扩展的 kind + 集成测试在每次推送时进行。集成测试位于 `pytest -m integration` 标记后,因此默认套件无需服务。
<!-- Uncomment once the repo has stars (renders an empty chart at 0):
## Star history
<p align="center">
<a href="https://star-history.com/#subratamondal1/argus&Date">
<img src="https://api.star-history.com/svg?repos=subratamondal1/argus&type=Date" width="600" alt="Star history">
</a>
</p>
-->
## 许可证
MIT — 请参阅 [LICENSE](LICENSE)。