内容
# Curia
*拉丁语:进行商议的房间。*
**Curia 是一个本地优先、多模型的商议系统,基于您的代码库。** 它通过选择的讨论结构运行多个模型,记录完整的执行轨迹,并为董事长模型提供生成最终答案所需的材料。
Curia 由 Auspex Labs 独立实现,其灵感来自 Andrej Karpathy 的 [llm-council](https://github.com/karpathy/llm-council) 概念。 经典的三阶段委员会是默认模式; Curia 的附加模式、CodeRAG 管道、代理控制平面、存储模型和观测站是其独有的。
> **公开构建:** [Auspex-Aerie/curia](https://github.com/Auspex-Aerie/curia)。 架构和产品决策记录在 [决策日志](docs/decision_log.md) 中。
## 概览
| 领域 | Curia 提供的内容 |
|------|---------------------|
| **商议** | 六种编排模式:委员会、循环赛、战斗、堆栈、复杂迭代和复杂问题解决 |
| **基础** | 会话范围的代码 RAG,具有 AST 分块、ColBERT 检索、实体和图信号、RRF 融合和跨编码器重新排序 |
| **可观察性** | 规范的执行轨迹、提示来源、模型失败、质量状态、令牌使用、成本和每步计时 |
| **界面** | 具有模式感知转折视图和全宽、可搜索的会话目录的观察站 |
| **代理控制** | 用于通过 HTTP API 驱动和检查 Curia 的 30 工具 MCP 服务器 |
| **存储** | 规范的对话 JSON 以及用于会话查询的可重建 SQLite 投影 |
## 快速入门
要求:Python 3.10+、[uv](https://docs.astral.sh/uv/)、Node.js/npm 和 [OpenRouter](https://openrouter.ai/) API 密钥。
```bash
uv sync
cd frontend && npm install && cd ..
cp .env.example .env # 设置 OPENROUTER_API_KEY
./start.sh
```
打开 [http://localhost:5173](http://localhost:5173)。 脚本在 `127.0.0.1:8001` 上启动 FastAPI 后端,在 `127.0.0.1:5173` 上启动观测站; 主机和 API 端口可以通过 `CURIA_API_HOST`、`CURIA_API_PORT` 和 `CURIA_WEB_HOST` 修改。
Curia 目前没有应用级身份验证。 将 API 和观测站保留在本地主机或受信任的网络边界上。
默认学习的 ColBERT 路径不需要 LM Studio。 仅当 `SEMANTIC_BACKEND=biencoder` 时才需要 LM Studio; 请参阅 [RAG_LMSTUDIO.md](RAG_LMSTUDIO.md)。
## 观测站
观测站将主动商议与会话历史分开:
- **回合** 显示当前会话、其不同回合、模式特定执行视图、上下文和提示来源、排名(如果适用)、质量证据和最终裁决。
- **会话** 是一个全宽目录,包含活动日期、调用者和来源、模式和团队、回合/消息计数、结果、持续时间、令牌/调用总数和成本。 搜索会立即过滤已加载的行; 分面控制会重新查询 SQLite; 滚动会延迟加载额外的页面。
- **检查器** 分为参与者、模式感知的商议脉搏和当前会话、匹配团队或所有已记住会话的可选成本系列。 单系列视图可以根据模型、顶部会话、周或月份进行细分。
对话 ID 和会话链接是可共享的 URL。 甲板实时轮询后端,因此通过 MCP 启动的回合在浏览器中无需启动即可出现。 **控制** 在您想要从 UI 继续会话时启用回合编辑器。
上下文视图区分三种不同的事物:
1. 用户的 grounded 提示以及 CodeRAG 是否提供了上下文;
2. Curia 在每个阶段注入的专有编排文本; 和
3. 从早期模型或阶段传递给后期模型的工件。
注入工作流是可点击的:工件引用链接回其生成的答案,而 RAG 链接打开检索源视图,而不是在编排提示内复制存储库文本。
## 商议模式
每种模式都使用相同的规范跟踪合约,但每种模式都有其自己的拓扑结构和视觉处理。
### 委员会(默认)
模型独立回答,匿名排名收集的答案,主席综合回答和同行排名。
```text
查询 + 上下文
│
├── 模型答案(并行)
│ │
│ └── 匿名同行排名
│ │
└─────────────────────────┴── 主席最终答案
```
聚合排名根据每个模型的解析排序计算得出。 它是主席和用户的证据,而不是最终综合的替代品。
### 循环赛
模型依次完善一个共享的草稿。 每个模型都会收到其基础提示和最新的前任草稿。 `@iterations <n>` 在主席接收到最新的草稿和原始基础问题之前,在团队中运行额外的传递。
```text
查询 + 上下文 ── 模型 A ── 模型 B ── 模型 C ── … ── 主席最终答案
最新草稿继续前进
```
### 战斗
所有模型都采取开场立场,批评同行立场,然后捍卫或修改自己的答案以应对同行批评。 主席接收开场陈述、批评和辩护。
```text
开场陈述(并行) ── 同行批评 ── 辩护 ── 主席最终答案
```
### 堆栈
前两个模型回答,主席合并他们的答案,其余模型批评合并。 主席根据这些批评、原始两个模型捍卫或修复合并后的判断,并由主席生成最终报告。
对于两个模型的团队,那两个模型也作为批评者。
```text
2 个答案 ── 主席合并 ── 批评者 ── 主席判断 ── 2 个辩护 ── 主席最终答案
```
### 复杂迭代
前两个竞技场模型通过固定的两轮提取/扩展链交替进行。 第一个模型提取意图、约束和下一个提示; 第二个模型用可行的细节扩展前一个提取。 四次跳跃后,主席根据原始基础问题和最新的链状态回答。
```text
提取 ── 扩展 ── 提取 ── 扩展 ── 主席最终答案
```
### 复杂问题解决
所有模型都回答,然后通过其他答案重新评估自己的答案。 主席将这些反思转化为简报; 每个模型都思考那个简报; 然后主席将简报和思考回合综合起来。
```text
答案 ── 通过同行进行自我提问 ── 主席简报 ── 思考 ── 主席最终答案
```
## 代码基础和上下文
CodeRAG 索引 ZIP 快照或配置的 Git 工作树每个对话。 其当前管道包括:
- Python、Rust、JavaScript、TypeScript/TSX 和 Go 的 tree-sitter AST 分块;
- 默认情况下使用学习的 PyLate ColBERT 检索,可选的 FAISS/LM Studio 双编码器路径;
- 实体种子和追加代码图;
- 互惠排名融合、嵌入查询路由器和 Jina v3 跨编码器重新排序;
- 基于清单的文件级增量索引和索引新鲜度 API; 和
- 检索块的显式源、分数、大小和估计令牌记录。
可以通过 HTTP API 或 CLI 提供手动上下文。 当存在手动文件时,它们会替换该请求的检索。
在运行商议之前预览为查询选择的上下文:
```bash
python -m backend.cli_context \
--conversation <id> \
--query "身份验证是如何工作的?"
# 强制一个或多个文件并绕过此请求的 RAG:
python -m backend.cli_context \
--conversation <id> \
--query "查看此实现" \
--manual-file backend/main.py
```
### 可靠的查询指令
指令在提示之前从用户文本中删除。
| 指令 | 当前效果 |
|-----------|----------------|
| `@norag` / `@raw` | 跳过此回合的检索 |
| `@lastchair` | 如果存在,则使用上一个主席响应作为上下文并跳过检索 |
| `@tokenbudget <n>` | 限制此回合的每个模型提示预算 |
| `@iterations <n>` | 设置循环赛团队的传递次数 |
| `@short` / `@detailed` | 向模型提示添加响应长度指令 |
| `@cite` | 要求模型引用提供的上下文为 `[file:line]` |
| `@noexecute` | 向模型提示添加仅推理、无工具指令 |
| `@reset` | 清除对话状态而不是运行回合 |
提示级指令是针对选定模型的请求,而不是独立强制执行的策略控制。
## 使用 MCP 的代理控制
运行 API,然后启动 Curia 的 stdio MCP 服务器:
```bash
uv run uvicorn backend.main:app --host 127.0.0.1 --port 8001
uv run curia-mcp
```
`CURIA_API_URL` 默认设置为 `http://127.0.0.1:8001`。 设置 `CURIA_AGENT_ID` 以记录谁启动了代理驱动的工作。 旧的 `ARENA_*` 别名为了兼容性而保留。
典型的完整回合流程是:
```text
get_index_manifest
→ 需要时重新索引
→ create_conversation
→ send_message
→ 检查 execution_quality、trace、failures 和 cost
```
`send_message` 是与模式无关的全回合工具。 对于委员会,只有 `run_council_turn` 是围绕较低级别的 `create_turn` / `advance_turn` 生命周期便捷包装器。 总是检查 `execution_quality.acceptable`,然后将主席响应视为成功的运行; 传输级成功并不保证每个必需模型阶段都成功。
有关工具映射和响应契约,请参阅 [代理控制平面架构](docs/agent-control-plane-architecture.md)。
## 配置
### 团队预设
团队位于 `backend/squads/`,定义了竞技场参与者和主席。
| 团队 | 竞技场 | 主席 |
|-------|-------|----------|
| `normal`(默认) | 5 个多样化免费模型 | `google/gemini-2.5-pro` |
| `freebee9` | 9 个免费模型 | `google/gemini-2.5-pro` |
| `cheap_pros` | 4 个低成本付费模型 | `deepseek/deepseek-v4-flash` |
在 `.env` 中选择启动默认设置:
```bash
ARENA_SQUAD=cheap_pros
```
观测站的 **设置 → 竞技场团队** 控制将选择保留到 `data/config.json`。 保留的运行时设置优先于环境默认设置。 设置还控制浅色/深色主题。
### 检索环境
```bash
OPENROUTER_API_KEY=sk-or-v1-...
# 默认语义路径
SEMANTIC_BACKEND=colbert # colbert | biencoder
COLBERT_LEARNED=true
COLBERT_DEVICE=auto # 可用时使用 CUDA,否则使用 CPU
# 检索拓扑
QUERY_ROUTER=embedding # embedding | regex
FUSION_MODE=rrf # rrf | max_score
GRAPH_MODE=append # append | resort
RERANK_MODEL=jinaai/jina-reranker-v3
RERANK_ENABLED=true
RETRIEVE_CANDIDATES=50
RERANK_TOP_K=20
CONTEXT_CHUNK_CAP=60
# 仅由 SEMANTIC_BACKEND=biencoder 使用
LMSTUDIO_BASE_URL=http://localhost:1234/v1
LMSTUDIO_EMBED_MODEL=text-embedding-nomic-embed-text-v1.5
```
### 模型上下文限制
已注册的模型限制和标签位于 `data/model_catalog.yaml`。 分配策略(包括 85% 安全裕度、4,000 令牌输出津贴、备用限制和标签修改器)位于 `data/arena_config.yaml`。 这些文件在进程启动时冻结; 修改后重新启动后端。
接受的运行时观察可能会取代已注册的规划限制。 `backend/config.py` 保留了未编目和旧模型 ID 的备用限制。
## 架构
- **后端:** FastAPI、Python 3.10+、异步 httpx、OpenRouter API
- **前端:** 普通 TypeScript、Vite 7、`marked` 和 DOMPurify、highlight.js
- **代理控制:** `mcp_arena/` 中的 FastMCP;`curia-mcp` 入口点,带有已弃用的 `arena-mcp` 别名
- **RAG:** tree-sitter、PyLate ColBERT 或 FAISS 双编码器、实体/图混合检索、Jina v3 重新排序
- **存储:** 对话 JSON 作为事实来源; SQLite 作为协调的、可重建的会话投影
- **配置:** 团队 JSON 加启动冻结的模型目录和竞技场策略 YAML
## 开发检查
```bash
# CI 使用的后端单元套件(不包括评估工作负载)
uv run pytest tests/unit -m "not eval"
# 前端类型检查和生产构建
cd frontend && npm run build
```
检索评估工具包与普通的单元套件故意分开:
```bash
python -m backend.run_hyp001
python -m backend.run_hyp002
```
## 文档
- [RAG_LMSTUDIO.md](RAG_LMSTUDIO.md) — 检索设置、拓扑、环境和索引 API
- [决策日志](docs/decision_log.md) — 追加决策、事件、假设和延期
- [代理控制平面](docs/agent-control-plane-architecture.md) — MCP 架构、工具和契约
- [PIV-001 检查清单](docs/piv-001-checklist.md) — 代理控制实现状态和未完成工作
- [PIV-002 观测站](docs/piv-002-observatory-ui.md) — 接受的观测站方向和设计历史
- [PIV-003 Curia 品牌重塑](docs/piv-003-curia-rebrand.md) — 完成的重命名层和剩余的兼容性工作
- [DEC-018 冻结配置](docs/dec-018-catalog-config-summarizer.md) — 模型目录、限制观察、总结器和提示注册表
- [LICENSING.md](LICENSING.md) — 源代码树和存储库历史许可边界
## 许可证
Curia 在 [Apache License 2.0](LICENSE) 下开源。 您可以在该许可证下运行、修改、分发和使用它进行商业活动。 重新分发者必须提供许可证、标记修改后的文件、保留适用的源代码通知,并保留 [NOTICE](NOTICE) 中的适用归属。 许可证不授予 Auspex Labs 贸易名称、商标、服务标志或产品名称的权利,但仅限于惯例归属。
有关源代码树和存储库历史边界,请参阅 [LICENSING.md](LICENSING.md)。
## 致谢
感谢 [Andrej Karpathy](https://github.com/karpathy) 发布 [llm-council](https://github.com/karpathy/llm-council) 并推广答案 → 匿名同行评审 → 主席综合模式,启发了 Curia。
根据上述许可证条款,欢迎贡献和反馈。