CUGA LogoCUGA AGENT
Build

Knowledge Base

Self-contained document ingestion and retrieval for CUGA agents using Docling and local vector stores.

Architecture: Knowledge is the Knowledge Engine in the Capability layer — Docling ingest, embeddings (Persistence layer), and retrieval with citations. See How CUGA works.

CUGA includes a built-in knowledge base powered by LangChain and local vector stores. Docling is integrated for document ingestion: it parses and normalizes PDFs, Office files, HTML, Markdown, images, and other supported types before chunking and embedding, so the pipeline stays self-contained with no external document services.

When enabled, the agent can search, ingest, and manage documents — and it automatically becomes aware of what documents are available.

Enabling Knowledge

Knowledge is enabled by default via settings.toml (see Storage for the embedding provider). To opt out for a specific agent in the SDK:

from cuga import CugaAgent

agent = CugaAgent(tools=[...], enable_knowledge=False)

The SDK auto-injects knowledge tools and an awareness block into the agent prompt, so the agent knows what documents are available and how to search them.

Try the Demo

cuga start demo_knowledge

This is the same chat UI as cuga start demo, with the knowledge engine on — upload documents and query them.

Programmatic Access

from cuga import CugaAgent
import asyncio

agent = CugaAgent(enable_knowledge=True)

async def main():
    # Ingest a document
    await agent.knowledge.ingest("/path/to/quarterly_report.pdf")

    # The agent now automatically knows about this document
    result = await agent.invoke("What does the report say about Q4 revenue?")
    print(result.answer)

    # Direct search (skip the agent loop)
    results = await agent.knowledge.search("Q4 revenue figures")
    for r in results:
        print(f"{r['filename']} (page {r['page']}): {r['text'][:100]}")

    # List documents
    docs = await agent.knowledge.list_documents()

    # Clean up
    await agent.aclose()

asyncio.run(main())

Scopes

Documents can be agent-scoped (the default — permanent and shared across conversations) or session-scoped (tied to a single thread).

# Permanent, shared across conversations
await agent.knowledge.ingest("/path/to/file.pdf", scope="agent")

results = await agent.knowledge.search("query", scope="agent")
thread_id = "user-session-123"

# Temporary, per-conversation
await agent.knowledge.ingest(
    "/path/to/file.pdf",
    scope="session",
    thread_id=thread_id,
)

results = await agent.knowledge.search(
    "query",
    scope="session",
    thread_id=thread_id,
)

Supported Document Types

PDF, DOCX, XLSX, PPTX, HTML, Markdown, images, and more — anything Docling can parse.

Storage and Embeddings

The knowledge backend is selected by the global [storage].mode setting:

Datamode = "local"mode = "prod"
Knowledge vectors{knowledge.persist_dir}/knowledge_vectors.db (vec0 tables per collection)storage.postgres_url (pgvector)
Knowledge metadata{knowledge.persist_dir}/metadata.dbPostgres tables cuga_knowledge_meta_*. Uploaded files still live under persist_dir/files/.

Embeddings are configured under [storage.embedding] and default to a local BAAI/bge-small-en-v1.5 model (no OpenAI key required). See Storage for full options.

The knowledge persistence directory defaults to <cwd>/.cuga/knowledge/ and can be overridden in knowledge_settings.toml.

Citations and sources

Numbered citations in answers are on by default (citations_enabled in knowledge_settings.toml, also a toggle under Knowledge → Settings in the UI).

When the agent cites retrieved chunks, invoke() fills result.sources:

result = await agent.invoke("What does the handbook say about PTO?")
print(result.answer)   # may include [1], [2]
for s in result.sources:
    print(s["n"], s["filename"], s.get("page"), s.get("snippet"))

In the demo UI you can open a cited PDF at the cited page.

Quality profiles and OCR

Pick a RAG profile instead of hand-tuning every knob:

ProfileWhen to use
speedFast ingest and search
standardDefault balance
balancedA bit more quality
max_qualityBest extraction (slower; enables heavier Docling/OCR)
customYou set the knobs yourself
cuga start demo_knowledge --knowledge-profile max_quality

max_quality is what you want for scanned PDFs (OCR). The default fast Docling path is aimed at digital PDFs.

You can also override embeddings from the CLI (--embeddings-provider, --embeddings-model, --embeddings-base-url, …). Built-in embedding families: local fastembed (default), Hugging Face, OpenAI-compatible, Ollama, and OpenRouter.

Routing Knowledge Through CugaLite

The [advanced_features].force_lite_mode_apps list defaults to ["knowledge"], so knowledge queries always run through CugaLite's faster execution path regardless of lite_mode_tool_threshold. To change this, edit settings.toml:

[advanced_features]
force_lite_mode_apps = ["knowledge", "crm"]   # add more apps as needed

The agent's awareness block is rebuilt as documents are ingested or removed, so newly added documents are usable immediately on the next invocation.