Skip to content

Commit 821181b

Browse files
authored
docs: update setup and configuration docs for RFC-011, RFC-012 (#110)
Updates all documentation to reflect the new LLM provider options: - local_backend (llama-cpp-python / onnxruntime-genai) for provider: local - litellm provider for unified 100+ provider routing - New env vars, extras, and config examples Files changed: - docs/reference/configuration.md: full rewrite with local_backend field, litellm provider docs, provider quick-reference table, 8 LiteLLM model prefix examples, use-case-specific config snippets, updated env var tables - docs/index.md: architecture overview updated with 4 LLM provider options, LLM provider comparison table in nav, version bumped to 2.5.0 - docs/tutorials/01-quickstart.md: installation options section, provider config reference in LLM Quick Reference - docs/how-to/integrate-llm-agent.md: LLM provider options note in Quick Reference - docs/how-to/upgrade.md: 2.2.x -> 2.5.x upgrade section with RFC-011 and RFC-012 feature descriptions and migration steps
1 parent 968c9c8 commit 821181b

5 files changed

Lines changed: 230 additions & 41 deletions

File tree

docs/how-to/integrate-llm-agent.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,4 +227,6 @@ def enrich_with_entities(task: str) -> dict:
227227

228228
**Entity retrieval**: `mm.recall_actor()`, `mm.recall_tool()`, `mm.recall_cve()` provide O(1) indexed lookups for targeted enrichment.
229229

230+
**LLM provider options**: Configure via `config.yaml` `llm:` section. The default is `provider: ollama` with `model: qwen3.5:9b`. Optional extras: `pip install zettelforge[local]` for in-process GGUF inference, `pip install zettelforge[local-onnx]` for ONNX inference, `pip install zettelforge[litellm]` for LiteLLM routing to 100+ cloud providers.
231+
230232
**Performance**: `remember()` is fast (no LLM). `remember_with_extraction()` is slow (LLM per fact). `get_context()` is fast (vector search). Tune `min_importance` and `max_facts` for throughput.

docs/how-to/upgrade.md

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,52 @@ the full list of changes per release see
1616

1717
## Upgrade matrix
1818

19-
| From To | Required action | Data migration? |
19+
| From -> To | Required action | Data migration? |
2020
|-----------|-----------------|-----------------|
21-
| 2.2.x → 2.2.y (patch) | `pip install -U zettelforge` | No |
22-
| 2.1.x → 2.2.x | `pip install -U zettelforge` + run JSONL → SQLite migration | **Yes** |
23-
| 2.0.x → 2.2.x | Upgrade in two hops via 2.1.x is recommended but not required | **Yes** |
24-
| < 2.0 | Not supported — export notes manually, fresh-install 2.2.x |
21+
| 2.4.x -> 2.5.x | `pip install -U zettelforge` | No |
22+
| 2.2.x -> 2.4.x | `pip install -U zettelforge` | No |
23+
| 2.1.x -> 2.2.x | `pip install -U zettelforge` + run JSONL -> SQLite migration | **Yes** |
24+
| 2.0.x -> 2.2.x | Upgrade in two hops via 2.1.x is recommended but not required | **Yes** |
25+
| < 2.0 | Not supported -- export notes manually, fresh-install 2.2.x |
26+
27+
## 2.2.x -> 2.5.x
28+
29+
No data migration required. The following new features are available as optional extras:
30+
31+
### Local LLM backend selection (RFC-011)
32+
33+
`provider: local` now supports two in-process inference engines via `local_backend`:
34+
35+
- **`llama-cpp-python`** (default) -- GGUF models. No config change needed if you already use `provider: local`.
36+
- **`onnxruntime-genai`** -- ONNX models with AMD ROCm, Intel OpenVINO, Apple CoreML support. Requires `pip install zettelforge[local-onnx]` and `local_backend: onnxruntime-genai` in config.
37+
38+
The `LlamaCppBackend` code was extracted from `LocalProvider` into its own class. Behavior is identical for existing users. See the [Configuration Reference](reference/configuration.md#llm) for example configs.
39+
40+
### LiteLLM unified provider (RFC-012)
41+
42+
A new `provider: litellm` option routes to 100+ LLM providers through a single interface, replacing the need for separate `openai_compat`, `anthropic`, `bedrock`, and `vertex` providers.
43+
44+
To use: `pip install zettelforge[litellm]`, then configure:
45+
46+
```yaml
47+
llm:
48+
provider: litellm
49+
model: gpt-4o
50+
api_key: ${OPENAI_API_KEY}
51+
```
52+
53+
Model name prefix routing determines the backend automatically: `gpt-4o` -> OpenAI, `claude-sonnet-4-20250514` -> Anthropic, `groq/llama-3.3-70b-versatile` -> Groq, etc.
54+
55+
### Steps
56+
57+
1. `pip install -U 'zettelforge>=2.5.0'`
58+
2. (Optional) Install optional extras:
59+
```bash
60+
pip install zettelforge[local-onnx] # ONNX local inference
61+
pip install zettelforge[litellm] # LiteLLM cloud provider routing
62+
pip install zettelforge[local-all] # both local backends
63+
```
64+
3. Update `config.yaml` if you want to use new providers (existing configs continue to work unchanged).
2565

2666
## 2.1.x → 2.2.x
2767

docs/index.md

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,23 @@ description: ZettelForge documentation — tutorials, API reference, and archite
44
diataxis_type: "navigation"
55
audience: "all"
66
tags: [overview, navigation]
7-
last_updated: "2026-04-18"
8-
version: "2.3.0"
7+
last_updated: "2026-04-25"
8+
version: "2.5.0"
99
---
1010

1111
# ZettelForge Documentation
1212

1313
**Your SOC's most expensive asset walks out the door every day.**
1414

15-
When a senior analyst leaves, two or three years of context walks out with them customer environments, prior investigations, actor TTPs, false-positive patterns, every hard-won "wait, we've seen this before." ZettelForge is an agentic memory system built so that context stays with the team.
15+
When a senior analyst leaves, two or three years of context walks out with them -- customer environments, prior investigations, actor TTPs, false-positive patterns, every hard-won "wait, we've seen this before." ZettelForge is an agentic memory system built so that context stays with the team.
1616

17-
It extracts CVEs, threat actors, IOCs, and ATT&CK techniques from analyst notes and threat reports, resolves aliases (APT28 = Fancy Bear = STRONTIUM = Sofacy), and indexes vector-embedded Zettelkasten notes in LanceDB for retrieval in natural language by analysts and Claude Code via MCP. Community defaults use SQLite + LanceDB, while TypeDB-backed STIX 2.1 graph storage is optional. No external API keys are required. Default LLM traffic stays on localhost (Ollama), and fully offline operation is possible after required models are preloaded.
17+
It extracts CVEs, threat actors, IOCs, and ATT&CK techniques from analyst notes and threat reports, resolves aliases (APT28 = Fancy Bear = STRONTIUM = Sofacy), and indexes vector-embedded Zettelkasten notes in LanceDB for retrieval in natural language by analysts and Claude Code via MCP. Community defaults use SQLite + LanceDB, while TypeDB-backed STIX 2.1 graph storage is optional. No external API keys are required by default. Fully offline operation is possible with the `local` provider after preloading models. For cloud-connected deployments, the `litellm` provider routes to OpenAI, Anthropic, Google, Groq, and 100+ other backends through a single interface.
1818

1919
**New here?** Start with the [5-minute Quickstart](tutorials/01-quickstart.md), or `pip install zettelforge`.
2020

2121
## Architecture Overview
2222

23-
ZettelForge uses a hybrid storage architecture with in-process AI. TypeDB stores structured CTI entities and their relationships using the STIX 2.1 ontology. LanceDB stores unstructured notes as 768-dimensional vectors with IVF_PQ indexing. Embeddings are generated in-process by fastembed (nomic-embed-text-v1.5-Q, ONNX runtime, ~7ms/embed) and LLM inference runs in-process via llama-cpp-python (Qwen2.5-3B-Instruct Q4_K_M GGUF). No external AI services are required by default. The BlendedRetriever fuses results from both stores at query time, weighting vector similarity against graph traversal based on the classified intent of the query.
23+
ZettelForge uses a hybrid storage architecture with in-process AI. TypeDB stores structured CTI entities and their relationships using the STIX 2.1 ontology. LanceDB stores unstructured notes as 768-dimensional vectors with IVF_PQ indexing. Embeddings are generated in-process by fastembed (nomic-embed-text-v1.5-Q, ONNX runtime, ~7ms/embed). LLM inference runs through one of four backends selected by `llm.provider`: in-process GGUF via `llama-cpp-python`, in-process ONNX via `onnxruntime-genai`, Ollama HTTP, or LiteLLM routing to 100+ cloud providers. No external AI services are required by default. The BlendedRetriever fuses results from both stores at query time, weighting vector similarity against graph traversal based on the classified intent of the query.
2424

2525
Ingestion follows a two-phase pipeline. The **FactExtractor** distills raw text into scored candidate facts using an LLM. The **MemoryUpdater** compares each fact against existing notes and decides whether to ADD, UPDATE, DELETE, or NOOP -- preventing duplicates and keeping the knowledge base current.
2626

@@ -62,6 +62,19 @@ graph TB
6262
end
6363
```
6464

65+
## LLM Provider Options
66+
67+
ZettelForge offers four LLM provider options, configured via `llm.provider` in `config.yaml`:
68+
69+
| Provider | Installation | Use Case | Configuration |
70+
|:---------|:-------------|:---------|:--------------|
71+
| `local` | `pip install zettelforge[local]` | Fully offline GGUF inference | `provider: local` + `local_backend: llama-cpp-python` |
72+
| `local` (ONNX) | `pip install zettelforge[local-onnx]` | Offline ONNX, AMD ROCm, DirectML | `provider: local` + `local_backend: onnxruntime-genai` |
73+
| `ollama` | core (no extra) | Local Ollama server (default) | `provider: ollama` + `url: http://localhost:11434` |
74+
| `litellm` | `pip install zettelforge[litellm]` | 100+ cloud providers, single interface | `provider: litellm` + `model: gpt-4o` |
75+
76+
See the [Configuration Reference](reference/configuration.md) for full details on all provider options, API key management, and example configurations.
77+
6578
## Documentation Map
6679

6780
This documentation follows the [Diataxis framework](https://diataxis.fr/), organized into four quadrants.
@@ -89,17 +102,17 @@ Practical recipes for specific tasks you need to accomplish.
89102
| [Configure TypeDB](how-to/configure-typedb.md) | Docker setup, schema deployment, and troubleshooting. |
90103
| [Configure LanceDB](how-to/configure-lancedb.md) | Tune IVF_PQ index, similarity threshold, and entity boost. |
91104
| [Integrate with Your LLM Agent](how-to/integrate-llm-agent.md) | Use `get_context()` and `ProactiveAgentMixin` in agent loops. |
92-
| [Configure OpenCTI Integration](how-to/configure-opencti.md) | Bi-directional sync with OpenCTI via pycti — pull threat intelligence, push notes as STIX reports. (requires zettelforge-enterprise) |
105+
| [Configure OpenCTI Integration](how-to/configure-opencti.md) | Bi-directional sync with OpenCTI via pycti. (requires zettelforge-enterprise) |
93106

94107
### Reference (Information-Oriented)
95108

96109
Exact specifications for every public class, method, and configuration option.
97110

98111
| Reference | Description |
99112
|-----------|-------------|
100-
| [Memory Manager API](reference/memory-manager-api.md) | `MemoryManager` all 19 public methods with full type signatures. |
113+
| [Memory Manager API](reference/memory-manager-api.md) | `MemoryManager` -- all 19 public methods with full type signatures. |
101114
| [STIX 2.1 Schema](reference/stix-schema.md) | 9 entity types, 8 relation types, TypeDB functions, and type mappings. |
102-
| [Configuration](reference/configuration.md) | All `config.yaml` keys, types, defaults, and environment variable overrides. |
115+
| [Configuration](reference/configuration.md) | All `config.yaml` keys, types, defaults, environment variable overrides, provider quick-reference, and example configs by use case. |
103116
| [Retrieval Policies](reference/retrieval-policies.md) | Intent-to-policy weight mapping, scoring formulas, merge algorithm. |
104117
| [Governance Controls](reference/governance-controls.md) | GOV-003/007/011/012 enforcement matrix. |
105118

@@ -129,9 +142,18 @@ Background context and design rationale for the system's architecture.
129142
- **Governance enforcement** -- GOV-003 (data classification), GOV-007 (retention), GOV-011 (access control), GOV-012 (audit) validated on every operation.
130143
- **Sigma rule generation** -- Produce detection rules from actor TTPs and indicators stored in memory.
131144
- **Proactive context injection** -- `ContextInjector` pushes relevant memories into agent prompts before the agent asks.
145+
- **Multi-backend LLM** -- Four provider options: in-process GGUF (llama-cpp-python), in-process ONNX (onnxruntime-genai), Ollama HTTP, and LiteLLM unified routing to 100+ cloud providers.
132146

133147
## LLM Quick Reference
134148

135-
ZettelForge (v2.3.0, MIT license) is an agentic memory system for cyber threat intelligence. It requires Python 3.10+. By default, storage uses SQLite for the primary backend together with LanceDB for vector-indexed notes; TypeDB 3.x via Docker on port 1729 is an optional graph backend/integration rather than a requirement. Embeddings run in-process via fastembed (nomic-embed-text-v1.5-Q, 768-dim, ONNX). The default LLM provider is Ollama. Local in-process inference via llama-cpp-python (for example, with a Qwen2.5-3B-Instruct Q4_K_M GGUF) is an optional configuration, and the implicit provider fallback is local to Ollama rather than Ollama to local. Storage therefore defaults to SQLite + LanceDB, while optional TypeDB-backed deployments can hold a STIX 2.1 knowledge graph with 9 entity types (threat-actor, malware, tool, attack-pattern, vulnerability, campaign, indicator, infrastructure, zettel-note) and 8 relation types (uses, targets, attributed-to, indicates, mitigates, mentioned-in, supersedes, alias-of). When TypeDB is enabled, graph-oriented functions include get_aliases, get_tools_used, and get_entity_notes. The system seeds 36 CTI aliases at startup (APT28/Fancy Bear/Strontium, APT29/Cozy Bear/Midnight Blizzard, Lazarus/Hidden Cobra/Diamond Sleet, Sandworm/Seashell Blizzard, Volt Typhoon/Bronze Silhouette, Kimsuky/Emerald Sleet, Turla/Secret Blizzard, MuddyWater/Mango Sandstorm, plus tool aliases for Cobalt Strike and Mimikatz).
149+
ZettelForge (v2.5.0, MIT license) is an agentic memory system for cyber threat intelligence. It requires Python 3.10+. By default, storage uses SQLite together with LanceDB for vector-indexed notes; TypeDB 3.x via Docker on port 1729 is an optional graph backend. Embeddings run in-process via fastembed (nomic-embed-text-v1.5-Q, 768-dim, ONNX). The default LLM provider is Ollama (`provider: ollama`, `model: qwen3.5:9b`).
150+
151+
Three additional LLM providers are available as optional extras:
152+
153+
- **`provider: local`** with `pip install zettelforge[local]` for in-process GGUF inference via llama-cpp-python (fully offline, Qwen2.5-3B-Instruct Q4_K_M default).
154+
- **`provider: local` with `local_backend: onnxruntime-genai`** and `pip install zettelforge[local-onnx]` for in-process ONNX inference (AMD ROCm, Intel OpenVINO, Apple CoreML support).
155+
- **`provider: litellm`** with `pip install zettelforge[litellm]` for unified routing to 100+ providers (OpenAI, Anthropic, Google, Groq, Together AI, AWS Bedrock, OpenRouter, and more) via model name prefix matching. API keys via config or standard environment variables.
156+
157+
Storage defaults to SQLite + LanceDB, while optional TypeDB-backed deployments can hold a STIX 2.1 knowledge graph with 9 entity types (threat-actor, malware, tool, attack-pattern, vulnerability, campaign, indicator, infrastructure, zettel-note) and 8 relation types (uses, targets, attributed-to, indicates, mitigates, mentioned-in, supersedes, alias-of). When TypeDB is enabled, graph-oriented functions include get_aliases, get_tools_used, and get_entity_notes. The system seeds 36 CTI aliases at startup (APT28/Fancy Bear/Strontium, APT29/Cozy Bear/Midnight Blizzard, Lazarus/Hidden Cobra/Diamond Sleet, Sandworm/Seashell Blizzard, Volt Typhoon/Bronze Silhouette, Kimsuky/Emerald Sleet, Turla/Secret Blizzard, MuddyWater/Mango Sandstorm, plus tool aliases for Cobalt Strike and Mimikatz).
136158

137-
The primary interface is `MemoryManager`. `remember(content)` stores a note with entity extraction, alias resolution, knowledge graph update, supersession check, and causal triple extraction. `remember_with_extraction(content)` runs the two-phase pipeline: FactExtractor distills scored facts, MemoryUpdater compares each against existing notes and applies ADD/UPDATE/DELETE/NOOP. `remember_report(content)` chunks long text and runs two-phase extraction per chunk. `recall(query)` classifies intent (factual/temporal/relational/causal/exploratory), runs BlendedRetriever with policy-weighted vector + graph scores, and returns ranked MemoryNote objects. `recall_actor(name)`, `recall_cve(id)`, `recall_tool(name)` perform fast entity-indexed lookups. `synthesize(query, format)` retrieves notes and produces an LLM-synthesized answer in one of four formats: direct_answer, synthesized_brief, timeline_analysis, or relationship_map. `get_entity_relationships(type, value)` and `traverse_graph(type, value, depth)` expose raw graph queries. Governance policies GOV-003 (data classification), GOV-007 (retention), GOV-011 (access control), and GOV-012 (audit) are enforced automatically on every operation via GovernanceValidator. Configuration lives in config.yaml with sections for storage, typedb, embedding, llm, extraction, retrieval, synthesis, cache, governance, and logging. The BlendedRetriever weights vector vs. graph results using the IntentClassifier's traversal policy: factual queries favor entity lookup, relational queries favor graph BFS, exploratory queries balance both. Notes support supersession (old note marked superseded_by, excluded from recall) and temporal edges for timeline queries.
159+
The primary interface is `MemoryManager`. `remember(content)` stores a note with entity extraction, alias resolution, knowledge graph update, supersession check, and causal triple extraction. `remember_with_extraction(content)` runs the two-phase pipeline: FactExtractor distills scored facts, MemoryUpdater compares each against existing notes and applies ADD/UPDATE/DELETE/NOOP. `remember_report(content)` chunks long text and runs two-phase extraction per chunk. `recall(query)` classifies intent (factual/temporal/relational/causal/exploratory), runs BlendedRetriever with policy-weighted vector + graph scores, and returns ranked MemoryNote objects. `recall_actor(name)`, `recall_cve(id)`, `recall_tool(name)` perform fast entity-indexed lookups. `synthesize(query, format)` retrieves notes and produces an LLM-synthesized answer in one of four formats: direct_answer, synthesized_brief, timeline_analysis, or relationship_map. `get_entity_relationships(type, value)` and `traverse_graph(type, value, depth)` expose raw graph queries. Governance policies GOV-003 (data classification), GOV-007 (retention), GOV-011 (access control), and GOV-012 (audit) are enforced automatically on every operation via GovernanceValidator. Configuration lives in config.yaml with sections for storage, typedb, embedding, llm, extraction, retrieval, synthesis, cache, governance, logging, lance, and opencti. The BlendedRetriever weights vector vs. graph results using the IntentClassifier's traversal policy: factual queries favor entity lookup, relational queries favor graph BFS, exploratory queries balance both. Notes support supersession (old note marked superseded_by, excluded from recall) and temporal edges for timeline queries.

0 commit comments

Comments
 (0)