Weekday support is open from 09:00 to 17:00 in the account's local time zone. Mail sent on Saturday or Sunday waits until Monday. There is no phone line and no weekend chat.
Home · AI in Practice · Support-docs answer bot
AI in Practice · Free example
Support-docs answer bot
One retrieval-augmented pass over a handful of support paragraphs. The page retrieves chunks, ranks them three ways, builds the prompt, and fills a cited answer from a template.
Free example Sample docs Answer is simulated
Northline Desk is not a real product. The paragraphs were written for this page and labelled sample docs. Nothing here calls a model. There is no API key. A real bot would send the assembled prompt to a provider. This one stops at the prompt and quotes a sentence the template already selected, or it says it does not know.
The steps link the live cards they use. Chunking, Document parsing, Embeddings for retrieval, Vector databases, RAG, Query rewriting, Hybrid search, Reranking, Long context vs RAG, Citation & grounding check, Freshness & access control, Prompting, Context Window, Context engineering, Structured Outputs, Hallucination, Prompt Caching, Model Selection & Routing, Cost forecasting, Latency, Fallbacks & rate limits, Evaluation basics, Production evaluation, Monitoring & drift, Prompt injection, Privacy & data handling, and Safety. Names on the map that still say coming soon are not links.
- Chunk and embed
- Hybrid search and rerank
- Prompt, context, and citations
- Say you don't know
- Cache the prefix, route the call
- Check five questions
- Treat the docs as untrusted
1 Chunk and embed
Cards: Document parsing, Chunking, Embeddings for retrieval, Vector databases.
Split each support doc into a chunk you can store, then embed the chunk and the question. Document parsing is the step before that split when the source is a PDF or a scan. These sample docs are already text. Vector databases is where a production index would keep the embeddings. This page does not. OpenAI's retrieval guide treats chunking as part of preparing files for search. Gemini's File Search guide says the tool chunks and indexes files, and that retrieved document tokens are later charged as ordinary context tokens. This demo uses one short paragraph per sample file, so you can read the chunk the ranker saw.
A production index calls an embeddings API. The vector in the demo is a 24-number hash of the words, so the page can show a vector rank without that call. It will not match a vendor embedding.
Cost
You pay to embed the corpus when you index it, and you pay again to embed each query. Query embeddings are usually the small line. Re-embedding after every doc edit is the line that grows. Dollar figures below are vendor list price as of 2026-10-18. Token counts are assumptions for the arithmetic, not a tokenizer count and not the length of the sample paragraphs.
Quality
If the sentence that holds the fact is split across two chunks, retrieval can return neither. One fact per chunk is the boring version, and it is the one this demo uses.
Risk
An embedding does not know who may read the file. A nearest chunk can still be a secret, a stale policy, or the pasted ticket in this set.
Per query, assumed 15 tokens
Standard prices, per 1,000,000 tokens, from the embedding tables. OpenAI API pricing: text-embedding-3-small $0.02, text-embedding-3-large $0.13. Gemini API pricing: gemini-embedding-2 text input $0.20 on the paid tier. Vendor list price as of 2026-10-18. Other columns on those pages are different. This arithmetic does not use them.
- text-embedding-3-small15 × $0.02 ÷ 1,000,000 = $0.00000030
- text-embedding-3-large15 × $0.13 ÷ 1,000,000 = $0.00000195
- gemini-embedding-2 text15 × $0.20 ÷ 1,000,000 = $0.00000300
Under that 15-token assumption, one query embedding is $0.00000030 to $0.00000300 across these three list prices. The spread is the price list, not a measured bill.
Index once, assumed 640 tokens
Assumption: 8 chunks × 80 tokens. Not the sample paragraphs, which are shorter.
- text-embedding-3-small640 × $0.02 ÷ 1,000,000 = $0.00001280
- text-embedding-3-large640 × $0.13 ÷ 1,000,000 = $0.00008320
- gemini-embedding-2 text640 × $0.20 ÷ 1,000,000 = $0.00012800
- Gemini File Search embeddings640 × $0.15 ÷ 1,000,000 = $0.00009600
The File Search line is the embeddings rate on the Gemini pricing page for that tool, $0.15 per 1,000,000 tokens. The same page says retrieved document tokens are then charged as regular tokens for the model you call. That second charge is step 3, not this one.
2 Hybrid search and rerank
Cards: Query rewriting, RAG, Hybrid search, Reranking.
Rank chunks by words and by a vector, fuse the two lists, then rerank a short candidate set. Query rewriting is the step this box skips: a follow-up such as "what about weekends?" is searched as typed. Write it as a question that names support hours before you trust the ranks. Word match catches SCIM, SAML, and CSV. A vector can still move when the wording drifts. Hybrid on this page scales each list from 0 to 1 and adds them, so a chunk does not need to win both. Cohere's rerank guide says a rerank model sorts texts by relevance to a query and is often used on results an existing search already returned. The demo's second pass is local math over the top five hybrid hits. It is not that API.
Cost
Keyword search over an index you already hold has no model bill. The vector half is the query embedding from step 1. A rerank is an extra request over the candidates you send. Cohere's pricing page defines a search unit as one query with up to 100 documents, and says a document over 500 tokens is split so each piece counts. The dollar rate for that unit was not on the tables returned from that page, so this step does not state one. Vendor list price as of 2026-10-18 applies only where a number is shown.
Quality
Look at the three lists before you trust the fused one. On “Is SCIM available?” the word list and the toy vector do not pick the same first chunk. The fused list and the rerank do. If you only read the vector column, you ship the wrong excerpt.
Risk
Rerank still only knows the text you handed it. A hostile paragraph with the right words can place first. Step 7 is what you do with that paragraph after it places.
A hosted search call, if you buy one instead
OpenAI's pricing page lists File search storage at $0.10 per GB per day after 1 GB free, and a File search tool call at $2.50 per 1,000 calls. That is $0.0025 per call. The note on that page says the tool-call price applies to the Responses API. It is not the cost of the ranks in this demo. Vendor list price as of 2026-10-18.
3 Prompt, context, and citations
Cards: Long context vs RAG, Prompting, Context Window, Context engineering, Structured Outputs, Citation & grounding check.
Put a stable instruction first, then the excerpts and the question, and ask for JSON with a citation. Long context vs RAG is why this prompt pastes three chunks instead of all eight sample docs. Citation & grounding check is the open-the-chunk step after the citations field comes back. Context engineering is the choice of what goes into the window for this step. Here that choice is the instruction, the top three reranked chunks, and the question. The window for one request is the prefix, the excerpts, and the answer. This demo pastes the top three reranked chunks and no others. OpenAI, Anthropic, and Gemini each document a mode that asks the model for a schema. The schema on this page is three fields: known, answer, and citations. Code can read a field. Code still has to check that each citation id was actually retrieved.
Cost
Every excerpt you paste is input. Output is the JSON, and a schema does not make output free. The lines below price one answer call. They are not the demo, which does not call a model. Assumptions, not a tokenizer count: 200 cached input tokens of stable instruction, 600 uncached input tokens of excerpts plus the question, 80 output tokens. Cache-hit rates, not a cache write. Standard short-context or base rates. Prompts in the assumption are under the long-context thresholds those pages publish (272K input on the OpenAI table, 100,000 tokens on Claude Haiku 5.5).
Quality
A citation field gives you an id to open. The sentence in the demo answer is copied from that chunk. A real model can cite an id and still write a sentence the chunk does not contain. The check is yours.
Risk
The instruction says the excerpts are data. The model can still follow a sentence inside them. The pasted-ticket chunk is in the prompt on purpose when it ranks, so you can see that.
Rates per 1,000,000 tokens, vendor list price as of 2026-10-18. OpenAI API pricing, standard, short context: gpt-5-nano input $0.05, cached input $0.005, output $0.40, cache writes blank. gpt-4.1 input $2.00, cached input $0.50, output $8.00, cache writes blank. Anthropic pricing: Claude Haiku 5.5, prompts up to 100,000 tokens, input $0.10, cache hits $0.01, output $0.50. Claude Sonnet 5.5 input $2, cache hits $0.10, output $10. The Anthropic page says a cache hit on Sonnet 5.5 is 0.05× the base input price, which is the $0.10 in the table. Batch, flex, and long-context columns are not used here.
- gpt-5-nano, cache hit200 × $0.005 ÷ 1,000,000 = $0.000001
600 × $0.05 ÷ 1,000,000 = $0.000030
80 × $0.40 ÷ 1,000,000 = $0.000032
Call = $0.000063 - gpt-4.1, cache hit200 × $0.50 ÷ 1,000,000 = $0.000100
600 × $2.00 ÷ 1,000,000 = $0.001200
80 × $8.00 ÷ 1,000,000 = $0.000640
Call = $0.001940 - Haiku 5.5, cache hit200 × $0.01 ÷ 1,000,000 = $0.000002
600 × $0.10 ÷ 1,000,000 = $0.000060
80 × $0.50 ÷ 1,000,000 = $0.000040
Call = $0.000102 - Sonnet 5.5, cache hit200 × $0.10 ÷ 1,000,000 = $0.000020
600 × $2 ÷ 1,000,000 = $0.001200
80 × $10 ÷ 1,000,000 = $0.000800
Call = $0.002020
Same assumed tokens, cache hit: $0.000063 at the gpt-5-nano list price and $0.002020 at the Claude Sonnet 5.5 list price. That is the range across these four published rates. It is not a measured invoice, and it says nothing about which model answers well.
4 Say you don't know
Cards: Hallucination, Freshness & access control.
If no trusted sentence shares the question, return “I don't know” and skip the answer model. Freshness & access control is the check this page does not run: whether the sentence is still the policy, and whether this caller may see it. The Hallucination card defines a hallucination as a reply that states something the prompt and the sources do not support. Anthropic's guide on reducing hallucinations and OpenAI's accuracy guide are the sources that card cites for keeping a reply on the material you supplied. This page's rule is narrower and local: a trusted sentence is quoted only when it shares at least two question words. Otherwise the JSON sets known to false, citations to an empty list, and the answer to “I don't know. The sample docs do not say.” Try “Which carrier ships the hardware token?”. The toy vector still returns chunks. The template does not quote them.
Cost
The refusal in this demo is code, so it adds no model bill. You can return it before the answer call. A second model that checks the claim is another request, priced like the judge in step 6. This page does not make that call.
Quality
An explicit unknown is a product result. Without it, a fluent refund window that the docs do not contain still looks finished. The two-word rule will also refuse a fair paraphrase that shares no words with the chunk. That is a miss you should see in the eval set, not a property of models in general.
Risk
A loose rule cites a weak chunk. A strict rule hides an answer you do have. Neither rule checks that the chunk is the current policy or that this user may see it.
5 Cache the prefix, route the call
Cards: Prompt Caching, Model Selection & Routing, Cost forecasting, Latency, Fallbacks & rate limits.
Cache the unchanged instruction prefix, and send a thin match to a higher list price than a quote you already have. OpenAI, Anthropic, and Gemini document prompt caching as a way to reuse a prefix that did not change. On this page the prefix is the instruction block in the assembled prompt. The excerpts and the question sit after it, because they change every call. The demo route is a label, not a dispatch: “I don't know” stops in code, three or more shared words is marked for the cheaper list price, and two shared words is marked for the higher one. A real route only earns its keep after the eval set in step 6 agrees. The arithmetic below is the multiplication Cost forecasting describes: assumed token counts times a published rate. Latency is the wait a user feels, which on this bot includes retrieval before any answer call. Fallbacks & rate limits is the plan when that call errors, stalls, or comes back rate-limited. This demo never makes the call, so it has no fallback to show.
Cost
A short prefix barely moves the bill. A long stable prefix does. The lines below keep the 600 uncached tokens and 80 output tokens from step 3 and change the prefix to an assumed 2,000 tokens. gpt-4.1's cache-write cell on the OpenAI table is blank, so no write charge is added. Haiku 5.5 lists a 5-minute cache write at $0.125 per 1,000,000 tokens, above the $0.10 base input rate. Vendor list price as of 2026-10-18. Same sources as step 3.
Quality
The cheaper route can miss a citation the higher list price would have written. You do not get that from the price table. You get it by running the same questions through both routes and reading the misses.
Risk
Caching the wrong block, such as the user's question or an untrusted excerpt, pins that text into later calls. Keep the cached region to text you wrote.
- gpt-4.1, no cache2,600 × $2.00 ÷ 1,000,000 = $0.005200
80 × $8.00 ÷ 1,000,000 = $0.000640
Call = $0.005840 - gpt-4.1, cache hit2,000 × $0.50 ÷ 1,000,000 = $0.001000
600 × $2.00 ÷ 1,000,000 = $0.001200
80 × $8.00 ÷ 1,000,000 = $0.000640
Call = $0.002840 - Haiku 5.5, no cache2,600 × $0.10 ÷ 1,000,000 = $0.000260
80 × $0.50 ÷ 1,000,000 = $0.000040
Call = $0.000300 - Haiku 5.5, cache hit2,000 × $0.01 ÷ 1,000,000 = $0.000020
600 × $0.10 ÷ 1,000,000 = $0.000060
80 × $0.50 ÷ 1,000,000 = $0.000040
Call = $0.000120 - Haiku 5.5, 5-minute write2,000 × $0.125 ÷ 1,000,000 = $0.000250
600 × $0.10 ÷ 1,000,000 = $0.000060
80 × $0.50 ÷ 1,000,000 = $0.000040
Call = $0.000350
On these assumptions the Haiku write costs more than sending the prefix uncached, and the next cache hit costs less. Anthropic's pricing page says a 5-minute cache pays off after one cache read. Use the cached rate only after a real response shows those tokens billed as a hit. The Foundations playbook makes the same point for a different example.
6 Check five questions
Cards: Evaluation basics, Production evaluation, Monitoring & drift.
Keep a small set of questions with labels, check citations in code, and treat an LLM judge as a second paid call. Evaluation basics is that labelled set. Production evaluation is the same kind of set, saved and run again before a prompt, model, or retrieval change faces users. Monitoring & drift is watching quality after launch, when a model update or a change in the documents moves behavior off the set. The five rows in the demo are the labelled set: weekday hours, the refund window, SCIM, a question the docs do not answer, and a request for an admin password. A row passes when the simulated citation matches the label. That check is code. These five rows are not a production suite.
OpenAI's evaluation guide describes LLM-as-a-judge as using a model to score outputs, and it says to start with a strong judge (the page names gpt-6-astra) and then validate agreement against human labels. It also names position bias and verbosity bias as problems with that setup. The graders guide says to use an LLM judge when code cannot score an open answer. Anthropic's testing guide says to define success criteria you can measure before you tune. None of those pages is a score for this bot. This page does not report one.
Cost
The code check has no model bill. A judge is another request: the question, the answer, the excerpt, and the rubric go in, and a grade comes out. Assumptions: 1,000 uncached input tokens and 50 output tokens, no cache. gpt-5-nano and gpt-6-astra standard short-context rates from the OpenAI pricing page. The judge names gpt-6-astra because the evaluation guide does. Vendor list price as of 2026-10-18.
Quality
Five labelled questions catch a broken citation and a missing “I don't know”. They do not describe production traffic. Add a row when a real miss shows up, and keep the old rows.
Risk
A judge that you have not checked against labels can prefer a long wrong answer. The OpenAI guide says to validate that agreement before you scale the judge. A set with only questions you already pass will not show a miss.
- gpt-5-nano judge1,000 × $0.05 ÷ 1,000,000 = $0.000050
50 × $0.40 ÷ 1,000,000 = $0.000020
Call = $0.000070 - gpt-6-astra judge1,000 × $10.00 ÷ 1,000,000 = $0.010000
50 × $50.00 ÷ 1,000,000 = $0.002500
Call = $0.012500
Five judge calls at the gpt-6-astra list price, under this token assumption, are 5 × $0.0125 = $0.0625. Five code checks are $0. The rubric you would send is the instruction already in the demo prompt, plus the expected citation. This page does not send it.
7 Treat the docs as untrusted
Cards: Prompt injection, Privacy & data handling, Safety.
A document can contain an instruction. Keep it in the prompt as data, and do not follow it. One sample file is a pasted ticket. It tells the reader to ignore the support policy, claim a 90-day refund, and email an admin password. OWASP's LLM01:2025 entry describes indirect prompt injection from external content such as a file, and says retrieval augmented generation does not fully remove that risk. The Prompt injection card cites that entry, plus Anthropic's jailbreak guide and OpenAI's safety notes. Privacy & data handling is the decision about what enters a prompt and what should never be sent. The admin password in the pasted ticket is text that should not be sent onward, and the template does not quote it. Safety is the limit on what the product will do with that text. The demo has no tool that can email a password.
Run the “90-day note” question. The pasted ticket can rank first, because it repeats the words in the question. The simulated answer still quotes the 14-day refund sentence and cites that chunk. A real model can follow the ticket instead. The template does not prove a model will refuse.
Cost
The hostile excerpt still counts as input tokens if you paste it into the answer call priced in step 3. A separate classifier, if you add one, is another model bill. A string check is code. This page uses the code path and does not add a classifier price.
Quality
If the model obeys the ticket, the refund answer becomes 90 days and the citation looks confident. Read the retrieved text, not only the answer.
Risk
The ticket is untrusted data in the same channel as the policy. Do not grant the answer model a tool that can email a password. The demo has no tool and no mailbox.
Build it yourself
A minimal sketch of the pass. The embed and complete lines are the ones a real build would send to a provider. This page does not run them.
function answer(question, chunks) {
var qv = embed(question); // vendor embeddings API
var keyword = chunks.map(bm25);
var vector = chunks.map(function (chunk) { return cosine(qv, chunk.vector); });
var hybrid = fuse(keyword, vector); // scale each list, then add
var top = rerank(question, hybrid).slice(0, 3);
var prompt = PREFIX + excerpts(top) + question;
if (!supported(top, question)) {
return { known: false, answer: "I don't know.", citations: [] };
}
return complete(prompt, schema); // vendor chat API; not called here
}
Checklist
- Put one fact you can point at in a chunk a person can read.
- Search with words and with vectors. Read both lists before you fuse them.
- Rerank a short candidate list, not the whole corpus, and read the new order.
- Keep the instruction prefix stable. Put the question and the excerpts after it.
- Ask for known, answer, and citations. Reject a citation id you did not retrieve.
- If no trusted sentence supports the question, return “I don't know” in code.
- Treat every document as untrusted. Do not follow instructions found in a chunk.
- Write five questions you know the answer to, including one the docs do not answer and one with a hostile chunk.
- Check citations with code. Add an LLM judge only after those rows pass, and price that second call.
- Open the pricing page on the day you ship. The list prices above were read on 2026-10-18.
Playbook The deeper set, on your documents, with a vendor reranker and a judged eval you run against a model, is what a playbook is for. The Retrieval & Grounding playbook is the how-to for this build. It is not written yet. This site does not take payment. Tiers are on Pricing.
Sources
Opened 2026-10-18. Prices in the steps are copied from the pricing pages. The other links are the docs the steps rely on. No rate was added beyond those pages.
- OpenAI, API pricing
- Anthropic, Pricing
- Gemini API, Pricing
- Cohere, Pricing
- Cohere, How pricing works
- OpenAI, Retrieval
- OpenAI, Embeddings
- Gemini, File Search
- Gemini, Embeddings
- Cohere, Rerank
- OpenAI, Structured outputs
- Anthropic, Structured outputs
- Gemini API, Structured outputs
- OpenAI, Prompt caching
- Anthropic, Prompt caching
- Gemini API, Context caching
- OpenAI, Model selection
- Anthropic, Choosing a model
- Anthropic, Reduce hallucinations
- OpenAI, Optimizing LLM accuracy
- OpenAI, Evaluation best practices
- OpenAI, Graders
- Anthropic, Develop tests
- OWASP, LLM01:2025 Prompt Injection
- Anthropic, Mitigate jailbreaks and prompt injections
- OpenAI, Safety best practices