内容
# 夸尔盖斯特
[](https://github.com/Rajeev-Shyam/Quellgeist/actions/workflows/ci.yml)
[](https://github.com/Rajeev-Shyam/Quellgeist/actions/workflows/security.yml)
[](docs/case-studies/wave4-qwen-finetune.md)
[](LICENSE)
[](https://www.python.org/downloads/)
> 可信赖的第一线事件分诊:排名的根因假设,其中 **每个主张都引用真实的证据句柄** —— 智能代理 **不会猜测,而是放弃**。
夸尔盖斯特(Quellgeist)是一种与模型无关的AI智能代理,用于第一线生产事件分诊。
它在只读工具(结构化日志 + 最近部署 + 度量时间序列)上运行可读的JSON动作ReAct循环,然后发出结构化的 **诊断**:
置信度排名的根因假设,每个假设都由结构化的证据句柄(`LogRef.id` / `CommitRef.sha` / `MetricRef.id`)支持,智能代理实际看到了这些句柄 ——
绝不使用自由文本。两个理念使其与众不同:
- **通过结构化句柄引用。** 证据是可检查的句柄,而不是句子,
因此伪造的引用是 **可衡量** 的,并通过 **无密钥制造检查** 确定性地拒绝 ——
而不是模糊的字符串匹配。
- **放弃而不是捏造。** 自信地陈述错误的原因是最糟糕的可能答案,
因此 *"证据不足"* 是一个一流的结果。
> **状态:第四波完成 —— 微调有效。** 当地的推理器(Qwen3-4B,通过Ollama提供)的DR-0020 QLoRA微调
> 使其从基础的 **0/16 留存率提升到 12/16** —— 零制造,零推测过滤,**比基础更便宜** ——
> 同时 **击败31B前沿模型** (Gemma-4-31B,16分之10) 在相同的留存率下 **0成本,全线下运行**。
> 非记忆性通过三种方式进行三角测量(装置≈留存率;核心新鲜≥核心重叠;结构探针7/10)。
> 两个诚实的限制:`resource_exhaustion`类没有转移(0/N;前沿模型通过它),
> 而对抗性放弃召回率在系统级别为 **6/12** ——
> 一个前沿模型 **共享** 的上限(也是6/12),不是微调回归。
> 当智能代理错过时,它 **不完整** 或 **过于谨慎** ,绝不自信地捏造。
> 参见
> [状态和路线图](#状态和路线图) · [微调案例研究](docs/case-studies/wave4-qwen-finetune.md)。
## 为什么它与众不同
| | |
|---|---|
| **证据是句柄** | 每个假设都引用日志行的源稳定`id`或提交`sha`,直接从工具结果复制 ——
确定性制造检查所查找的单位。(DR-0009) |
| **放弃是一种功能** | 当信号较弱时,智能代理返回`abstained=true`,并附带原因和空假设列表 ——
由模式强制执行。 |
| **通过构造与模型无关** | 循环从普通聊天文本解析JSON操作,因此在Gemini的免费层和本地4比特Qwen上是相同的 ——
没有依赖于任何后端的原生函数调用。只需更改一个配置即可更换模型。(DR-0008,DR-0010) |
| **可靠性是门控的,而不是断言的** | 无密钥、确定性的CI门控(ruff + black + `pytest`,包括基于装置的评估套件)
在每次推送时运行。 |
### 它是什么 / 它不是什么
- **它是:** 一个第一线 **分诊** 智能代理 —— 排名的、引用证据的根因假设(或诚实的放弃),
来自只读日志/部署/指标,通过一个与模型无关的循环运行在托管的前沿模型 **或** 本地4B模型上。
- **它不是:** 一个自主的修复程序(它绝不改变生产环境 —— 解决验证是延迟的第一波);
一个生产强化的服务(演示是一个刻意的玩具);
或一个通用的智能代理。测试的保留率是 **超出词汇但在结构内** ——
不是对未见事件形状或真实生产数据的声明。
## 快速开始(~30秒到一个损坏的服务 + 结构化日志)
需要 [uv](https://docs.astral.sh/uv/) 和 Python 3.12+。
**通过一个无密钥命令在一个真实的形状诊断中查看** (无需模型,无需API密钥):
```bash
uv sync && uv run quellgeist diagnose --demo # 渲染演示事件的引用事后总结
```
然后针对实时玩具服务运行完整的循环:
```bash
uv run uvicorn demo.app.main:app # 1. 启动玩具服务(保持运行)
# --- 在第二个shell中,从仓库根目录 ---
uv run python -m demo.chaos.bad_deploy # 2. 注入模拟的错误部署
curl -s localhost:8000/login # 3. 触发/login -> 500s + 结构化错误日志
uv run quellgeist diagnose --show-trace # 4. 诊断实时(需要模型;参见下文)
uv run python -m demo.chaos.reset # 回到绿色 slate
```
实时步骤需要一个推理器 —— 参见 [运行模型](#运行模型)。
如果没有密钥,`quellgeist diagnose` 以一行错误 + 提示退出(绝不 traceback);
`--demo` 始终有效,并确定性地从黄金渲染相同的输出形状。
## 架构
自定义、可读的循环是编排层;三个只读工具是证据接口;
`Diagnosis` 模式是后验渲染器和评估裁判都读取的契约。
```mermaid
flowchart TD
trigger(["事件触发 - CLI"]) --> loop
model["推理器通过LiteLLM<br/>(Gemini或本地Qwen,可互换)"] -. "聊天完成" .-> loop
subgraph loopbox["与模型无关的JSON操作ReAct循环"]
loop["run_loop()<br/>决定,调用工具,观察,重复"]
end
loop -- "query_logs" --> logs["日志工具<br/>结构化JSONL,稳定id"]
loop -- "get_recent_commits" --> commits["提交工具<br/>deploy_log.json,shas"]
loop -- "query_metrics" --> metrics["指标工具<br/>时间序列,命名序列"]
logs -- "行 + id" --> loop
commits -- "提交 + shas" --> loop
metrics -- "序列 + 名称" --> loop
loop --> diag["诊断(schema.py)<br/>排名假设,引用<br/>LogRef.id / CommitRef.sha / MetricRef.id,或放弃"]
diag --> pm["事后总结渲染器<br/>确定性Markdown"]
diag --> judge["评估裁判<br/>装置场景,CI门控"]
```
所有三个工具也通过 **MCP服务器** 公开给stdio
(`python -m quellgeist.servers.logs_mcp`,`…commits_mcp`,`…metrics_mcp`)。
智能代理当前在进程内重用相同的工具 **函数** ,在 `ToolSpec` 注册表后面;
基于stdio的MCP-**客户端** 路径(智能代理通过线路驱动服务器)正在路线图中(DR-0010)。
> **深入了解:** [`docs/architecture.md`](docs/architecture.md) 遍历整个
> 流水线(循环→工具→验证器→事后总结),一个序列图,模块映射和跨越设计决策。
<!-- MCP注册表所有权标记:注册表通过在发布的软件包README中找到这些`mcp-name:`字符串来验证PyPI软件包所有权。
参见docs/publishing.md。(不可见地渲染。)
mcp-name: io.github.Rajeev-Shyam/quellgeist-logs
mcp-name: io.github.Rajeev-Shyam/quellgeist-commits
mcp-name: io.github.Rajeev-Shyam/quellgeist-metrics
-->
服务器在每个标记版本上发布到 **官方MCP注册表** (参见
[`docs/publishing.md`](docs/publishing.md));一旦发布,每个服务器都可以通过
`uvx --from quellgeist quellgeist-logs-mcp`(或`…-commits-mcp` / `…-metrics-mcp`)运行。
## 示例会话
注入错误的部署 —— 它会丢弃一个标记,该标记将`verify_token`变为NoneType回归,
并写入一个`deploy_log.json`,其有问题的提交在错误之前刚刚登陆:
```text
$ uv run python -m demo.chaos.bad_deploy
注入错误的部署 a1b2c3d (影响 demo/app/auth.py) 于 2026-06-24T12:22:43Z
标记: demo/.bad_deploy
部署日志: demo/deploy_log.json
下一步:访问/login以生成500,然后`quellgeist diagnose`
```
配置推理器后,`quellgeist diagnose` 读取日志 + 部署并发出事后总结。
CI环境没有验证的模型密钥(DR-0012),因此下面的诊断是 **从黄金渲染** ——
从装置的标记原因和证据句柄通过`render_postmortem` 构建确定性,而不是
实时模型输出:
```text
# 事件事后总结(从黄金渲染)
## 根原因假设
### 1. 错误部署 a1b2c3d (10:01:50Z)重构了auth.py并在verify_token中引入了NoneType错误;/login 500s开始于10:02:12Z。 (置信度:1.00)
证据:
- 日志 #2
- 提交 a1b2c3d
```
自己重现(无需模型):
```bash
uv run python - <<'PY'
from evals.scenarios.generator import load_scenario
from quellgeist.agent.schema import Diagnosis, Hypothesis
from quellgeist.output.postmortem import render_postmortem
s = load_scenario("evals/scenarios/fixtures/bad_deploy_0001.json")
gold = Diagnosis(hypotheses=[
Hypothesis(cause=s.gold_cause, confidence=1.0, evidence=s.gold_evidence_refs)
])
print(render_postmortem(gold, title="事件事后总结(从黄金渲染)"))
PY
```
重点不是文字 —— 而是 **`log #2`** 和 **`commit a1b2c3d`**
是进入真实信号的精确句柄,而不是转述。
实时运行还会填充一行摘要和建议的操作,并在证据不足以命名自信的原因时直接放弃。
## 运行模型
推理器是任何 [LiteLLM](https://docs.litellm.ai/) 模型字符串,由
`--model` 或 `QG_MODEL` 环境变量选择(默认为 `gemini/gemini-3.5-flash`)。
提供者密钥由LiteLLM从环境中读取;仓库中不存储任何内容。
```bash
export QG_MODEL="gemini/gemini-3.5-flash"
export GEMINI_API_KEY="…"
uv run quellgeist diagnose --show-trace
```
或完全本地和离线通过 [Ollama](https://ollama.com) —— 默认的预期家用(DR-0008;
确切的制品在DR-0019中固定),无需API密钥参与:
```bash
ollama pull qwen3:4b-instruct-2507-q4_K_M
export QG_MODEL="ollama_chat/qwen3:4b-instruct-2507-q4_K_M"
uv run quellgeist diagnose --show-trace
```
> **基础与调优 —— 重要。** 上面的`ollama pull`是 **基础** Qwen3-4B:
> 诚实的 **安全下限** —— 它在保留率上得分为 **0/16** ,并且在所有内容上放弃,
> 从不捏造(DR-0019)。**12/16** 的标题是 **DR-0020微调**
> (`quellgeist-qwen3-dr0020`),您可以通过 [`finetune/README.md`](finetune/README.md)
> 构建并提供(免费Colab QLoRA运行 → `ollama create`)。直到发布调优的GGUF进行一行拉取,
> 基础模型是纯粹的ollama pull给出 —— 安全,但还不够用。使用托管模型(上文)
> 或微调以查看实时诊断。
### 运行评估(推理器 + 验证器 + LLM-裁判)
装置评估通过确定性关键词裁判 + 零制造检查(无密钥门控)来评估推理器,
并且可以额外运行两个模型层(DR-0016):一个 **验证器** ,确认引用的证据支持每个
假设(否则强制放弃),以及一个咨询 **LLM裁判** 规则。
```bash
export GEMINI_API_KEY="…"
export QG_MODEL="gemini/gemini-3.5-flash"
QG_VERIFY=1 QG_JUDGE_LLM=1 \
QG_MIN_CALL_INTERVAL_S=6 \ # 在免费层RPM下调整调用(避免429突发)
uv run python -m evals.run_evals
```
`QG_VERIFIER_MODEL` / `QG_JUDGE_MODEL` 按层覆盖模型(默认为
`QG_MODEL`)。无法访问的后端(配额/503/超时) **或** 拒绝的凭证(丢失/无效/过时密钥)
被报告为 **跳过** ,而不是失败(DR-0015/DR-0017),因此带外评估永远不会变红在免费层 hiccup。
LLM裁判的分数是 **建议** (它们永远不会门控)。在人类标记的黄金子集上,
它与人类判决一致 **Cohen's kappa 0.81** 使用独立裁判(`groq/llama-3.1-8b-instant`≠推理器)
- 在该子集上验证(DR-0018);仍然自我评分,只要`QG_JUDGE_MODEL`等于推理器。
> **CI的带外评估运行在Groq** (`groq/llama-3.3-70b-versatile`),门控在
> `GROQ_API_KEY`:Gemini的免费层证明无法从云CI使用(429 → 503 →
> timeout → 无效密钥),因此推理器被交换为一个环境变量 - 模型无关的论文在行动(DR-0017)。
> 预期的 **家庭** 默认设置仍然是本地Qwen3-4B(DR-0008)。
## 状态和路线图
构建在 **滚动波** 中 - 只有当前波在细节中实现(参见
[`docs/quellgeist-plan-rolling-wave.md`](docs/quellgeist-plan-rolling-wave.md)。
完整的决策历史记录在
[**ADR日志**](docs/quellgeist-adr-log.md).
| 波 | 范围 | 状态 |
|---|---|---|
| 0 | 风险降低模型(4B可以编排循环) | ✅ 完成 — 默认 = Qwen3-4B(DR-0008) |
| 1 | 错误部署切片:demo → 断开 → 诊断 → 事后总结;评估套件 + CI | ✅ 完成 — 构建和单元测试的脊柱 |
| 2 | 可靠性核心:验证器通过,确定性制造检查,放弃,LLM作为裁判 | ✅ 构建 - 无密钥确定门控 + 选择性验证器/裁判;第一个实际运行通过零制造(DR-0016/DR-0017); 判读器验证 + 可靠性 **速率** 载入波 3 |
| 3 | 宽度:配置/环境 + 资源耗尽类,指标,~50个场景 | ✅ 完成 — 3类分布在65个场景套件中;第一个完整运行 **61/65,0个制造**;裁判验证(kappa 0.81)。参见 [可靠性案例研究](docs/case-studies/wave3-reliability-rate.md) + [裁判](docs/case-studies/wave3-judge-validation.md) 案例研究 |
| **4** | **成本/微调:QLoRA Qwen3-4B vs 基础 vs 前沿,开启/关闭验证器** | ✅ **完成** — 基础 **0/16 → 调优 12/16** 保留率(0个制造,0个推测过滤,更便宜);与Gemma-4-31B竞争(在能力上击败10/16,在放弃上打平6/12);`resource_exhaustion`未学习 + 对抗性放弃共享一个6/12上限 ([案例研究](docs/case-studies/wave4-qwen-finetune.md),DR-0019/DR-0020) |
| **5** | 润色和发布:HTML渲染、安全检查、MCP注册表、启动 | 🚧 **工程完成 - 发布门控** (HTML渲染 + 安全扫描器 + 威胁建模 + 注册表/ OIDC脚手架完成;发布标签 + 启动是剩余步骤) |
| 6 | 解决验证循环 | ⏳ 切割第一 |
波边界是刻意的,而不是未完成:只有当前波在细节中实现,并且后续波被作用域但故意未实现。
## 可靠性门控
确定性CI门控是可靠性契约:**196个测试** (ruff + black通过pre-commit,然后`pytest` - 涵盖循环的绝不崩溃/礼貌放弃行为,确定性制造检查和基于引用的裁判门控,验证器和建议的LLM裁判,参数化场景生成,裁判验证套件,服务器过滤器,后验渲染器,以及装置支持的评估套件) 在Python 3.12和3.13上。
在带外,**模型驱动评估** 在65场景套件上运行推理器。最新的完整运行得分为 **61/65通过,0个制造的证据** (Cerebras Gemma-4-31B)- 按类分解 + 失败分析在 [可靠性案例研究](docs/case-studies/wave3-reliability-rate.md).
```bash
uv run pytest tests/ -q
uv run pre-commit run --all-files
```
## 开发和贡献
参见 [CONTRIBUTING.md](CONTRIBUTING.md) 了解开发设置、约定和波模型;
[SECURITY.md](SECURITY.md) 报告和无秘密/玩具演示策略;
以及 [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) 了解社区期望。
错误报告和功能请求使用 [问题模板](.github/ISSUE_TEMPLATE);
拉取请求遵循 [拉取请求模板](.github/PULL_REQUEST_TEMPLATE.md).
## 许可
[MIT](LICENSE) © Rajeev Shyam Kumar.