For the complete documentation index, see llms.txt. This page is also available as Markdown.

Knowledge base & retrieval

Retrieval grounding for the agent: the built-in pgvector knowledge base or an external HTTP search endpoint you own. Exactly one, selected by type.

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.

YAML examples follow manifest schema 6.1.5. Manifest and content shapes are schema-versioned and differ across runtime versions — see Versioning & compatibility.

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

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.

Request your endpoint receives

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:

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.

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

See also

Last updated

Was this helpful?