klarlabs-studio/mnemos

GitHub: klarlabs-studio/mnemos

Mnemos 是一个自托管的 AI 记忆与证据层服务,为 AI agents 提供证据支撑的声明存储、矛盾检测、双时态召回与决策审计能力。

Stars: 3 | Forks: 0

# Mnemos **为 AI 应用提供的自托管记忆服务。没有供应商云,没有按次计费,无需安装 SDK。** 你真正拥有的、开源的 AI 应用记忆层。仅仅是一个 Go 二进制文件、一个 HTTP API 和你的数据。每一项声明都有证据,每一处矛盾都会浮现,每一次决策都可重放 —— 几个月后,依然在你的基础设施中。 ## 5 行代码为 AI 应用添加记忆 无需安装 SDK。任何支持 HTTP 客户端的语言都可以。以下是 Python 示例;你也可以将其替换为 `curl`、`fetch`、`reqwest` 等。 ``` import httpx, uuid m = "http://localhost:7777" run = str(uuid.uuid4()) # 记住某些内容 httpx.post(f"{m}/v1/events", json={"events": [{ "id": str(uuid.uuid4()), "run_id": run, "source_input_id": "chat-session-1", "content": "user prefers vegetarian options", "timestamp": "2026-05-03T16:00:00Z", "metadata": {"role": "preference"}, }]}) # 稍后召回(几个月后,同样的调用) events = httpx.get(f"{m}/v1/events", params={"run_id": run}).json() ``` 这就是最简单情况下所需的全部 API。如需更丰富的记忆功能 —— 带类型的声明、矛盾检测、证据溯源 —— 请继续阅读。 ## Mnemos 的适用场景 | 方案 | 最适合 | 权衡 | |---|---|---| | 托管式 AI 记忆服务 | 快速上手,消费级应用 | 供应商云,按次计费,客户数据会离开你的基础设施 | | Vector DBs (Pinecone, Chroma, Weaviate) | 纯语义搜索 | 没有声明/矛盾结构,无证据追踪,无法重放 | | 笔记应用 (Notion, Obsidian, Roam) | 人类组织自己的思维 | 不是为大规模程序化 AI 记忆写入而构建的 | | **Mnemos** | 用于不能离开你服务器的 AI 记忆技术栈 —— 例如受监管的、本地部署的、物理隔离的环境 | 你需要自己运行一个二进制文件 | ## CLI 快速开始 ### 1. 安装 ``` # macOS / Linux (Homebrew) brew tap felixgeelhaar/tap && brew install mnemos # Go(任何支持 Go 1.26+ 的平台) go install go.klarlabs.de/mnemos/cmd/mnemos@latest # Docker docker run --rm ghcr.io/klarlabs-studio/mnemos --version # 从 source 构建 git clone https://github.com/klarlabs-studio/mnemos.git && cd mnemos && make install ``` ### 2. 处理文本 —— 提取声明并检测矛盾 ``` mnemos process --text "The deployment succeeded in production. The deployment did not succeed in production. Response times averaged 45ms." ``` Mnemos 提取了三条声明,检测到了前两条之间的矛盾,并将它们标记为有争议。 ### 3. 带证据查询 ``` mnemos query "What happened with the deployment?" ``` 答案会附带源声明、置信度分数和浮现的矛盾 —— 让你知道什么是真实的,什么是有争议的。 ### 4. 使用你自己的文档进行尝试 ``` mnemos process meeting-notes.md mnemos query "What decisions were made?" ``` 无需 API keys —— 基于规则的提取和矛盾检测可以直接开箱即用。 ### 推荐:添加 LLM provider 以获得最佳效果 如果要查询真实文档,请配置 LLM provider。这将启用语义搜索、更好的提取和有根据的回答: ``` export MNEMOS_LLM_PROVIDER=openai # or: anthropic, gemini, ollama, openai-compat export MNEMOS_LLM_API_KEY=sk-... # LLM 提取 + embeddings + 基于事实的查询回答 mnemos process --llm --embed meeting-notes.md mnemos query --llm "What decisions were made?" ``` 在没有 provider 的情况下,提取和矛盾检测仍然可以通过基于规则的启发式算法完成。查询使用 BM25 关键字匹配,这对于简单问题很有效,但在处理较长文档时可能会忽略细微差别。使用 `--embed`(或配置任何 embedding provider)时,查询会升级为 **hybrid BM25 + cosine** 排序 —— 有关完整的信号细分,请参阅下文的“查询排序”。 ### 可选:用于 AI agents 的 MCP server ``` mnemos mcp # Exposes query_knowledge, process_text, and knowledge_metrics over stdio ``` ### 封装 LangGraph / CrewAI / MCP agent 以进行审计 + 重放 Mnemos 还可以作为任何 AI agent 底层的审计基础。每个 node 或步骤都会发出一个以单一 `run_id` 为 key 的事件;几周后, 只需一次 HTTP 调用即可检索完整的推理链。 ``` # 一个 4 节点的 LangGraph 退款分类 agent,封装了 Mnemos 用于审计: cd examples/refund_triage_langgraph pip install -r requirements.txt python agent.py --customer-id CUST-42 --amount 245.00 # 重放准确的决策链 curl -s "http://localhost:7777/v1/events?run_id=" | jq ``` 该示例使用原生 HTTP(无 SDK),因此你可以清楚地看到每个 node 只需四行代码即可获得可靠的审计轨迹。源码: [`examples/refund_triage_langgraph/`](examples/refund_triage_langgraph/)。 ## 工作原理 ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Ingest │ -> │ Extract │ -> │ Relate │ -> │ Query │ │ (events) │ │ (claims) │ │ (evidence) │ │ (truth) │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ ``` **提取** — 将原始文本转化为结构化的声明(事实、决策、假设) **关联** — 检测声明之间的支持和矛盾关系 **查询** — 返回附带声明、证据和浮现的矛盾的答案 ## 示例输出 ``` { "answer": "Tech stack decisions show contradiction: PostgreSQL vs MySQL", "claims": [ {"text": "We decided to use PostgreSQL", "type": "decision", "confidence": 0.88}, {"text": "The team prefers MySQL", "type": "fact", "confidence": 0.75} ], "contradictions": [ {"from": "claim-1", "to": "claim-2", "type": "contradicts"} ] } ``` ## 为什么选择 Mnemos? | | 传统 RAG | Mnemos | |---|---|---| | 声明可追溯到证据 | ❌ | ✅ | | 浮现矛盾 | ❌ | ✅ | | 本地优先 / 隐私保护 | ❌ | ✅ | | 基于受治理的数据 | ❌ | ✅ | | 随时间演进 | ❌ | ✅ | ## 核心功能 - **证据支撑的声明** — 每个提取的声明都映射到原始材料 - **矛盾检测** — 自动浮现冲突信息 - **本地优先** — 你的数据保留在你的机器上 (`~/.local/share/mnemos/`) - **多 provider 提取** — Anthropic, OpenAI, Gemini, Ollama 以及兼容 OpenAI 的 endpoints - **对开发者友好** — CLI 优先,JSON 输出,支持 MCP,对 pipeline 友好 ## 命令 | 命令 | 描述 | |---------|-------------| | `mnemos process ` | 一步完成摄取 + 提取 + 关联 | | `mnemos process --llm --text ` | 使用基于 LLM 的提取 | | `mnemos ingest ` | 将文档作为事件摄取 | | `mnemos extract --run ` | 从某个 run 的事件中提取声明 | | `mnemos relate` | 检测声明之间的关系 | | `mnemos query ` | 带证据查询 | | `mnemos query --hops ` | 通过 N 个支持/矛盾跳数(最多 5 跳)扩展结果声明 | | `mnemos query --llm ` | 查询并使用 LLM 生成有根据的回答 | | `mnemos metrics` | 知识库统计信息 | | `mnemos audit [--include-embeddings]` | 将整个知识库导出为 JSON,用于合规/备份 | | `mnemos resolve --over [--reason "..."]` | 解决矛盾:胜者 → resolved,败者 → deprecated | | `mnemos resolve --supersedes [--reason "..."]` | 时间替代:在 `new.valid_from` 时关闭 `old.valid_to`。旧声明保留其状态 —— 当它为真时,它就是真的。 | | `mnemos query --at YYYY-MM-DD "..."` | 针对时间有效性层的定点查询 | | `mnemos query --include-history "..."` | 在结果集中包含被替代的声明(默认关闭) | | `mnemos query --entity "..."` | 限制结果仅返回与此 entity 关联的声明 | | `mnemos entities list [--type T]` | 列出规范化的 entities (people/orgs/projects/...) | | `mnemos entities show ` | 显示一个 entity 及其关联的声明 | | `mnemos entities merge ` | 将一个 entity 合并到另一个中(手动规范化) | | `mnemos extract-entities [--all]` | 为早于 v0.9 prompt 的声明回填 entity 链接 | | `mnemos reset [--keep-events] [--yes]` | 清除声明/关系/embeddings(events 可选) | | `mnemos delete-claim ...` | 删除特定声明及其派生状态 | | `mnemos delete-event ...` | 删除 events 并级联删除派生的声明 | | `mnemos reembed [--force] [--dry-run]` | 在当前 embed 配置下(重新)生成声明 embeddings | | `mnemos recompute-trust` | 为每个声明重建 `trust_score` (置信度 × 佐证 × 新鲜度) | | `mnemos dedup [--threshold T] [--force]` | 根据 embedding 余弦相似度合并近乎重复的声明(默认 dry-run) | | `mnemos query --min-trust X "..."` | 仅返回 `trust_score` ≥ X 的声明 | | `mnemos query --kind causes,validates "..."` | 将跳数扩展限制为特定的边类型 (causes, caused_by, supports, contradicts, validates, refutes, action_of, outcome_of, derived_from) | | `mnemos query --service X --env prod --team Y "..."` | 对回答声明应用多租户范围过滤器 | | `mnemos process --no-relate ...` | 跳过 relate 阶段以实现快速摄取;稍后可批量处理 relate | | `mnemos verify [--half-life-days N]` | 更新 `last_verified` 和 `verify_count`;可选的按声明新鲜度覆盖 | | `mnemos init [--force]` | 为当前项目创建 `.mnemos/mnemos.db`(否则解析为 XDG 全局路径) | | `mnemos doctor` | 对安装进行健康检查:store 可达性、schema 应用情况、env 配置、LLM/embed 配置 | | `mnemos quality` | 记忆质量遥测:平均 trust、平均置信度、过期/有争议/矛盾计数 | | `mnemos trust --test= [--service X --env Y --team Z]` | 根据认知可信度将某个需求下的 `test_result` 声明进行排序;浮现胜者及理由 | | `mnemos incident open --title "..." [--severity sev1\|sev2\|sev3\|sev4]` / `incident close ` | 在 Decisions/Outcomes 旁边跟踪事件生命周期 | | `mnemos user create / list / rotate-token` 和 `mnemos agent register / list / authority` | JWT 认证管理:创建操作员用户 + 非人类 agents,管理 authority 分数 | | `mnemos metrics --workspace [--telemetry-opt-in\|--telemetry-opt-out\|--telemetry-send]` | North Star 工作区视图(活跃的 runs / 证据支持的声明)+ 选择性加入匿名化 payload | ### Action + Outcome (v0.13+) 记录真实的运维变更及其观察到的结果,以便合成层能够推导出 Lessons。 | 命令 | 描述 | |---------|-------------| | `mnemos action record --kind --subject [--actor X] [--run R]` | 记录一项运维操作 (deploy, rollback, scale, ...) | | `mnemos action list [--subject X\|--run R]` | 列出已记录的操作 | | `mnemos outcome record --action --result [--metric k=v]...` | 将观察到的结果附加到某个操作上 | | `mnemos outcome list [--action ]` | 列出结果 | ### 合成:Lessons + Playbooks (v0.13+) | 命令 | 描述 | |---------|-------------| | `mnemos synthesize [--min-corroboration N] [--min-confidence X]` | 将 action→outcome 链条聚类为 Lessons | | `mnemos lessons [--service X\|--trigger T]` | 列出经过验证的 lessons | | `mnemos playbook synthesize` | 从共享同一触发器的 Lessons 中推导出 Playbooks | | `mnemos playbook list [--service X]` / `mnemos playbook ` | 浏览 playbooks | | `mnemos playbook show ` | 展示包含具体步骤的完整 playbook | ### Decisions (v0.13+) | 命令 | 描述 | |---------|-------------| | `mnemos decision record --statement "..." --risk [--belief cl_id]... [--alternative "..."]...` | 记录一个带有其置信证据的 agent 决策 | | `mnemos decision list [--risk X]` / `mnemos decision show ` | 审计已记录的决策 | | `mnemos decision attach-outcome ` | 将一个结果关联到先前记录的决策上 | ### Markdown 往返 + 历史 (v0.13+) | 命令 | 描述 | |---------|-------------| | `mnemos export --kind --id [--out file.md]` | 导出为 YAML-frontmatter markdown | | `mnemos import ` | 重新 upsert 手动编辑过的 markdown 文件 | | `mnemos history --kind --id ` | 列出 `*_versions` 中的先前快照 | ### 声明生命周期 每个声明都带有一个状态:`active`、`contested`、`resolved` 或 `deprecated`。状态变更会记录在 `claim_status_history` 中(包含 from, to, when, why),因此每个声明的生命周期都是可审计的。当查询浮现出一个状态在某个时间点发生过变更的声明时,回答文本中会包含一个 `Evolution:` 行来总结其时间线 —— 例如 _"在 2026-04-18 从 contested 转换为 resolved(由 jane 进行证据复核)。"_ | `mnemos mcp` | 通过 stdio 启动 MCP server | | `mnemos serve [--port N]` | 启动 HTTP registry server(默认 `:7777`) | | `mnemos registry connect ` | 将此项目连接到远程 registry | | `mnemos push` | 将本地知识发送 registry | | `mnemos pull` | 将知识从 registry 拉取到本地 DB | ### HTTP Registry (Phase 2B) `mnemos serve` 将本地知识库暴露为一个小巧的 HTTP API,以便其他工具、仪表板或脚本可以在不直接使用 SQLite 的情况下进行读写。跨项目的联邦和命名空间范围界定将在后续提交中实现。 | Endpoint | 方法 | 描述 | |---|---|---| | `/health` | GET | 存活探针 + 版本信息 | | `/v1/events` | GET | 列出 events (`?limit`, `?offset`) | | `/v1/events` | POST | 追加一批 events | | `/v1/claims` | GET | 列出声明 (`?type=fact\|hypothesis\|decision`, `?status=active\|contested\|resolved\|deprecated`, `?limit`, `?offset`) | | `/v1/claims` | POST | Upsert 一批声明(可选包含 `evidence` 链接) | | `/v1/relationships` | GET | 列出关系 (`?type=supports\|contradicts`, `?limit`, `?offset`) | | `/v1/relationships` | POST | Upsert 一批关系 | | `/v1/embeddings` | GET | 列出 embeddings (`?entity_type=event\|claim`, `?limit`, `?offset`) | | `/v1/embeddings` | POST | Upsert 一批 embeddings(vector 以 JSON 浮点数组表示) | | `/v1/metrics` | GET | 计数,镜像对应 `mnemos metrics` | 默认:`limit=50`,上限为 `200`。Port 也接受 `MNEMOS_SERVE_PORT`。请求体大小上限为 5 MB。 **Web UI.** `mnemos serve` 还会在 `GET /` 提供一个最小化的单页 UI。它通过调用上述相同的 `/v1/*` endpoints 来渲染指标、分页声明(带有类型/状态过滤器)以及矛盾列表。HTML 通过 `//go:embed` 嵌入,因此不需要单独的部署步骤 —— 一个二进制文件,一个端口。 **认证。** 所有的写方法(POST/PUT/DELETE)都需要由同一个 `mnemos serve` 实例颁发的 JWT bearer token:`Authorization: Bearer `。读取操作默认保持开放 —— 适用于仅供浏览的仪表板。签名 key 来自 `MNEMOS_JWT_SECRET`(十六进制编码,≥ 32 字节)或 `MNEMOS_AUTH_DIR/jwt-secret`(首次启动时自动创建,权限 0600)。使用 `mnemos token issue` 签发 token;使用 `mnemos token revoke` 撤销。如果未配置验证器,registry 将完全开放(适用于本地开发和受信任的网络)。 客户端使用的 `MNEMOS_REGISTRY_TOKEN`(由 `mnemos push` / `mnemos pull` 用于与*远程* registry 通信)与入站 HTTP 认证无关 —— 请参阅下文的“Push / Pull”。 完整的 HTTP schema:[`api/openapi.yaml`](api/openapi.yaml)。 ### gRPC(与 HTTP 并存) `mnemos serve --grpc-port 7778` 通过 gRPC 暴露相同的 registry 接口,适用于强类型、支持流式的客户端。Schema:[`proto/mnemos/v1/mnemos.proto`](proto/mnemos/v1/mnemos.proto)。该服务镜像了 HTTP 并涵盖了 Phase 2-7 实体:`ListEvents/AppendEvents`、`ListClaims/AppendClaims`、`ListRelationships/AppendRelationships`、`ListEmbeddings/AppendEmbeddings`、`Metrics`,以及针对 `Actions`、`Outcomes`、`Lessons`、`Decisions`、`Playbooks`、`EntityRelationships` 的 `List*/Append*`。认证使用 JWT 验证器(`MNEMOS_JWT_SECRET` 或 `MNEMOS_AUTH_DIR`);发送 `authorization: Bearer ` metadata。如果未配置验证器,则禁用认证 —— 仅适用于本地开发。 ### 在你的应用中集成 Mnemos `mnemos serve` 提供的 HTTP API 是一种集成途径;对于 Go 应用, 你还可以通过根包在进程内嵌入 Mnemos。根据你的运行时 选择最合适的方式即可。 **Go(进程内库,v0.17+)** — `import "go.klarlabs.de/mnemos"`: ``` import ( "go.klarlabs.de/mnemos" _ "go.klarlabs.de/mnemos/internal/store/sqlite" ) mem, err := mnemos.New() // passive mode, XDG storage, bundled Chronos if err != nil { panic(err) } defer mem.Close() _ = mem.Remember(ctx, mnemos.Item{ Type: "decision", Content: "Adopted Postgres for the new service.", }) results, _ := mem.Recall(ctx, mnemos.Query{Text: "Postgres decision"}) ``` 三种模式:`WithPassiveMode()`(无 LLM),`WithSharedProvider(tg, emb)` (agent 运行时提供模型),`WithEnhancedMode(cfg)`(专用 provider)。Chronos 默认打包在进程内;你可以通过 `WithChronos(eng)` 提供你自己的。有关完整的 3 种模式 操作说明 + godoc 示例,请参阅 [`docs/library.md`](docs/library.md)。 HTTP API 和 MCP 传输层仍可用于非 Go 消费者;两者都 通过相同的内部机制路由。 **Go(HTTP 客户端)** — `import "go.klarlabs.de/mnemos/client"`: 当你确实想在 Go 中使用 HTTP(不同的进程,或者非 Go 消费者通过 HTTP 需要强类型客户端)时: ``` c := client.New("http://localhost:7777", client.WithToken("optional-secret"), client.WithLogger(logger), // *bolt.Logger client.WithRetry(retry.Config{ // fortify retry; 5xx + 429 retry, 4xx fail fast MaxAttempts: 3, InitialDelay: 200 * time.Millisecond, MaxDelay: time.Second, BackoffPolicy: retry.BackoffExponential, Jitter: true, }), ) // Write c.Events().Append(ctx, []client.Event{{ ID: "ev_1", RunID: "session-A", SchemaVersion: "v1", Content: "We chose Postgres for the new service", SourceInputID: "src_1", Timestamp: client.FormatTime(time.Now()), }}) // Read with chained filters list, _ := c.Claims().Type("decision").Status("active").Limit(25).List(ctx) for _, claim := range list.Claims { fmt.Printf("[%s] %s\n", claim.Type, claim.Text) } ``` Resource 访问器(`Events()`、`Claims()`、`Relationships()`、`Embeddings()`)返回 fluent builders。过滤方法支持链式调用;终止方法 `List(ctx)` 用于读取,`Append(ctx, ...)` 用于写入。非 2xx 响应将返回 `*client.APIError`,其中包含服务器的状态和消息;可与 `errors.As` 配合使用。内置 `bolt` 请求日志记录和 `fortify` 退避重试机制。可安全用于并发。 **任何其他语言(curl)**: ``` # 追加一个 event curl -X POST http://localhost:7777/v1/events \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer ' \ -d '{"events":[{"id":"ev_1","content":"...","timestamp":"2026-04-19T10:00:00Z"}]}' # 浏览 claims,已筛选 curl 'http://localhost:7777/v1/claims?type=decision&limit=25' ``` **Python(标准库)**: ``` import json, urllib.request req = urllib.request.Request( "http://localhost:7777/v1/events", data=json.dumps({"events": [{"id": "ev_1", "content": "...", "timestamp": "2026-04-19T10:00:00Z"}]}).encode(), headers={"Content-Type": "application/json", "Authorization": "Bearer "}, ) urllib.request.urlopen(req) ``` 对于 AI agent:完全跳过 HTTP API 并使用 MCP 传输(`mnemos mcp`)。支持 MCP 的 agents 可以获得相同的接口,外加已经内置好的 `query_knowledge`、`process_text`、浏览、文件监视和 git 摄取功能。 ### Push / Pull 一旦项目连接到 registry,知识就会像 git 一样流动: ``` mnemos registry connect https://registry.example.com --token mnemos push # send local events/claims/relationships mnemos pull # fetch remote knowledge into the local DB ``` `registry connect` 会写入 `.mnemos/config.json`。`push`/`pull` 的解析优先级为 **CLI flags (`--url`, `--token`) > 环境变量 (`MNEMOS_REGISTRY_URL`, `MNEMOS_REGISTRY_TOKEN`) > 配置文件**,因此 CI 可以在不编辑文件的情况下按任务进行覆盖。 同步是幂等的 —— ID 是去重的 key,因此运行两次 `push`/`pull` 是安全的。Vectors 也会传输:embeddings 以 JSON 浮点数组的形式在同一条传输线上进行位级精确的往返,因此拉取的内容无需重新进行 embedding 即可实现语义排序。声明与证据的链接会随声明一起传输,因此本地查询引擎可以将拉取的声明追溯回其源 events。 **联邦出处。** 拉取的 events 在其 metadata 中会被标记 `pulled_from_registry: `。查询引擎会在回答文本中浮现此信息 —— 源自 registry 的声明会显示为 `… (from https://reg.example.com)`,并且摘要行会对它们进行计数:`Context used 5 event(s) and 8 claim(s) (3 from a connected registry).` 本地声明不加标记(无 registry 的情况保持整洁,不显杂乱)。MCP `query_knowledge` 响应中的 `claim_provenance` 字段以编程方式承载相同的映射。 ## 架构 ``` cmd/mnemos # CLI entrypoint (CLI + mcp + serve subcommands) proto/mnemos/v1 # gRPC schema (Phase 2-7 entities) internal/ domain/ # Core types: Event, Claim, ClaimEvidence, Relationship, EmbeddingRecord, Action, Outcome, Lesson, Decision, Playbook, Scope ports/ # Interfaces for engines and repositories pipeline/ # Shared orchestration (extraction, persistence, embeddings) ingest/ # Multi-format input ingestion parser/ # Input-to-event normalization extract/ # Claim extraction with evidence mapping relate/ # Relationship + causal edge detection (supports, contradicts, causes, validates, ...) query/ # Query assembly and ranking (BM25 + cosine hybrid) embedding/ # Vector embedding client abstraction llm/ # LLM client abstraction (multi-provider) synthesize/ # Cluster action→outcome chains into Lessons; Lessons → Playbooks markdown/ # YAML-frontmatter round-trip for Lessons + Playbooks adapters/outcomes/ # Pull-based Outcome sources (Prometheus instant-query) store/ # URL-scheme dispatched repository registry (ADR 0001) store/sqlite/ # SQLite + FTS5 (sqlc-generated) store/memory/ # In-process backend store/postgres/ # Postgres / Postgres-wire-compatible engines store/mysql/ # MySQL / MariaDB / MySQL-wire-compatible engines store/libsql/ # libSQL / Turso (remote + local file) workflow/ # Job runner with retries and structured logs trust/ # Trust scoring (confidence × corroboration × freshness) autoedge/ # Polymorphic cross-entity edges + auto-fire auth/ # JWT signing + bearer-token enforcement server/ # HTTP REST + gRPC server wiring ``` ## 环境变量 | 变量 | 描述 | |----------|-------------| | `MNEMOS_DB_URL` | 存储 DSN,按 URL scheme 分发:`sqlite:///var/lib/mnemos/mnemos.db`, `memory://`, `postgres://...`, `mysql://...`, `libsql://...`。未设置时,Mnemos 会从 CWD 向上查找 `.mnemos/mnemos.db`,找不到则回退到 `~/.local/share/mnemos/mnemos.db`。参见 [ADR 0001](docs/adr/0001-multi-backend-storage.md)。 | | `MNEMOS_LLM_PROVIDER` | `anthropic`, `openai`, `gemini`, `ollama`, `openai-compat` | | `MNEMOS_LLM_API_KEY` | API key(云供应商必填) | | `MNEMOS_LLM_MODEL` | 模型覆盖(可选) | | `MNEMOS_LLM_BASE_URL` | 自定义 endpoint。`openai-compat` 必填。**当 Mnemos 与 Ollama 守护进程不在同一主机时,`ollama` 也必填** —— 最常见的情况是 Mnemos 运行在容器中,而 Ollama 运行在主机上(Docker Desktop 为 `http://host.docker.internal:11434`,Linux 为 `http://172.17.0.1:11434`)。`ollama` 默认值为 `http://localhost:11434`。 | | `MNEMOS_LLM_TIMEOUT` | 每次请求的 LLM HTTP 超时时间(默认 `120s`)。针对缓慢的本地模型或大量的 completions 请增加此值:`MNEMOS_LLM_TIMEOUT=5m`。 | | `MNEMOS_EXTRACT_MODEL` | 仅针对 extract 阶段覆盖 `MNEMOS_LLM_MODEL`。允许你在提取时使用强模型,而在其他地方使用较小的模型。 | | `MNEMOS_JOB_TIMEOUT` | 整个工作流任务的截止时间(默认 `10m`)。如果你的 provider 足够慢,导致一次完整的 `process` 运行超过 10 分钟,请调大此值。 | | `MNEMOS_EMBED_PROVIDER` | Embedding provider(回退到 `LLM_PROVIDER`) | | `MNEMOS_EMBED_API_KEY` | Embedding API key(回退到 `LLM_API_KEY`) | | `MNEMOS_EMBED_MODEL` | Embedding 模型覆盖(可选) | | `MNEMOS_EMBED_BASE_URL` | Embedding endpoint(与 `MNEMOS_LLM_BASE_URL` 的容器/主机注意事项相同) | | `MNEMOS_EMBED_TIMEOUT` | 每次请求的 embedding HTTP 超时时间(默认 `60s`) | | `MNEMOS_AUTH_DIR` | 用于存储 JWT 签名密钥的目录(默认:项目 `.mnemos/` 或 `$HOME/.mnemos/`)。在只读根文件系统上运行时(Docker `read_only: true`,k8s `readOnlyRootFilesystem: true`),请通过指向一个可写卷来覆盖此设置。 | | `MNEMOS_JWT_SECRET` | 十六进制编码的 JWT 签名密钥(≥32 字节)。设置后,优先于文件路径;适用于你宁愿在 CI/Kubernetes 中将密钥作为环境变量注入而不想挂载文件的场景。 | | `MNEMOS_LLM_CACHE_MAX_BYTES` | `data/cache/llm-extraction/` 下的 LLM 提取缓存上限(默认 `1 GiB`;`0` 表示禁用逐出)。按最旧 mtime 的文件优先逐出。 | | `MNEMOS_DB_MAX_CONNS` | Postgres/MySQL 连接池 `MaxOpenConns`(默认 `25`)。 | | `MNEMOS_DB_MAX_IDLE_CONNS` | Postgres/MySQL 连接池 `MaxIdleConns`(默认 `5`)。 | | `MNEMOS_DB_CONN_MAX_LIFETIME` | Postgres/MySQL 连接池 `ConnMaxLifetime`(默认 `30m`)。 | | `MNEMOS_TELEMETRY_OPTIN` | 设置为真值(`1`/`true`/`yes`)以加入匿名化使用 payload。默认关闭。参见 [`docs/telemetry.md`](docs/telemetry.md)。 | | `MNEMOS_TELEMETRY_ENDPOINT` | `mnemos metrics --workspace --telemetry-send` 的 POST 目标。未设置 = 无目标 = 无请求,即使激活了加入选项也是如此。 | ### 信任度评分 (v0.7+) 每个声明都带有一个 `trust_score ∈ [0, 1]`,它源自三个 LLM 无法伪造的信号: ``` trust = confidence × corroboration × freshness corroboration = 1 + ln(evidence_count) × 0.2 # 1 source: 1.0; 5: 1.32; 20: 1.60 freshness = max(0.3, exp(-days_since_latest / 90)) # 90-day half-life, floor 0.3 ``` 该分数在每次 `process` 运行后自动重新计算;你 可以使用 `mnemos recompute-trust` 手动重建它(例如,在 升级或调整 `internal/trust` 中的常量之后)。 `mnemos query --min-trust 0.5 "..."` 会在排序前过滤掉 低置信度的结果。`mnemos metrics` 会报告 `avg_trust` 和 `low_trust_count`,以便一目了然地查看语料库质量。 trust-scoring 策略位于 `internal/trust/trust.go` —— 在此处 更改常量以为你的语料库重新调优,然后运行 `mnemos recompute-trust` 进行回填。 ### 混检索 (v0.10+) Mnemos 现在使用混合信号对查询结果进行排序: - 基于 FTS5 关键字索引的 **BM25**(v0.10 引入)可捕获 纯余弦相似度会漏掉的词法匹配 —— 专有名词、精确的术语、代码片段。 - 基于存储的 embeddings 的 **余弦相似度** 可捕获 BM25 漏掉的释义和同义词。 每个信号都会针对每次查询被最大归一化到 `[0, 1]`,然后 以等权重组合成一个单一的复合分数。当只有一个信号可用时 (尚无 embeddings,或由于某种原因没有 FTS 索引), 该信号将承担全部权重,无需进一步调整。 内存中的 token 重叠排序器作为 test doubles 和无 embedding、 无 FTS 部署的最终 fallback 保留下来。 FTS5 索引(`events_fts`、`claims_fts`)会在 v0.9 → v0.10 schema 迁移时 自动创建并回填;无需操作员干预。它们由源表上的 INSERT/UPDATE/DELETE 触发器保持最新,因此读取操作 不必考虑数据陈旧问题。 ### Entity 层 (v0.9+) Mnemos 将名词短语("Felix Geelhaar"、"Acme"、 "PostgreSQL"、"Berlin"、...)规范化为独立于任何单个 声明的、第一-class 的 entity 节点。一旦 entities 存在,你就可以 提出针对 entity 范围的问题: ``` mnemos entities list --type person mnemos entities show "Felix Geelhaar" mnemos query --entity "Felix Geelhaar" "what does he need this week?" ``` 它们是如何创建的。v1.4 LLM 提取 prompt 会用其提到的命名实体 标记每个声明。在 `mnemos process` 持久化声明后,pipeline 会将这些标签物化到 `entities` 和 `claim_entities` 表中,按 (normalized_name, type) 进行去重,因此只有在 LLM 赋予 不同名称时,"Felix"、"felixgeelhaar" 和 "Felix Geelhaar" 才会得到不同的 ids —— 手动规范化可以 消除这种差异: ``` mnemos entities merge en_abc123 en_def456 # winner absorbs loser ``` 对于早于 v0.9 的数据库(在 v1.3 prompt 或更早版本下提取的声明),`mnemos extract-entities --all` 会重新针对存储的声明文本运行 LLM 以回填 entity 链接。它会通过 LLM 缓存进行批处理,因此在相同内容上重新运行是免费的。 ### 时间有效性 (v0.8+) 每个声明都带有一个有效期 —— `valid_from`(事实 变为真实的时间)和 `valid_to`(它不再为真的时间;NULL 表示“仍然有效”)。pipeline 在插入时从最早的 证据 event 的时间戳推导出 `valid_from`,因此回填的 摄取无需操作员费力即可获得正确的时间线。 由此衍生出两种新行为: - **默认查询会隐藏被取代的声明。** `mnemos query "..."` 会过滤掉 `valid_to` 处于过去的声明,因此一旦 "senior engineer" 关闭了 其时间间隔,"Felix is a junior engineer" 就不再出现。传递 `--include-history` 可同时查看两者。 - **定点查询。** `mnemos query --at 2026-03-01 "..."` 返回该日期时的答案 —— 非常适合用于审计轨迹 和“我们当时相信什么?”之类的问题。 要在新声明取代旧声明时关闭旧声明的时间间隔: ``` mnemos resolve cl_new --supersedes cl_old --reason "promoted 2026-04" ``` `--supersedes` 不同于 `--over`(矛盾 解决器)。`--over` 表示“其中一个一直都是错的,而 另一个是对的”;`--supersedes` 表示“这个事实发生了变化”。后者 保留旧声明的状态 —— 当它为真时它就是真的 —— 并且只设置 `valid_to`。自动取代(无需操作员干预的启发式 检测)已在 v0.9 路线图上。 ### 升级 Mnemos v0.6.1+ 会在 `sqlite.Open` 时自动迁移较旧的数据库 —— 无需执行 `mnemos reset` 或删除 DB。迁移是幂等的, 并且会添加 auth 功能在 v0.6.0 中引入的 `created_by` / `changed_by` 列。 Schema 生成通过 `PRAGMA user_version` 跟踪,因此在已迁移的 DB 上重新运行 是空操作。 ### 本地模型 (Ollama) 已测试的组合和已知怪癖。提取 pipeline 对常见的 reasoning-model 输出(`` 块、散文式前言、` ```json ` 围栏)具有容错性,因此大多数模型都可以工作;表格中列出了例外情况。 | 模型 | LLM | Embed | 备注 | |---|---|---|---| | `llama3.2:latest` | ✅ | — | 快速、可靠、JSON 规范 | | `mistral:latest` | ✅ | — | 快速;偶尔会出现散文式前言(已处理) | | `qwen3:*` | ✅ | — | 会发出 `...` 块(自动剥离);如果推理过程较长,请配合 `MNEMOS_LLM_TIMEOUT=2m+` 使用 | | `deepseek-r1:*` | ✅ | — | 同 qwen3 的推理块处理方式 | | `gpt-oss:20b` | ⚠️ | — | 结构化输出能力强,但在消费级硬件上速度慢 → 设置 `MNEMOS_LLM_TIMEOUT=5m` 和 `MNEMOS_JOB_TIMEOUT=15m` | | `gemma3:*` | ❌ | — | 当前 Ollama 构建版本不支持 tool/结构化输出 | | `nomic-embed-text` | — | ✅ | 768 维 embeddings,速度快;推荐的本地 embed 模型 | 完全本地化 Mnemos 的快速开始: ``` ollama pull llama3.2 nomic-embed-text export MNEMOS_LLM_PROVIDER=ollama export MNEMOS_LLM_MODEL=llama3.2 export MNEMOS_EMBED_MODEL=nomic-embed-text mnemos process --llm --embed --text "Your knowledge here" ``` **容器注意事项。** 当 Mnemos 运行在 Docker/Podman 中,而 Ollama 运行在宿主机上时,请设置 `MNEMOS_LLM_BASE_URL=http://host.docker.internal:11434`(Docker Desktop)或 `http://172.17.0.1:11434`(Linux Docker)。默认的 `http://localhost:11434` 会解析到容器自身,并会因为连接被拒绝而失败。 ## 开发 ``` make check # Format, lint, test, build (CI equivalent) make build # Build bin/mnemos make test # Run tests (includes 102 eval cases) make sqlc # Regenerate sqlc query code make release-check # Validate GoReleaser config ``` ## 状态 Phase 1: 开发者原语 — 现已可用。 - 基于规则和基于 LLM 的提取,具备评估覆盖率 - 用于语义搜索的 Embeddings - CLI + MCP server + HTTP REST + gRPC 入口点 - 102 个评估用例(90 个提取 + 12 个关系检测) - 根据 [ADR 0001](docs/adr/0001-multi-backend-storage.md) 的可插拔存储后端:SQLite、内存、Postgres、MySQL/MariaDB、libSQL/Turso ### Evidence + Causality + Outcomes (v0.13+) Mnemos 在 evidence 层之上发布了一个自我学习循环: - **因果边** — `causes`、`caused_by`、`action_of`、`outcome_of`、`validates`、`refutes`、`derived_from` 将关系图扩展到逻辑一致性之外。`relate.DetectCausal` 根据 event-time + 共享 entity 信号推断这些关系;可选的 `relate.DetectCausalLLM` 通过 LLM 消歧来增强边缘案例。 - **Action + Outcome 记录** — `mnemos action record` / `mnemos outcome record` 捕获运维变更及其观察到的指标。Prometheus 拉取适配器 (`internal/adapters/outcomes/prometheus.go`) 会抓取指标并自动生成 Outcomes。 - **Lessons 合成** — `mnemos synthesize` 将 action→outcome 链聚类为经过验证的 Lessons(置信度 = 佐证 × 一致性 × 时效性)。 - **Playbooks** — `mnemos playbook synthesize` 从 Lesson 集群中推导出仅包含步骤的运维智能。消费者可以通过他们拥有的任何执行层(agent 运行时、进程内执行器、程序化系统)来运行它们。 - **Decisions** — `mnemos decision record` 审计带有置信声明、备选方案和风险级别的 agent 推理;结果稍后通过 `decision attach-outcome` 附加。 - **时间强化** — 基于单个声明的 `last_verified`、`verify_count`、`half_life_days`。`mnemos verify` 重新确认声明;`Answer.StaleClaimIDs` 浮现低于信任下限的衰减。 - **多租户范围** — Claims、Lessons、Decisions、Playbooks 上的 `Scope{Service, Env, Team}`;`mnemos query --service X --env prod` 过滤回答。 - **人类可编辑层** — `mnemos export` + `mnemos import` 将 Lessons/Playbooks 往返转换为 Git 友好的 YAML+markdown;`mnemos history` 列出来自系统版本化 `*_versions` 表的快照。 营销主张:*"基于证据的记忆,随着时间的推移从行动中学习,具有可证明的因果关系、有范围限制的多租户以及人类可编辑的修正循环。"* ## 贡献 欢迎贡献。有关产品方向,请参阅 [PRD.md](./PRD.md);有关技术设计,请参阅 [TDD.md](./TDD.md)。 ## 发布 带有标签的版本通过 `.github/workflows/release.yml` 使用 GoReleaser 发布,包括 Homebrew formula 更新和 Docker 镜像。人类可读的发布历史:[`CHANGELOG.md`](CHANGELOG.md)。 ## 安全性 认证表面、威胁模型、容器强化和密钥管理:[`SECURITY.md`](SECURITY.md)。 ## 遥测 默认关闭。必须保持两个独立的门槛(加入标志 + endpoint URL)才能让任何 payload 离开主机。隐私姿态、payload schema 以及加入/退出流程:[`docs/telemetry.md`](docs/telemetry.md)。 ## 可靠性 SLO:30 天内 99.9% 的可用性,p99 读取 250ms,p99 写入 500ms。错误预算消耗警报见 [`SLO.md`](SLO.md)。`internal/trust` 上的突变测试门槛杀灭率为 70%(目前为 100% / 捕获了 45 个突变体) —— 参见 [`docs/testing/mutation.md`](docs/testing/mutation.md)。 ## 许可证 MIT
标签:AI智能体, EVTX分析, Go语言, Python脚本, RAG基础设施, 双时态数据库, 审计日志, 日志审计, 时序数据库, 本地部署, 程序破解, 记忆存储, 请求拦截