# Course: Retrieval methods for AI agents
https://www.sanity.io/learn/course/retrieval-methods-for-ai-agents

Sort out which retrieval method should answer which kind of question, and which system owns each answer, before you build an agent.

---

## Navigation

## Contents

1. [Where your agent's knowledge runs out](https://www.sanity.io/learn/course/retrieval-methods-for-ai-agents/where-your-agents-knowledge-runs-out) · [markdown](https://www.sanity.io/learn/course/retrieval-methods-for-ai-agents/where-your-agents-knowledge-runs-out.md)
2. [What it costs to answer a question](https://www.sanity.io/learn/course/retrieval-methods-for-ai-agents/what-it-costs-to-answer-a-question) · [markdown](https://www.sanity.io/learn/course/retrieval-methods-for-ai-agents/what-it-costs-to-answer-a-question.md)
3. [The four ways an agent finds something](https://www.sanity.io/learn/course/retrieval-methods-for-ai-agents/the-four-ways-an-agent-finds-something) · [markdown](https://www.sanity.io/learn/course/retrieval-methods-for-ai-agents/the-four-ways-an-agent-finds-something.md)
4. [Sorting questions by what they cost](https://www.sanity.io/learn/course/retrieval-methods-for-ai-agents/sorting-questions-by-what-they-cost) · [markdown](https://www.sanity.io/learn/course/retrieval-methods-for-ai-agents/sorting-questions-by-what-they-cost.md)
5. [What each method can't do](https://www.sanity.io/learn/course/retrieval-methods-for-ai-agents/what-each-method-cant-do) · [markdown](https://www.sanity.io/learn/course/retrieval-methods-for-ai-agents/what-each-method-cant-do.md)
6. [Who owns the answer](https://www.sanity.io/learn/course/retrieval-methods-for-ai-agents/who-owns-the-answer) · [markdown](https://www.sanity.io/learn/course/retrieval-methods-for-ai-agents/who-owns-the-answer.md)
7. [Putting it all together](https://www.sanity.io/learn/course/retrieval-methods-for-ai-agents/putting-it-all-together) · [markdown](https://www.sanity.io/learn/course/retrieval-methods-for-ai-agents/putting-it-all-together.md)

---

## Lesson 1: Where your agent's knowledge runs out
https://www.sanity.io/learn/course/retrieval-methods-for-ai-agents/where-your-agents-knowledge-runs-out

A model knows a lot about the world and nothing about your business. Retrieval closes that gap, and the method you pick decides what your agent can answer.

**What happens when your agent promises a customer a refund your return policy doesn't actually cover?**



Someone has to honor it or explain why you won't, and by the time anyone on your team reads the conversation, the promise has already been made. The agent wasn't careless. It read the question, reasoned about it carefully, and produced a confident, well-written answer that happened to be wrong.



A language model arrives knowing a lot about the world and nothing about your business. It understands what a return policy is. It has no idea what your docs call a workspace, which of your plans includes audit logs, or that you stopped selling the Starter tier in March. That information was never in its training data, and reasoning cannot recover facts that were never there to reason over.



Retrieval closes that gap. Every time someone asks your agent a question, something has to go find the relevant piece of your content and put it in front of the model before it answers. That step determines the quality of everything downstream, because a model reasoning over the wrong three documents will produce a fluent, confident, wrong answer with complete composure.



There is more than one way to perform that step, and the right one depends on the question being asked.



Some answers already exist as structured content. Asking which of your plans include audit logs, or which integrations are generally available, means narrowing a set of records down to the ones that match. The answer lives in a field, it changes when your catalog changes, and querying your content directly at the moment someone asks returns something exact and current.



Other answers have never been written down in one place or need multiple documents to compose a single answer. Asking where customer data is stored, or what your retention policy is, means reading across a help center, a security document, and whatever legal published last quarter, then working out which of them is right. Answers like that can be assembled ahead of time into a knowledge base, settled by someone who knows which source wins, and retrieved later as a finished conclusion rather than reasoned out on the spot.



The distance between those two is wider than it first appears. Consider two customers asking about data retention on the same afternoon. One asks: **how long you keep their data**. The other asks: **what your retention policy is**. Any human reading those may treat them as the same question. An agent that researches the answer fresh each time has no guarantee of reaching the same conclusion twice, and if your help center says ninety days while your security documentation says thirty, those two customers walk away with two different answers. Both sound confident, but one of them is wrong.



Questions that look alike from the outside can cost very different amounts to answer, and they fail in different ways. What you learn here is how to sort them before any of it gets built. By the end of this course, you'll be able to:



1. Match each question your users ask to the retrieval method that should answer it, and recognize that a working agent usually needs more than one.

2. Identify where a method genuinely cannot serve a question, and determine where that content belongs instead.

3. Decide which system owns which answers, and what your agent is allowed to know.


The stakes are not evenly distributed across a question set. A wrong answer about a return window costs money. A wrong answer about an allergen in food service, a dosage in healthcare, or a contractual term in an enterprise agreement costs considerably more. Other questions have exactly one answer sitting in exactly one place and cost almost nothing to get right. Telling the cheap questions from the expensive ones is where the sorting starts.



---

## Lesson 2: What it costs to answer a question
https://www.sanity.io/learn/course/retrieval-methods-for-ai-agents/what-it-costs-to-answer-a-question

Two questions that look identical in a chat window, traced side by side. One resolves in three steps. The other is a research project, repeated every time.

**Your agent answered a question about data retention this morning. Will it give the same answer this afternoon?**



For a large class of questions, nobody can say, because the agent works the problem out fresh every time someone asks. Understanding why starts with two questions that arrive on the same afternoon and look equally simple.



The first asks: **which of your integrations support SSO?** The second asks: **how long do you keep customer data?** Both are a single line, and both sound like something a colleague could answer in under a minute. The work behind them is not remotely comparable.



The SSO question has a shape that makes it easy to query. Your integrations live as structured content, each record carrying fields that describe what it supports, so the agent orients itself in your content model, writes one query against the field holding the answer, and reads the result. That gives you three steps with one source. The answer already existed in your content and the agent did nothing more than go and get it. Ask again next month and the result reflects whatever shipped in between, because the query runs against live content rather than a copy of it.



The retention question doesn’t have the same shape. Retention is a policy rather than a property, so no field anywhere holds the number. The agent goes looking instead, and finds a help center article saying ninety days, a security white-paper saying thirty, and a page on the documentation site you inherited in an acquisition that gestures at industry standards and hasn't been edited in years. Three sources, three answers, and nothing to check them against.



At that point the agent has to decide which source to believe, and it will. These systems don't stop and ask. The agent weighs what it found, favors whichever source reads as most authoritative, and hands your customer a confident answer about data retention roughly two minutes and a dozen tool calls later.



Tool calls can be expensive, but what's more costly is an incorrect judgment made that no one reviewed. Nobody in legal chose ninety days, and nobody decided which source wins when two of your own documents disagree. The agent decided in the moment, based on what it happened to retrieve and in what order, and the customer who phrases the question differently tomorrow may well be told thirty. Every individual response looks fine, which is exactly what makes the problem hard to catch. It surfaces when two customers compare notes, when it reaches a support ticket, or during an audit.



None of that research has to happen while a customer waits. The same work can be done once, ahead of time. Someone reads the help article, the whitepaper, and the inherited documentation, notices that they disagree, and settles on thirty days with the whitepaper recorded as the source of record. The conclusion gets written down alone with where it came from. 



When the question arrives after that, the agent retrieves a conclusion a person already reached, with a citation attached to it. The research still happened, but it happened at build time, under review, once.



Moving the work earlier changes three things:



1. **Consistency.** Every customer who asks gets the same answer, settled once by someone with the authority to settle it.

2. **Cost.** A dozen round trips is a dozen round trips of tokens, repeated for every person who asks. Retrieved from a settled conclusion, the same question costs one lookup.

3. **Speed.** An answer that took a dozen calls and two minutes to assemble comes back in the time it takes to fetch one entry.


Which of the three matters most depends on what your agent is for. An agent fielding compliance questions lives or dies on consistency. An agent handling support volume feels the token cost first. An agent that customers abandon mid-conversation needs the speed. Most production agents care about all three in different proportions, and the proportions are yours to weigh.



A settled answer is only as current as the last build, which is why the choice is not made once for an entire product. Stable facts are worth settling ahead of time. Anything that moves belongs in a live query, and most products contain both.



Both approaches are retrieval, performed by different means at different moments. Sanity Context provides four of them across two retrieval modes, and each one can do something the others cannot.



---

## Lesson 3: The four ways an agent finds something
https://www.sanity.io/learn/course/retrieval-methods-for-ai-agents/the-four-ways-an-agent-finds-something

Exact filters, keyword relevance, semantic similarity, and path navigation. What each one does, where each one stops, and which one handles meaning.

**A customer asks your agent which integrations support single sign-on, and it returns nothing. Every integration in your catalog supports it. Which part of retrieval failed?**



Keyword matching failed, and it failed by working exactly as designed. The customer typed `single sign-on`. Your content says `SSO`. Token matching has no way to know those are the same thing, so the query returned an empty set and the agent reported, accurately, that it found nothing.



That failure is a property of one retrieval strategy rather than a bug in your setup. Sanity Context serves retrieval in two modes, **GROQ** and **Knowledge Bases**, and offers four strategies between them, each with different capabilities.



### **Exact filter, in GROQ mode.** 



Predicates over fields: `_type == "integration" && supportsSSO == true && status == "ga"`. Of the four strategies, the exact filter is the only one that narrows a set. The other three rank. A filter is also the only strategy that can promise a result set is complete, which is what makes it the right tool for anything a customer might act on. It stops being useful the moment the concept you want to filter on has no field behind it, which is the usual reason a filter returns nothing.



GROQ mode reads your schema to know what fields exist, so the dataset needs a deployed schema before the GROQ tools can do anything.



### **Keyword relevance, in GROQ mode.** 



The `match` operator does two different jobs depending on where you put it. Inside a filter, it narrows the set. Inside `score()`, it produces a BM25 relevance score and ranks the results that surfaced. The same operator plays two roles. It compares tokens, which is why `single sign-on` finds nothing in a catalog that says `SSO`.



### **Semantic similarity, in GROQ mode.** 



`text::semanticSimilarity()` compares meaning rather than tokens, which is the fix for the SSO problem that opened the lesson, however, there are two constraints come attached. It requires dataset embeddings to be enabled, and it is only valid as an argument to `score()`. Semantic search ranks and never filters, so it cannot exclude a document, guarantee a set is complete, or count anything.



### **Path navigation with Knowledge Bases** 



A build reads your sources ahead of time, resolves the places they contradict each other, and writes entries at addressable paths. At conversation time, the agent receives an outline through `initial_context`: every entry path with a one-line summary of what it covers, small enough to hold in context for the whole conversation. The agent reads the outline, picks the entries likely to hold the answer, and fetches them by path. It gives you deterministic lookup with without embeddings.



The vector search sits on the GROQ side. A knowledge base is not a vector database because its reasoning already happened during the build and what remains at query time is a path lookup. Meaning-based retrieval comes from enabling dataset embeddings and staying in GROQ mode.



The three GROQ strategies work together in a single query. The filter narrows the set, `score()` ranks what's left, and `boost()` weights one signal against another. Filter first, then an unfiltered score ranks your entire dataset, so you get the best of everything instead of the best of what qualifies.



An endpoint's mode comes from its sources rather than from a setting, and an endpoint can hold both types of source. Each mode serves its own tools, which is why a request returns one mode's toolset rather than a blend of the two.



### **What Sanity Context is and isn't. **



Sanity Context is read-only, and it does not run the agent loop. You bring the model and the harness; Context exposes `initial_context`, `schema_explorer`, and `groq_query` over MCP and answers from your content. The write-capable Sanity MCP is a separate server rather than a write mode of this one. Content Agent brings its own harness. AI Assist is a Studio field plugin. Each one solves a different problem, and none substitutes for another.



> **Question:** Your team wants a query where asking about single sign-on also surfaces records that only say SSO. Where does that capability live?
>
> 1. In a knowledge base, since knowledge bases handle meaning
> 2. In GROQ mode, with dataset embeddings enabled **[correct]**
> 3. In a vector database connected alongside Sanity
> 4. In the system prompt, by listing synonyms

With four strategies on the table, how do you know which one should answer a given question?



---

## Lesson 4: Sorting questions by what they cost
https://www.sanity.io/learn/course/retrieval-methods-for-ai-agents/sorting-questions-by-what-they-cost

Gathering, reconciling, and judgment. Three properties that sort any question into a live query or a settled fact, applied one question at a time.

**How many times are you willing to pay for the same answer?**



That question sorts a question set faster than any comparison of features, and it runs per question rather than per project. You are deciding how your agent should answer this particular question, not which product your company adopts. A real agent's question set lands on both answers, which is the normal outcome, not a sign that something went wrong.



Three properties decide how expensive a question is:



1. **Gathering.** One lookup, or a dozen?

2. **Reconciling.** One source, or several that disagree across multiple systems?

3. **Judgment.** A value you return, or a conclusion someone has to reach?


When none of the three are present, reach for GROQ mode and let the agent query your live content at the moment someone asks. When one or more are present on a question people ask repeatedly, settle the answer ahead of time in a knowledge base.



One more question tells you how much the cost matters: **is there a single right answer, and what happens if your agent gets it wrong?** A question with one correct answer and consequences attached to missing it is worth settling ahead of time even when querying it would be cheap, because settling it puts a person between your sources and your customer.



Consider a few examples:



- ***Which integrations support SSO?* **One lookup, one source, a value that already exists. A query: `*[_type == "integration" && supportsSSO == true && status == "ga"]`. The catalog changes, the answer changes with it, and nothing needs rebuilding.

- ***How many integrations support SCIM?* **Many records, but still one source and a value, computed rather than stored: `count(*[_type == "integration" && supportsSCIM == true])`. A query again, and here only GROQ can do the work, because a knowledge base has no way to compute over records.

- ***Where is customer data stored?*** Four sources, actively disagreeing, with contractual exposure attached to getting it wrong. All three properties present on a question enterprise buyers ask constantly. Settle this ahead of time with a knowledge base.

- ***How do I set up SAML with Okta?*** Setup guides, release notes, and a migration doc that describes an older flow. Gathering and reconciling both present, with version drift as the specific risk. Settle this ahead of time with a knowledge base.

- ***Are we over our usage limit right now?* **Neither method applies. Usage belongs to your billing system, which is the only thing that knows the current number, and a later lesson covers what to do with questions like it.


The common first instinct is to ask whether GROQ can answer a question. It usually can, including the hard ones, given enough tool calls and enough time. The more useful question is what it costs you when the wrong answer reaches a customer. A question whose wrong answer means a refund you didn't owe, a contract term you can't honor, or a compliance claim you can't support is worth settling ahead of time no matter if query could produce it.



Settling an answer ahead of time carries its own cost. Builds run on a refresh schedule set per knowledge base rather than per source, so a settled answer is only as current as the last build. Stable facts tolerate that well. Pricing, availability, and anything else that moves between builds does not. **Settle what's stable. Query what moves.**



> **Question:** A customer asks what your data retention policy is, and the answer turns out to be expensive to produce. Which property makes it expensive?
>
> 1. The answer requires reconciling sources that disagree **[correct]**
> 2. The query has to scan too many records
> 3. The answer has to reflect real-time data
> 4. The content model has no field for retention

Sorting works until a question lands somewhere neither method can reach.



---

## Lesson 5: What each method can't do
https://www.sanity.io/learn/course/retrieval-methods-for-ai-agents/what-each-method-cant-do

Some questions only one method can answer. Some belong to neither. Knowing which is which keeps you from building the wrong thing.

**A sales engineer asks your agent how many integrations support SCIM, and a knowledge base answers with a number. Should you trust it?**



Not without checking, and the reason is structural rather than a matter of quality. A knowledge base holds entries written during a build, and an entry can state a count that was accurate the day someone wrote it. Nothing recounts when your catalog changes. Counting is arithmetic over records, and only a query performs arithmetic.



Each method holds territory the other cannot enter.



### **Only GROQ computes.** 



Counting, summing, averaging, aggregating, and traversing references between documents all operate over a live set of records. `count(*[_type == "integration" && supportsSCIM == true])` returns a number that is correct at the moment it runs, and correct again next quarter without anyone touching it. A knowledge base has no function to complete mathematical operations over your content, so any number it reports is a number someone documented.



### **Only a knowledge base reconciles.** 



When your help center and your security whitepaper disagree, a build surfaces the conflict as an issue for someone to settle. The decision persists as an instruction anchored to those sources, so later builds keep it instead of working the question out again. Every entry carries a citation back to the claim's origin. A query returns what your documents say and has no concept of which document is the most correct.



### **Neither answers for a system you don't own.** 



Whether this account is past its usage limit, whether that order shipped, whether the item is in stock: those facts live in billing, your order management system, and your inventory service. No retrieval method over your content produces them, because your content is not where they are.



That third category gets misread more than the other two. GROQ queries your dataset at request time, so anything Sanity owns is already real-time. Publish a price change and the new price is queryable immediately. What separates Sanity from an operational system is which one owns the fact, not which one has it first.



Capability decides most routing. A few constraints decide the rest, and each one moves content somewhere else rather than ruling a method out of your project.



### **What gets into a knowledge base. **



A knowledge base can combine three kinds of sources. One Sanity dataset selected with a GROQ query, uploaded files (like PDFs, images, text, code), and websites crawled from a starting URL. 



Capability and ingestion route most of your content. What's left is a question neither one answers: which system owns a fact in the first place?



---

## Lesson 6: Who owns the answer
https://www.sanity.io/learn/course/retrieval-methods-for-ai-agents/who-owns-the-answer

What your agent is allowed to reach, what it's allowed to say, and which system owns each answer it gives.

**A customer asks your agent whether their account is past its usage limit, and the agent answers from your pricing content. What went wrong?**



The agent answered a question about one account using a document that describes a plan. The plan's limit is 50,000 events, which is true, published, and correctly retrieved. Whether this particular customer has used 51,000 of them is a fact only your billing system holds. The answer was assembled with complete confidence from the wrong owner.



Nothing in the retrieval layer prevents that. There is no built-in router. Every backend you connect contributes its tools to one flat list, and the model chooses by matching tool names and descriptions against the conversation. Sanity Context's tools are deliberately generic. `groq_query`, `schema_explorer`, and `initial_context` describe mechanisms rather than domains, so a model choosing between them and a billing API's tools has very little to go on.



You are the router. An ownership table makes the split visible, with exactly one owner for each kind of data your agent could be asked about.



- **Catalog, articles, help content, and marketing copy.** Sanity owns them, because they are structured, editorially managed, and queryable.

- **Live inventory, order status, and shipping.** Your commerce platform or order management system owns them, because they change second by second.

- **Payments and refunds.** Your billing system owns them as the system of record, and the operations have side effects.

- **Support ticket history.** Your helpdesk owns it, because it owns the conversation.

- **Entitlements and current usage.** Your billing or entitlement service owns them, because they are per-account state.


Sanity owns your content: the product, the plan, the policy, and every word you have published about them. Operational systems own state: what this customer has used, where that order is, how many units are left. Most routing problems answer themselves once the split is clean, and the table becomes the routing table in your system prompt when you build.



Four ways to enforce the split:



1. **A routing table in the system prompt.** Name each data type and the tool that owns it. This isn’t complex, and it handles the ordinary cases.

2. **Structural scoping.** A `groqFilter` on the Context document keeps out-of-scope content from being returned at all, and an instruction stating what the dataset does not contain ("live stock is not stored here, use the inventory tool") closes the gap from the other side. The scoping fails safe, which the prompt alone does not.

3. **Reshaping the tool set.** Subset and re-describe the generic tools before handing them to the model, so the description carries the domain and the boundary.

4. **Architectural change.** Past a certain complexity, a cheap classification call that picks a domain first, or a supervisor that delegates to sub-agents holding only the relevant tools, scales better than one agent holding every tool.


```typescript
const tools = {
  ...commerceTools,
  query_content: {
    ...sanityTools.groq_query,
    description:
      'Query the CONTENT catalog (products, articles, help docs) in Sanity. ' +
      'Use for descriptions, specs, copy, and canonical IDs, NOT live stock or orders.',
  },
}
```

Scoping is the difference between an agent that is asked not to reach something and an agent that cannot. A `groqFilter` is an access boundary enforced at the endpoint, so excluded content never reaches the model at all. Unreleased work is the clearest case. A plan tier launching next quarter, a feature still in staging, an integration under NDA: all of it sits in your dataset, and none of it should reach a customer-facing agent. A filter like `_type == "feature" && status == "ga"` keeps it out structurally rather than asking the model not to mention it. 



Sanity Context separates what an agent can reach from how it behaves. Scope is the filter. Behavior is the instructions, and they live in Sanity rather than in your agent code, so changing how your agent uses your content takes no deploy and no additional dev work. 



Knowledge bases add a review step that isn't possible at query time. A build surfaces contradictions as issues before anything reaches production, a person settles them, and the decision persists as an instruction anchored to its sources. Every entry cites where its claim came from. Query time retrieval still involves judgment about which source to believe. The judgment happens at answer time instead, once per question, with no one to validate.



Composing across owners is how a working agent answers a question like the one that opened this lesson. Resolve the canonical product and its editorial detail from Sanity, hand the SKU to the commerce API for live stock, and answer from both. Because you own the split, you decide what your agent trusts for which class of fact, and no vendor default decides it for you.



> **Question:** A customer asks whether their account is past its usage limit. Which system should answer?
>
> 1. The billing or entitlement service that tracks consumption **[correct]**
> 2. A GROQ query against your plan documents
> 3. A knowledge base entry describing plan limits
> 4. The system prompt, if the limits are listed there

---

## Lesson 7: Putting it all together
https://www.sanity.io/learn/course/retrieval-methods-for-ai-agents/putting-it-all-together

How the pieces fit together, and the one artifact worth writing before you build anything.

**Which question in your product costs the most to get wrong?**



Start there, because the sorting in this course pays off fastest on the questions that carry consequences.



Retrieval is the handoff between what a model knows and what your business knows, and the method you choose decides what your agent can answer and how consistently it answers.



Answers that already exist as structured content belong in a live query. GROQ mode narrows with a filter, ranks with `score()`, and weights with `boost()`, all in one query against content that is current the moment the question arrives. Counting, summing, and traversing references belong here too, because no other method computes.



Answers scattered across prose that nobody has settled belong in a knowledge base. A build gathers them, surfaces the contradictions for a person to resolve, and writes entries with citations, so your agent retrieves a reviewed conclusion instead of reaching a fresh one while a customer waits.



Three properties tell you which is which: gathering, reconciling, and judgment. A fourth question tells you how much the answer matters: is there a single right answer, and what does getting it wrong cost?



Some answers belong to neither method. Per-account state, live inventory, and transactional status live in the systems that own them, and your agent's job is to route to those systems rather than guess from content that looks close enough.



The first thing to build is not an agent. Write the ownership table for your own content: every kind of question your users ask, with exactly one owner each. The rows you hesitate on are the ones worth settling now, while the cost of being wrong is a conversation rather than a customer.



### Keep going!



Check out the following courses and docs to start building your own agent with structured content, grounded in facts, using knowledge bases.



- [Knowledge Bases](https://www.sanity.io/learn/ai/sanity-context-knowledge-bases) Learn more about what a knowledge base is, how a build works, and what the purpose, outline, entries, issues, and instructions each do.

- [Quick start: connect an agent to Sanity Context](https://www.sanity.io/learn/ai/sanity-context-quick-start)Connect an agent to Sanity Context

- [Context retrieval modes](https://www.sanity.io/learn/ai/sanity-context-retrieval-modes) Choosing between GROQ mode and Knowledge Base mode for a given body of content.

- [Sanity Context patterns and best practices](https://www.sanity.io/learn/ai/sanity-context-patterns) Scoping, routing, and instructing agents once the basics work.

- [Between GROQ and a hard place](https://www.sanity.io/learn/course/between-groq-and-a-hard-place)


---

## Related Resources

- [All courses and lessons](https://www.sanity.io/learn/sitemap.md)
- [Complete content for LLMs](https://www.sanity.io/learn/llms-full.txt)
