Custom knowledge base
Answer from your own knowledge: a search API, a vector database, a product catalogue, a document store. You write one function, search, that returns the passages for a question; HelpPuff numbers them, gives them to the model as quoted context, cites the ones it uses, and says "not sure" when none answer. What you search, and how, is up to you.
The other options need no code: HelpPuff's own knowledge base (the default), Cloudflare AI Search, an OpenAI vector store, your own search over HTTP, or none. See Providers.
Over HTTP (no code)
helppuff rag set http --url https://search.example.com/query --token-env SEARCH_TOKENHelpPuff sends POST url with { "query", "question", "siteId", "limit" } (and Authorization: Bearer <token>), and expects:
{ "passages": [{ "title": "Prices", "content": "Our callout fee is $99…", "url": "https://acme.com/prices", "score": 0.9 }] }In TypeScript
helppuff scaffold rag --use # writes ./rag.ts and points helppuff.json at it"knowledge": { "retrieval": { "type": "custom", "module": "./rag.ts", "secrets": ["MY_SEARCH_KEY"] } }import type { Retriever } from '@knowtific/helppuff/sdk';
export default {
id: 'my-knowledge',
async search(request, ctx) {
const response = await ctx.fetch('https://search.example.com/query', {
method: 'POST',
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${String(ctx.env['MY_SEARCH_KEY'])}` },
body: JSON.stringify({ query: request.query, limit: request.limit }),
});
if (!response.ok) throw new Error(`search ${response.status}`);
const { results } = await response.json();
return results.map((r) => ({ title: r.title, content: r.text, url: r.url, score: r.score }));
},
} satisfies Retriever;What you get (request): query (the question, made to stand alone when it was a follow-up), question (the visitor's own words), limit (how many passages the answer can use).
What you return, best first, each:
| Field | What |
|---|---|
title | Shown to the model, and as the source link's text |
content | The text (up to 4,000 characters are used) |
url | Optional: linked as a source when the answer cites it (http/https only) |
heading | Optional: where in the page, e.g. "Pricing › Hot water" |
score | Optional: higher is better |
The passages are quoted to the model as content, not instructions: text in them cannot change the assistant's rules. A search that throws, or times out, is logged and the assistant answers without passages (it says it is not sure and offers a callback), so a slow search never fails the chat.
What you can use (ctx): ctx.fetch, ctx.env (your secrets and the Worker's bindings), ctx.log, ctx.siteId.
Secrets, deploy, test
helppuff secret set MY_SEARCH_KEY
helppuff deploy
helppuff rag test "price of a blocked drain" # the passages the deployed Worker findsThe file is bundled into the Worker at deploy, like a custom model. HelpPuff's crawl keeps reading your website for the dashboard (business details, suggestions, jobs) whatever the knowledge base; to have your search include it, index the site in your own store.