LLM-compiled personal knowledge base system.
Inspired by Karpathy's vision: raw documents get ingested, an LLM compiles them into a markdown wiki with summaries, backlinks, and cross-references. You can Q&A over it, generate outputs, and run health checks.
Quick Start — Plugin Mode
Add the KB plugin to any agent for interactive use:
agent = Nous.Agent.new("openai:gpt-4",
plugins: [Nous.Plugins.KnowledgeBase],
deps: %{
kb_config: %{
store: Nous.KnowledgeBase.Store.ETS,
kb_id: "my_kb"
}
}
)
{:ok, result} = Nous.Agent.run(agent, "Ingest this article: ...")
{:ok, result} = Nous.Agent.run(agent, "What do we know about GenServers?")Quick Start — Workflow Mode
For batch operations, use the workflow API:
# Batch ingest
{:ok, state} = Nous.KnowledgeBase.ingest(
[%{title: "Article 1", content: "..."}],
kb_config: config
)
# Health check
{:ok, state} = Nous.KnowledgeBase.health_check(kb_config: config)Quick Start — Agent Behaviour Mode
For a KB-specialized agent:
agent = Nous.Agent.new("openai:gpt-4",
behaviour_module: Nous.Agents.KnowledgeBaseAgent,
plugins: [Nous.Plugins.KnowledgeBase],
deps: %{kb_config: %{store: Nous.KnowledgeBase.Store.ETS, kb_id: "my_kb"}}
)Architecture
The KB system has four composable layers:
- Data model & store —
Document,Entry,Link,HealthReportstructs with a pluggableStorebehaviour (ETS, SQLite, etc.) - Plugin & tools —
Nous.Plugins.KnowledgeBaseintegrates with any agent, providing 9 tools (search, read, ingest, add_entry, link, backlinks, list, health_check, generate) - Workflows — Pre-built DAG pipelines for ingest, incremental update, health check, and output generation
- Agent behaviour —
Nous.Agents.KnowledgeBaseAgentfor specialized KB curation and reasoning
Summary
Types
Knowledge base configuration.
The kind of artifact generate/2 should produce.
A raw, uncompiled document handed to ingest/2 or incremental_update/2.
Opaque per-store state, as returned by the store's init/1.
Result of a workflow-backed operation.
Functions
Get backlinks for an entry.
Generate structured output from the knowledge base.
Get a specific entry by slug or ID.
Run a health check audit on the knowledge base.
Incrementally update the knowledge base with new or changed documents.
Ingest documents through the full compilation pipeline.
List all documents, optionally filtered.
List all entries, optionally filtered.
Get related entries (connected by any link direction).
Search knowledge base entries directly.
Types
@type kb_config() :: map()
Knowledge base configuration.
Recognised keys:
:store— theNous.KnowledgeBase.Storeimplementation module:store_state— the opaque state returned by that store'sinit/1:kb_id— namespace for entries and documents within the store
Store implementations may read additional keys.
@type output_type() :: :report | :summary | :slides
The kind of artifact generate/2 should produce.
@type raw_document() :: map()
A raw, uncompiled document handed to ingest/2 or incremental_update/2.
Keys may be atoms or strings; title and content are read, and
doc_type/source/metadata are used when present. Documents are
normalised into Nous.KnowledgeBase.Document structs by the pipeline.
@type store_state() :: term()
Opaque per-store state, as returned by the store's init/1.
@type workflow_result() :: {:ok, Nous.Workflow.State.t()} | {:error, term()}
Result of a workflow-backed operation.
The final Nous.Workflow.State carries every node's output under
state.data, including the updated :store_state.
Functions
@spec backlinks(module(), store_state(), String.t()) :: {:ok, [Nous.KnowledgeBase.Link.t()]}
Get backlinks for an entry.
Returns the links whose to_entry_id is entry_id — that is, every entry
that points at this one.
@spec generate( output_type(), keyword() ) :: workflow_result()
Generate structured output from the knowledge base.
Parameters
output_type-:report,:summary, or:slidesopts- Must include:kb_configand:topic
@spec get_entry(module(), store_state(), String.t()) :: {:ok, Nous.KnowledgeBase.Entry.t()} | {:error, :not_found}
Get a specific entry by slug or ID.
The slug is tried first; if no entry carries that slug the value is looked up as an entry ID.
@spec health_check(keyword()) :: workflow_result()
Run a health check audit on the knowledge base.
@spec incremental_update( [raw_document()], keyword() ) :: workflow_result()
Incrementally update the knowledge base with new or changed documents.
@spec ingest( [raw_document()], keyword() ) :: workflow_result()
Ingest documents through the full compilation pipeline.
Options
:kb_config- Required. Knowledge base configuration map.:compiler_model- Model for compilation (default: "openai:gpt-4o-mini"):embedding- Embedding provider module:embedding_opts- Embedding options
@spec list_documents(module(), store_state(), keyword()) :: {:ok, [Nous.KnowledgeBase.Document.t()]}
List all documents, optionally filtered.
Options
:kb_id- Restrict to one knowledge base namespace.:limit- Maximum number of documents returned.
@spec list_entries(module(), store_state(), keyword()) :: {:ok, [Nous.KnowledgeBase.Entry.t()]}
List all entries, optionally filtered.
Options
:kb_id- Restrict to one knowledge base namespace.:entry_type- Keep only entries of this type.:tags/:concepts- Keep entries matching any of the given values.:limit- Maximum number of entries returned.
@spec search(module(), store_state(), String.t(), keyword()) :: {:ok, [{Nous.KnowledgeBase.Entry.t(), float()}]}
Search knowledge base entries directly.
Returns entries paired with a relevance score in 0.0..1.0, best first.
Options
:kb_id- Restrict the search to one knowledge base namespace.:limit- Maximum number of results (store default: 10).:min_score- Drop results scoring at or below this value (default: 0.0).