Skip to main content

Knowledge Base Management

Upload and manage your brand's FAQ, product catalog, promotions, and policies. All KB entries are automatically embedded and indexed for RAG retrieval.

List Knowledge Base Entries

Retrieve all KB entries for your tenant.

GET /api/tenants/me/kb?type=FAQ&isActive=true&limit=20

Query Parameters

ParamTypeDefaultNotes
typeenumallFAQ, SKU, Promotion, Policy, Custom
isActivebooleanallFilter by active/inactive status
limitnumber20Page size (max 100)
afterstringCursor for pagination

Response

{
"data": [
{
"id": "kb_ulid",
"tenantId": "ulid",
"title": "How do I track my order?",
"type": "FAQ",
"content": "Go to Orders → click the order → view tracking number...",
"tags": ["orders", "tracking"],
"isActive": true,
"expiresAt": null,
"createdAt": "2026-03-01T00:00:00Z",
"updatedAt": "2026-03-12T00:00:00Z"
}
],
"pagination": {
"limit": 20,
"hasMore": false
}
}

Create Knowledge Base Entry

Add a new FAQ, product info, promotion, or policy.

POST /api/tenants/me/kb

Request

{
"title": "Polo Shirt YD-001",
"type": "SKU",
"content": "Color: White, Black, Navy. Material: 100% cotton. Size: XS-XXL. Price: 299,000đ",
"tags": ["clothing", "polos"],
"expiresAt": null
}

Field Descriptions

FieldTypeRequiredNotes
titlestringEntry title (indexed for search)
typeenumFAQ, SKU, Promotion, Policy, Custom
contentstringFull text content (max 4000 chars)
tagsstring[]Keywords for semantic search
expiresAtISO8601Promotion expiry date (optional)

Response

{
"id": "kb_ulid",
"title": "Polo Shirt YD-001",
"type": "SKU",
"content": "Color: White, Black, Navy...",
"tags": ["clothing", "polos"],
"isActive": true,
"expiresAt": null,
"embeddingStatus": "pending",
"createdAt": "2026-03-12T00:00:00Z"
}

Note: embeddingStatus: pending means the entry is being indexed. It will be available for RAG in ~2 seconds.


Update Knowledge Base Entry

Modify an existing KB entry.

PUT /api/tenants/me/kb/:entryId

Request

{
"title": "Polo Shirt YD-001 (Updated)",
"content": "Color: White, Black, Navy, Olive...",
"tags": ["clothing", "polos", "spring-collection"],
"expiresAt": null
}

Response

{
"id": "kb_ulid",
"title": "Polo Shirt YD-001 (Updated)",
"embeddingStatus": "pending",
"updatedAt": "2026-03-12T14:30:00Z"
}

Delete Knowledge Base Entry

Remove a KB entry from your knowledge base.

DELETE /api/tenants/me/kb/:entryId

Response

{
"success": true,
"message": "Entry deleted"
}

Get Entry Details

Retrieve a single KB entry with full content.

GET /api/tenants/me/kb/:entryId

Response

{
"id": "kb_ulid",
"title": "How do I track my order?",
"type": "FAQ",
"content": "Go to Orders → click the order → view tracking number. SMS notification sent to your phone number on file.",
"tags": ["orders", "tracking"],
"isActive": true,
"expiresAt": null,
"embeddingStatus": "completed",
"embedding": null,
"usageCount": 3,
"lastUsedAt": "2026-03-12T14:00:00Z",
"createdAt": "2026-03-01T00:00:00Z",
"updatedAt": "2026-03-12T00:00:00Z"
}

Promotions & Expiry

Promotion entries with expiresAt are automatically deactivated after the expiry date. They will not appear in RAG results.

{
"title": "Spring Sale: 30% Off",
"type": "Promotion",
"content": "30% discount on all polo shirts until March 31, 2026",
"tags": ["sale", "polos"],
"expiresAt": "2026-03-31T23:59:59Z"
}

Background job runs every 5 minutes to deactivate expired promotions.


RAG Retrieval

When a customer message arrives, Dolly searches your knowledge base:

  1. Embed customer message — All-MiniLM local embedding
  2. Vector search — pgvector similarity search returns top 3 hits (regardless of confidence score)
  3. Inject into prompt — All 3 KB entries added as context
  4. Gate 2 validates — Hallucination gate ensures AI doesn't use KB entries to invent unverified claims

Key Design: Always return top 3 hits (no minimum score cutoff). The hallucination gate is the guard against low-confidence results being misused. This design ensures the AI always has context to work with, even for edge-case queries.

Example:

Customer: "Áo polo có được giặt khô không?"
Vector search returns:
1. "Care instructions: Machine wash cold, hang dry" (high confidence)
2. "Returns policy includes care damage" (medium confidence)
3. "Customer review about fabric" (low confidence)

All 3 injected into prompt.
Haiku reads all 3, but Gate 2 validates that claims are only from the high/medium confidence entries.

Embedding Status

When you create or update a KB entry, Dolly automatically embeds the content:

  • pending — Waiting to be indexed
  • completed — Ready for RAG retrieval
  • failed — Embedding failed (e.g., invalid content)

Monitor embeddingStatus to know when entries are live.


Usage Stats

Each KB entry tracks how often it was retrieved during RAG:

  • usageCount — Times this entry was in top-3 RAG results
  • lastUsedAt — Last time it was injected into a response

Use this to identify your most helpful content.


Error Responses

ErrorHTTPCause
INVALID_REQUEST400Missing title, invalid type, content empty
NOT_FOUND404Entry does not exist
CONFLICT409Duplicate title in same type
INTERNAL_ERROR500Embedding failed — retry