Ground an Agent in Your Company Handbook
Maya runs the internal-tools team. The company handbook is a folder of policies, onboarding guides, and contracts — hundreds of files across dozens of folders. Her first attempt at a “handbook bot” was the usual recipe: a loader, a text splitter, an embedder, a vector store, glued together by hand. It answered confidently and often wrongly, with no way to show where an answer came from.
The problem wasn’t the model. It was that her pipeline flattened the handbook into a pile of disconnected chunks. The folder structure — policies/data/ vs contracts/2024/ — and the links between documents were thrown away before the model ever saw them.
What you’ll build
Section titled “What you’ll build”A retrieval agent that:
- Answers questions from the handbook and cites the source file every time.
- Knows the shape of the handbook — document types, folders, and cross-references.
- Took one build command and one
connect()call to wire up.
By the end you’ll have a handbook.indx archive and an agent that reads from it.
The build
Section titled “The build”-
Install indx and a framework adapter.
The connectors live behind extras so the core stays light. Maya uses the OpenAI Agents SDK, but every framework is one method call — pick yours.
Terminal window pip install "indx[cloud]" "indx[openai-agents]"export OPENAI_API_KEY="sk-..." -
Build the knowledge space from the handbook folder.
The directory is the input. indx walks the tree, parses each file, chunks it, derives the relationship graph, enriches each document with a type and summary, and embeds everything — then seals it into one portable archive.
Terminal window indx ./handbook --out ./ai-readyindx ./handbook → ./ai-ready01 walk 142 files, 18 folders02 parse 142 ok, 0 skipped03 chunk 1180 chunks04 relate 412 relations05 enrich 142 documents (openai:gpt-5-mini)06 embed 1180 vectors → qdrant, sealed handbook.indxdone: 1180 chunks, 142 docs, embed_dim=1536 (14.1s)That
04 relate 412 relationsline is the part a hand-rolled pipeline never had:sibling,parent, andreferencesedges that carry the handbook’s structure into retrieval. -
Sanity-check retrieval before writing any agent code.
Never wire an agent to a space you haven’t looked at. Query it from the terminal first.
Terminal window indx query ./ai-ready/handbook.indx "how long do we retain customer data?" -k 3#1 score 0.84 policies/data/retention.pdf (policies/data · policy)"Customer data is retained for 90 days, after which it is purged…"neighbors: chunk_0203, chunk_0205The hit comes back with its source path, its detected type (
policy), and neighbor chunk ids for context. That provenance is exactly what your agent will cite. -
Plug the space into your agent — one call.
connect()loads the archive and hands your framework native tools. No indx types leak into your agent code.from agents import Agent, Runnerfrom indx.agent import connectkb = connect("ai-ready/handbook.indx", name="company-handbook")agent = Agent(name="Handbook",instructions="Answer only from the handbook tools. Always cite the source path.",tools=kb.openai(),)result = Runner.run_sync(agent, "How long do we retain customer data? Cite the source.")print(result.final_output)from indx.agent import connectkb = connect("ai-ready/handbook.indx", name="company-handbook")tools = kb.langchain() # StructuredTools for a tool-calling agent# or a classic retrieval chain:retriever = kb.langchain_retriever(k=5)docs = retriever.invoke("how long do we retain customer data?")from pydantic_ai import Agentfrom indx.agent import connectkb = connect("ai-ready/handbook.indx", name="company-handbook")agent = Agent("openai:gpt-5-mini", tools=kb.pydantic_ai())print(agent.run_sync("How long do we retain customer data? Cite the source.").output)The agent now has three tools —
indx_search,indx_overview, andindx_get_document— the same retrieval path you tested in step 3. -
Read a grounded, cited answer.
We retain customer data for 90 days, after which it is automatically purged.Source: policies/data/retention.pdf (policy)The citation is real: it’s the
hit.source.paththe search tool returned, not something the model invented.
Why the answers are better
Section titled “Why the answers are better”Maya’s hand-rolled pipeline retrieved text. The indx space retrieves grounded text — every chunk carries its source document, folder, detected type, and neighbor links.
That changes what the agent can do:
- It cites. Every hit has a
source.path, so “where did this come from?” always has an answer. - It can filter by structure. Ask it to restrict to one document type and it can —
kb.search(query, k=5, doc_type="policy")only returns policies. - It can widen context. Pass
with_context=Truetoconnect()and each hit carries its neighbor chunks, so the model reads around a match instead of seeing an orphaned fragment.
kb = connect("ai-ready/handbook.indx", default_k=8, with_context=True)What you learned
Section titled “What you learned”- A directory becomes a queryable, cited knowledge space with one build command.
connect()turns that archive into native tools for any framework — one object, one method per framework.- Provenance (
source.path, type, neighbors) is what makes grounded RAG trustworthy, and indx keeps it end to end.