Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ handoff all come from `openai-agents`.
| Module | Role |
|--------|------|
| `quantmind/knowledge/` | Pydantic data standard (`FlattenKnowledge` / `TreeKnowledge` / `GraphKnowledge`) — dependency leaf |
| `quantmind/library/` | Local persistence and semantic retrieval for canonical knowledge — depends only on `knowledge` |
| `quantmind/configs/` | Operation cfg + typed input models or unions (`BaseFlowCfg`, `NewsWindow`, `PaperInput`) — depends only on `knowledge` |
| `quantmind/preprocess/` | Deterministic fetch / format / clean / time utilities — depends only on `utils` |
| `quantmind/flows/` | Apex layer: public library operations (`paper_flow`, `collect_news`, `batch_run`) |
Expand Down
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ handoff all come from `openai-agents`.
| Module | Role |
|--------|------|
| `quantmind/knowledge/` | Pydantic data standard (`FlattenKnowledge` / `TreeKnowledge` / `GraphKnowledge`) — dependency leaf |
| `quantmind/library/` | Local persistence and semantic retrieval for canonical knowledge — depends only on `knowledge` |
| `quantmind/configs/` | Operation cfg + typed input models or unions (`BaseFlowCfg`, `NewsWindow`, `PaperInput`) — depends only on `knowledge` |
| `quantmind/preprocess/` | Deterministic fetch / format / clean / time utilities — depends only on `utils` |
| `quantmind/flows/` | Apex layer: public library operations (`paper_flow`, `collect_news`, `batch_run`) |
Expand Down
1 change: 1 addition & 0 deletions contexts/usage/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ current public API, focused examples, and component-specific guidance.
| Installation and common usage | [Root README usage](../../README.md#-usage-examples) |
| Paper extraction | [Paper guide](../../docs/papers.md) |
| News collection | [News design and behavior](../../docs/design/en/news.md) |
| Local semantic search | [Library guide](../../docs/library.md) and [focused example](../../examples/library/README.md) |
| Runnable operation examples | [`examples/flows/`](../../examples/flows/) |
| Focused preprocessing examples | [`examples/preprocess/`](../../examples/preprocess/) |

Expand Down
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ harness.
| Paper extraction | `quantmind.flows.paper_flow` | `PaperInput`, `PaperFlowCfg` | `Paper` | [README usage](../README.md#-usage-examples) | [Papers](papers.md) |
| News collection | `quantmind.flows.collect_news` | `NewsWindow`, `NewsCollectionCfg` | `NewsBatch` from `quantmind.preprocess` | [Collect news](../examples/flows/collect_news.py) | [News collection design](design/en/news.md) |
| Bounded fan-out | `quantmind.flows.batch_run` | Operation inputs and shared config | `BatchResult` | [README usage](../README.md#-usage-examples) | API docstrings |
| Local semantic search | `quantmind.library.LocalKnowledgeLibrary` | `BaseKnowledge`, `SemanticQuery` | `list[SemanticHit]` | [Library example](../examples/library/README.md) | [Library guide](library.md) |

Import public inputs and configs from `quantmind.configs` and current public
operations from `quantmind.flows`. Import result contracts from the canonical
Expand Down
128 changes: 128 additions & 0 deletions docs/library.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Local Semantic Knowledge Library

`quantmind.library` persists canonical `BaseKnowledge` in SQLite and ranks
rebuildable NumPy indexes with exact cosine similarity. It is a financial
knowledge API, not a generic RAG framework: provider and storage details remain
private, and search returns typed QuantMind evidence without generating an
answer.

## Retrieval grain

- Each `FlattenKnowledge` item produces one target from its exact
`embedding_text()` projection.
- Each `TreeKnowledge` produces one item target for the root with
`node_id=None`, plus one target for every non-root `TreeNode`.
- Canonical typed records are the source of truth. Embeddings and filter
columns are derived data and can be replaced by re-putting the item.

## Local storage model

The default local database is SQLite, with separate canonical and derived
concerns:

- `knowledge_items` stores one aggregate root per `BaseKnowledge`. The type
discriminator and schema version select the concrete Pydantic model.
- `knowledge_nodes` stores every canonical `TreeNode` separately with its item,
parent, position, payload, and content hash. A large tree is not hidden in the
aggregate-root JSON row.
- `semantic_records` stores rebuildable item/root/node projections and vectors.

Concrete types do not get tables such as `news`, `earnings`, or `papers`.
Creating one table per Pydantic subtype would duplicate common metadata and
require a database migration whenever the knowledge standard adds a type. The
aggregate-root plus normalized-node model preserves typed validation while
giving future tree navigation a stable node-level storage boundary.

SQLite is the default because canonical knowledge needs transactions, foreign
keys, typed reconstruction, and explicit corrupt/stale/not-found behavior. A
vector database such as Chroma optimizes the derived similarity-search layer;
it does not replace those canonical-storage responsibilities. The current local
scale therefore uses a rebuildable NumPy exact-cosine index backed by
`semantic_records`, without adding another service or dependency. If corpus
size later requires an approximate or remote vector index, that derived layer
can change privately without changing `LocalKnowledgeLibrary`, the canonical
tables, or user code.

The durable vector metadata records the embedding model and dimension, exact
projection hash, source content hash, knowledge schema version, and projection
schema version. Re-putting an unchanged item ID reuses its vectors. A changed
node projection replaces only that node vector; model, dimension, source hash,
or schema changes replace the affected item's vectors.

## Financial-time filters

`as_of` is the information cutoff represented by the knowledge. `available_at`
is when its source became observable. They intentionally remain separate:

- `as_of_before` includes records whose information cutoff is at or before the
query cutoff.
- `available_at_before` includes only records with a known availability time at
or before the query cutoff. Unknown availability is excluded.

Consequently, `as_of_before` alone does not prevent look-ahead. Ingestion flows
should populate `available_at` from publication time. When publication time is
unknown, the caller can copy `SourceRef.fetched_at` to `available_at` as a
conservative upper bound.

`item_types` and `source_kinds` use any-of matching. Every requested tag must be
present. `confidence`, `tree_id`, and both time cutoffs combine with those
filters before ranking.

## Usage

The bundled AI-infrastructure scenario contains primary-source-backed `News`,
`Earnings`, and a real research `Paper` tree. Its canonical source JSON is
precompiled into a SQLite database with six `text-embedding-3-small` targets,
so the user-facing example does not perform ingestion or document embedding.
Put `OPENAI_API_KEY` in `.env` and run:

```bash
python examples/library/semantic_search.py
```

The example:

1. Opens the ready-to-search SQLite bundle through `LocalKnowledgeLibrary`.
2. Embeds only the user's query with `text-embedding-3-small`.
3. Searches a concrete AI-infrastructure question with a no-look-ahead
availability cutoff.
4. Resolves every hit with `get()` and prints source, citation, financial time,
and the root-to-node path and content for tree evidence.

Maintainers can regenerate the model-specific database from the auditable JSON
after changing the source data or storage schema:

```bash
python scripts/examples/build_ai_infrastructure_bundle.py
```

The bundle's facts and short citations come directly from the
[Compute Trends Across Three Eras of Machine Learning paper](https://arxiv.org/abs/2202.05924),
[Microsoft's FY2025 AI-datacenter investment announcement](https://blogs.microsoft.com/on-the-issues/2025/01/03/the-golden-opportunity-for-american-ai/),
and [NVIDIA's FY2026 Q1 results](https://investor.nvidia.com/news/press-release-details/2025/NVIDIA-Announces-Financial-Results-for-First-Quarter-Fiscal-2026/default.aspx).

Representative output has this shape; scores depend on the selected embedding
model:

```text
Bundle: .../examples/library/data/ai_infrastructure.db
Query: What evidence shows demand for AI infrastructure is expanding?

1. score=0.812 type=paper
path: ... > ...
matched: ...
source: https://...
citation: ...
```

`SemanticHit.matched_text` is the exact projection used in ranking. Use
`get(item_id)` to resolve the full canonical item and, for node hits, the node
identified by `node_id`.

Missing IDs raise `KeyError`. Stored canonical payloads that no longer validate
and orphaned or mismatched derived records raise `RuntimeError` with stale-data
context. Invalid vector bytes and inconsistent stored dimensions raise a clear
corrupt-index `RuntimeError`; provider or query dimension mismatches raise
`ValueError`. `delete()` does not deserialize canonical JSON, so a stale
canonical payload can still be removed together with all derived targets in one
transaction.
39 changes: 39 additions & 0 deletions examples/library/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Local Knowledge Library Example

This example searches an auditable AI-infrastructure knowledge bundle containing
`News`, `Earnings`, and a research `Paper` tree.

## Run

Put `OPENAI_API_KEY` in the repository `.env`, then run from the repository root:

```bash
python examples/library/semantic_search.py
```

The bundled SQLite database already contains six 1536-dimensional
`text-embedding-3-small` document targets. Running the example embeds only the
query, then uses `LocalKnowledgeLibrary.open()`, `search()`, and `get()` to show
ranked evidence and tree paths.

## Files

- `semantic_search.py` is the user-facing query example.
- `data/ai_infrastructure.json` is the canonical, reviewable source bundle.
- `data/ai_infrastructure.db` is the generated SQLite library with canonical
records and model-specific embeddings. Do not edit it directly.

## Rebuild the bundle

Regenerate the database after changing the source JSON, library schema,
retrieval-target rules, embedding model, or dimension:

```bash
python scripts/examples/build_ai_infrastructure_bundle.py
```

The build validates every source item as canonical QuantMind knowledge and
removes an incomplete database if embedding generation fails.

See [the library guide](../../docs/library.md) for storage, retrieval-grain, and
financial-time semantics.
Binary file added examples/library/data/ai_infrastructure.db
Binary file not shown.
Loading
Loading