Skip to content
Bifrost Docs

Knowledge Bases

Hybrid retrieval for grounded AI workflows and agents

Store and search documents for retrieval-augmented generation (RAG). Bifrost combines semantic similarity with PostgreSQL full-text matching so searches can recover both conceptually related passages and exact product terms.

The knowledge store uses hybrid retrieval:

  • Documents are chunked, embedded with pgvector, and indexed for full-text search
  • Search fuses semantic and lexical rankings into one relevance-ordered result set
  • Chunks from the same keyed document are deduplicated
  • Results can be used as context for AI completions
from bifrost import knowledge
# Store a single document
doc_id = await knowledge.store(
"Our refund policy allows returns within 30 days...",
namespace="policies"
)
# With metadata and key for upsert
await knowledge.store(
"Updated policy content...",
namespace="policies",
key="refund-policy", # Upserts if key exists
metadata={"version": "2.0", "effective_date": "2024-01-01"}
)

For multiple documents:

docs = [
{"content": "Document 1...", "key": "doc-1"},
{"content": "Document 2...", "key": "doc-2"},
{"content": "Document 3...", "metadata": {"type": "faq"}}
]
doc_ids = await knowledge.store_many(docs, namespace="support")
# Basic search
results = await knowledge.search(
"What is the refund policy?",
namespace="policies"
)
for doc in results:
print(f"Score: {doc.score}")
print(f"Content: {doc.content}")
results = await knowledge.search(
"refund policy",
namespace=["policies", "faq"], # Multiple namespaces
limit=10 # Default is 5
)

Organize documents by namespace:

Namespace Use Case
policies Company policies and procedures
faq Frequently asked questions
docs Product documentation
tickets Historical support tickets

List available namespaces:

namespaces = await knowledge.list_namespaces()
for ns in namespaces:
print(f"{ns.namespace}: {ns.scopes['total']} documents")

Documents can be global or organization-specific:

# Global scope (all orgs can search)
await knowledge.store(content, namespace="global-policies", scope=None)
# Org-specific (default - only that org sees it)
await knowledge.store(content, namespace="org-policies", org_id="org-123")

The ai.complete() function can include knowledge context:

from bifrost import ai
response = await ai.complete(
"What is our vacation policy?",
knowledge=["policies", "hr"]
)

Bifrost automatically:

  1. Searches the specified namespaces
  2. Retrieves and fuses semantic and full-text matches
  3. Includes them as context in the prompt
  4. Returns a grounded response

For agents, retrieval is bounded per turn: repeated queries do not fetch the same evidence again, results are deduplicated, and the evidence envelope is capped before it enters the model context. This prevents a retrieval loop from repeatedly inflating the prompt while preserving the best matching evidence.

# Delete by ID
await knowledge.delete(doc_id)
# Or delete by key (if you stored with a key)
# Re-store with empty content to effectively remove
from bifrost import workflow, ai, knowledge
@workflow
async def answer_question(question: str):
# Direct RAG approach
response = await ai.complete(
question,
knowledge=["faq", "docs"],
system="Answer based on the provided context. If unsure, say so."
)
return {"answer": response.content}
@workflow
async def index_faq(question: str, answer: str):
await knowledge.store(
f"Q: {question}\nA: {answer}",
namespace="faq",
key=f"faq-{hash(question)}"
)
return {"status": "indexed"}