> For the complete documentation index, see [llms.txt](https://docs.interactive.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.interactive.ai/agents/concepts/knowledge-base.md).

# Knowledge base & retrieval

> **Context** — Retrieval grounds the agent's answers in your documents (help-centre articles, product docs, policies-the-business-kind). It is optional: omit the `search` block entirely and the agent runs without retrieval. Setup walkthrough: [Setting up the knowledge base](/agents/guides/knowledge-base-setup.md).
>
> YAML examples follow **manifest schema 6.1.1**. Manifest and content shapes are schema-versioned and differ across runtime versions — see [Versioning & compatibility](/agents/operations/versioning.md).

## One slot, two implementations

`agent_config.search` is a single slot selected by a `type` tag — you get exactly one of:

| `type`     | What it is                                                                                                                                                                                                                                     | Choose when                                                                                    |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| `pgvector` | The built-in retriever: the agent queries a Postgres + pgvector collection directly (rewrite → embed → cosine search). The store can be **a database you deploy in the platform or a remote Postgres** — the manifest just points at its host. | You have (or can index into) a pgvector table and want zero extra services.                    |
| `external` | An HTTP endpoint **you own** receives the recent conversation and returns text snippets — the integration path for an existing search system, reached as a plain **HTTP call**. You own rewriting, embedding, and search.                      | You already run a search/RAG service, need custom ranking, or your corpus lives behind an API. |

Either way the knowledge base is yours: a pgvector database hosted in the platform or anywhere you run Postgres, or an external HTTP search service you integrate. The agent only needs to reach the host/endpoint the manifest declares.

## `type: pgvector`: the built-in knowledge base

```yaml
agent_config:
  search:
    type: pgvector
    hostname: kb-postgres.internal.example.com
    port: 5432
    user: postgres
    password: ${KB_PG_PASSWORD}
    dbname: postgres
    sslmode: require
    collection: support_articles
    content_key: content
    metadata_filter:
      kb_location: article
    embedding_model: openai/text-embedding-3-small
    embedding_dimensions: 1536
    top_k: 5
    prompt:
      id: kb-rewrite-instructions
      version: 3
```

### How a retrieval runs

1. **Rewrite** — a model call (on the chat-lane primary, `llms.default`) condenses the recent conversation into one search query. The optional `prompt` reference appends your domain instructions to the built-in rewrite prompt ("expand product abbreviations", "always include the product line").
2. **Embed** — the query is embedded with `embedding_model`, routed through the LLM router using the same `llms.api_key` as chat.
3. **Search** — cosine similarity against the `collection` table, with `metadata_filter` applied as a containment match on the row's JSONB metadata; the top `top_k` rows return.
4. **Ground** — each row's document body (read from the metadata key named by `content_key`) is appended to the agent's context for the turn.

### Fields

| Field                  | Type             | Required | Default    | Meaning                                                                                                                                       |
| ---------------------- | ---------------- | -------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `hostname`             | string           | yes      | —          | Postgres host. Bare host — no scheme, path, or port.                                                                                          |
| `port`                 | integer 1–65535  | yes      | —          | Postgres port.                                                                                                                                |
| `user`                 | string           | no       | `postgres` | Role to connect as.                                                                                                                           |
| `password`             | `${VAR}` env-ref | yes      | —          | Postgres password.                                                                                                                            |
| `dbname`               | string           | no       | `postgres` | Database name.                                                                                                                                |
| `sslmode`              | enum             | no       | `require`  | `disable` \| `allow` \| `prefer` \| `require` \| `verify-ca` \| `verify-full`.                                                                |
| `collection`           | string           | yes      | —          | Table holding the vectors. Bare (`support_articles`) or schema-qualified (`vecs.support_articles`); each part must be a valid SQL identifier. |
| `content_key`          | string           | no       | `content`  | JSONB metadata key holding the document body. Set to `text` if your indexing pipeline writes it there.                                        |
| `metadata_filter`      | object           | no       | `{}`       | Fixed filter applied to every search (JSONB containment). Use when one collection mixes document kinds.                                       |
| `embedding_model`      | string           | yes      | —          | `provider/model` form. Must match the model used to index the collection.                                                                     |
| `embedding_dimensions` | integer ≥ 1      | yes      | —          | Must equal the collection's vector column dimension — validated at boot, mismatch fails fast.                                                 |
| `top_k`                | integer ≥ 1      | no       | `5`        | Rows returned per retrieval.                                                                                                                  |
| `prompt`               | versioned ref    | no       | —          | Extra instructions for the rewrite call.                                                                                                      |

### Contract with your indexing pipeline

The agent only *reads* the collection. Your pipeline must write rows whose vector column matches `embedding_dimensions`, produced by the **same embedding model** the manifest declares, with the document body stored under `content_key` in the row's JSONB metadata. Index-side chunking strategy is yours; the agent retrieves whatever granularity you stored.

## `type: external`: bring your own search

```yaml
agent_config:
  search:
    type: external
    hostname: https://search.internal.example.com
    port: 443
    path: /agent-search
    api_key: ${SEARCH_API_KEY}
    top_k: 5
    max_messages: 20
    timeout_seconds: 5.0
```

### Request your endpoint receives

```json
{
  "session_id": "sess_abc123",
  "agent_id": "agt_xyz789",
  "top_k": 5,
  "messages": [
    {"role": "customer", "content": "What's your cancellation policy?"},
    {"role": "agent", "content": "Free cancellation up to 24 hours before pickup."},
    {"role": "customer", "content": "And for one-way rentals?"}
  ]
}
```

`messages` is the last `max_messages` turns, most-recent **last**, with `role` normalised to `customer` | `agent` | `tool`. When `api_key` is set the request carries `Authorization: Bearer <resolved key>`.

### Response your endpoint must return

A bare JSON array of strings — each one a snippet to ground on:

```json
[
  "One-way rentals can be cancelled free of charge up to 24 hours before pickup; the 50 EUR one-way fee is fully refunded.",
  "Cancellations within 24 hours of pickup forfeit one day's rental rate."
]
```

Snippets are joined with `\n\n---\n\n` and appended to the agent's context as-is. Empty/whitespace-only strings are dropped. Any other shape (object envelope, non-string items, non-list root) is treated as a failure.

### Fields

| Field             | Type             | Required | Default | Meaning                                                            |
| ----------------- | ---------------- | -------- | ------- | ------------------------------------------------------------------ |
| `hostname`        | string           | yes      | —       | Endpoint host. Scheme optional (defaults `http://`). Host only.    |
| `port`            | integer 1–65535  | yes      | —       | TCP port.                                                          |
| `path`            | string           | yes      | —       | POST path, must start with `/`.                                    |
| `api_key`         | `${VAR}` env-ref | no       | —       | Sent as `Authorization: Bearer`.                                   |
| `top_k`           | integer ≥ 1      | no       | `5`     | Forwarded in the envelope; your endpoint is expected to honour it. |
| `max_messages`    | integer ≥ 1      | no       | `20`    | History cap per request.                                           |
| `timeout_seconds` | float > 0        | no       | `5.0`   | HTTP timeout.                                                      |

## Failure semantics: retrieval soft-fails

For both implementations, **retrieval failure never fails the turn**. Timeouts, connection errors, non-200 responses, malformed results — all log a warning and the turn proceeds with no retrieved context. The agent answers from the system prompt, policies, and history alone. Watch for retrieval warnings in logs if answers suddenly lose grounding — see [Troubleshooting](/agents/operations/troubleshooting.md).

Internal query timeout for pgvector searches is 30 seconds; the external endpoint's budget is its `timeout_seconds`.

## See also

* [Setting up the knowledge base](/agents/guides/knowledge-base-setup.md) — provisioning walkthrough
* [Models](/agents/concepts/models.md) — where the rewrite and embedding calls fit
* [Conversation lifecycle](/agents/concepts/conversation-lifecycle.md) — when retrieval happens in a turn


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.interactive.ai/agents/concepts/knowledge-base.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
