Skip to content
GitHubDiscord

Knowledge Base

A knowledge base is the set of documents your agent is supposed to answer from, such as the published policies behind support_agent, the retail-bank support agent from Wrap your agent. The quality scan writes questions from those documents and checks the agent’s answers against them, which is how it catches answers the agent invented (hallucinations).

Knowledge base primitives for document-grounded scan generators. quality_scan and every knowledge-base generator build their scenarios from these documents and judge the agent’s answers against them.

from giskard.scan import Document, KnowledgeBase

Module: giskard.scan.utils.knowledge_base

Immutable collection of documents used by knowledge-base scenario generators. Embeddings are not computed at construction time: they are filled lazily, in one batch, the first time nearest-neighbor retrieval needs them. The document collection is frozen so documents cannot be added after embeddings exist.

KnowledgeBase
documents tuple[Document, ...] Required

The documents. Entries whose content is blank are dropped on validation; a knowledge base with no non-empty document raises ValueError.

embedding_model BaseEmbeddingModel | None Default: None

Embedding model used to embed the documents. Falls back to the global default when None.

.from_texts() KnowledgeBase

Class method. Create a knowledge base from raw text documents, one Document per text.

texts list[str] Required
Text chunks to wrap as documents.
.ensure_embeddings() None

Coroutine. Ensure every document has embeddings from the same model. If any document is missing them, all embeddings are recomputed in one batch so vectors from different embedding models are never mixed. Called automatically by the retrieval methods.

.closest_documents() list[Document]

Coroutine. Return the documents closest to a seed document by cosine similarity, sorted from highest to lowest.

seed_index int Required
Index of the seed document in documents. Out-of-range values raise IndexError.
max_documents int Required
Maximum number of documents to return, including the seed document itself. Values <= 0 return an empty list.
.closest_documents_to_text() list[Document]

Coroutine. Return the documents closest to arbitrary query text by cosine similarity.

text str Required
Query text to embed and compare against the knowledge base. Blank text raises ValueError.
max_documents int Required
Maximum number of documents to return. Values <= 0 return an empty list.

KnowledgeBase extends WithEmbeddingMixin, so the embedding model follows the framework’s embedding configuration.

from giskard.scan import KnowledgeBase
kb = KnowledgeBase.from_texts(
[
"A disputed card transaction must be reported within 120 days of the statement date.",
"A card reported lost cannot be unfrozen and must be replaced.",
"We do not give investment or tax advice; refer the customer to an independent adviser.",
]
)

One fact per document. The generators sample a document and write questions from it, so a page-long document produces vague questions and vague verdicts.

Or build it from documents directly when you want tags or precomputed vectors:

from giskard.scan import Document, KnowledgeBase
kb = KnowledgeBase(
documents=(
Document(
content="A disputed card transaction must be reported within 120 days of the statement date.",
tags=["disputes"],
),
Document(
content="A card reported lost cannot be unfrozen and must be replaced.",
tags=["cards"],
),
)
)
from agent import bank_agent as support_agent
from giskard.scan import quality_scan
result = await quality_scan(
support_agent,
description="A customer-support agent for a retail bank, answering from our published policies.",
languages=["en"],
knowledge_base=kb,
)

Pass a KnowledgeBase rather than a list[str] when you want tags on the documents or want to reuse one embedded knowledge base across several runs. The plain list is fine for a first pass.

quality_scan and generate_suite also accept a plain list[str] and convert it for you. A single str is rejected with TypeError. A bare string is a valid iterable of characters, and treating it as one document per character would be silently wrong.

The embedding matrix is validated once and reused across every retrieval call. It must be a 2D matrix, free of NaN/Inf values, with no zero vectors; any of these raise ValueError. Documents with incomplete embeddings raise ValueError too.


Module: giskard.scan.utils.knowledge_base

A single document stored in a knowledge base.

Document
content str Required

Text content used for question generation and grounding.

embeddings list[float] | None Default: None

Optional embedding vector. Missing vectors are computed lazily when nearest-neighbor retrieval is requested.

tags list[str] | None Default: None

Optional document labels carried by the caller.

from giskard.scan import Document
doc = Document(
content="A card reported lost cannot be unfrozen and must be replaced.",
tags=["policy", "cards"],
)