# `Nous.KnowledgeBase`
[🔗](https://github.com/nyo16/nous/blob/v0.17.1/lib/nous/knowledge_base.ex#L1)

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:

1. **Data model & store** — `Document`, `Entry`, `Link`, `HealthReport` structs
   with a pluggable `Store` behaviour (ETS, SQLite, etc.)
2. **Plugin & tools** — `Nous.Plugins.KnowledgeBase` integrates with any agent,
   providing 9 tools (search, read, ingest, add_entry, link, backlinks, list,
   health_check, generate)
3. **Workflows** — Pre-built DAG pipelines for ingest, incremental update,
   health check, and output generation
4. **Agent behaviour** — `Nous.Agents.KnowledgeBaseAgent` for specialized
   KB curation and reasoning

# `kb_config`

```elixir
@type kb_config() :: map()
```

Knowledge base configuration.

Recognised keys:

  * `:store` — the `Nous.KnowledgeBase.Store` implementation module
  * `:store_state` — the opaque state returned by that store's `init/1`
  * `:kb_id` — namespace for entries and documents within the store

Store implementations may read additional keys.

# `output_type`

```elixir
@type output_type() :: :report | :summary | :slides
```

The kind of artifact `generate/2` should produce.

# `raw_document`

```elixir
@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.

# `store_state`

```elixir
@type store_state() :: term()
```

Opaque per-store state, as returned by the store's `init/1`.

# `workflow_result`

```elixir
@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`.

# `backlinks`

```elixir
@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.

# `generate`

```elixir
@spec generate(
  output_type(),
  keyword()
) :: workflow_result()
```

Generate structured output from the knowledge base.

## Parameters

  * `output_type` - `:report`, `:summary`, or `:slides`
  * `opts` - Must include `:kb_config` and `:topic`

# `get_entry`

```elixir
@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.

# `health_check`

```elixir
@spec health_check(keyword()) :: workflow_result()
```

Run a health check audit on the knowledge base.

# `incremental_update`

```elixir
@spec incremental_update(
  [raw_document()],
  keyword()
) :: workflow_result()
```

Incrementally update the knowledge base with new or changed documents.

# `ingest`

```elixir
@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

# `list_documents`

```elixir
@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.

# `list_entries`

```elixir
@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.

# `related_entries`

```elixir
@spec related_entries(module(), store_state(), String.t(), keyword()) ::
  {:ok, [Nous.KnowledgeBase.Entry.t()]}
```

Get related entries (connected by any link direction).

## Options

  * `:limit` - Maximum number of entries returned (store default: 10).

# `search`

```elixir
@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).

---

*Consult [api-reference.md](api-reference.md) for complete listing*
