{"slug": "llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and", "title": "LlamaIndex ‘legal-kb’: Agentic Retrieval over Index v2 with retrieve, find, read, and grep Tools", "summary": "LlamaIndex released legal-kb, an open-source reference application demonstrating agentic retrieval over legal documents using Index v2. The app provides an agent with filesystem-style tools—retrieve, findFiles, readFile, and grepFile—to crawl and query a knowledge base, offering version control and hybrid search. This approach moves beyond single-shot retrieval by enabling iterative, tool-driven document analysis.", "body_md": "LlamaIndex has published\n\n, a public reference application on GitHub. It is described as a knowledge base for legal documents, powered by LlamaIndex Index v2 (the LlamaParse Platform). The project demonstrates a pattern the team calls a Retrieval Harness for agentic retrieval.[legal-kb](https://github.com/run-llama/legal-kb)\n\nThe approach differs from single-shot retrieval. Instead of one embedding search per query, an agent is given filesystem-style tools. It can then crawl a large, evolving knowledge base to solve a task. The tools mirror operations engineers already know: semantic and keyword search, regex grep, file search, and read.\n\n**What is legal-kb?**\n\n`legal-kb`\n\nis a working TanStack Start web app, not a library. You sign in, create a project, upload files, and chat with an agent. Each project is mirrored as a managed LlamaCloud Index v2. Uploaded files are parsed and indexed automatically in the background. The chat agent then queries that index live during each turn.\n\n**The Retrieval Harness, in plain terms**\n\nThe harness provides a persistent data pipeline over your documents. It connects to a data source, indexes it, and keeps it updated. On top of that pipeline, it exposes a set of tools to the agent.\n\nThose tools are deliberately close to filesystem operations. An agent can list files, read a file, grep inside a file, or run hybrid search. Because the tools are generic, you can plug the harness into your own agents.\n\n**The four agent tools**\n\nThe agent in `src/lib/agent.ts`\n\nis given four tools. Each maps to an Index v2 retrieval API. The table below lists them as implemented.\n\n| Tool | Backing API | Key parameters | What it does |\n|---|---|---|---|\n`retrieve` | `beta.retrieval.retrieve` | `query` , `top_k` , `score_threshold` , `rerank_top_n` , `file_name` , `file_version` | Runs hybrid semantic search; optional reranking; returns chunks plus citations |\n`findFiles` | `beta.retrieval.find` | `file_name` , `file_name_contains` | Searches files by exact name or substring; paginates automatically |\n`readFile` | `beta.retrieval.read` | `file_id` , `offset` , `max_length` | Reads raw file content, with offset and length windows |\n`grepFile` | `beta.retrieval.grep` | `file_id` , `pattern` , `context_chars` , `limit` | Matches a pattern in one file; returns character positions |\n\nThe system prompt enforces an order. The agent must call `findFiles`\n\nfirst to establish the document inventory. It then narrows with `retrieve`\n\n, and confirms exact wording with `readFile`\n\nor `grepFile`\n\nbefore citing.\n\n**How it works under the hood**\n\nUploads follow a clear pipeline in `src/lib/files.ts`\n\n. Bytes are pushed to the project’s LlamaCloud source directory. A `File`\n\nand `ProjectFile`\n\nrow are written to PostgreSQL via Prisma. An index sync is triggered but not awaited; the UI polls status until ready.\n\nVersioning is scoped to the (project, filename) pair. Re-uploading `nda.pdf`\n\nto the same project produces v1, v2, v3 side by side. The retrieval layer filters on the `version`\n\nmetadata field. This gives version control over the knowledge base itself.\n\nThe agent uses the `ToolLoopAgent`\n\nfrom Vercel AI SDK 6. You pick OpenAI or Anthropic per turn and bring your own keys. Reasoning is streamed: Claude models use extended thinking; OpenAI reasoning models use a medium reasoning effort.\n\nHere is a condensed but faithful view of the `retrieve`\n\ntool and the agent.\n\n``` js\nimport { LlamaCloud } from '@llamaindex/llama-cloud'\nimport { tool, ToolLoopAgent } from 'ai'\nimport { z } from 'zod'\nimport { makeCitationId } from './citations'\n\n// One tool closure per index. Wraps Index v2 retrieval APIs.\nfunction createLlamaParseTools(apiKey: string, projectId: string, indexId: string) {\n  const client = new LlamaCloud({ apiKey })\n\n  const retrieve = tool({\n    description: 'Run a semantic retrieval query against an index.',\n    inputSchema: z.object({\n      query: z.string(),\n      top_k: z.number().nullable(),\n      score_threshold: z.number().nullable(),\n      rerank_top_n: z.number().nullable(),   // set to enable reranking\n      file_name: z.string().nullable(),      // metadata filter\n      file_version: z.number().nullable(),\n    }),\n    execute: async ({ query, top_k, score_threshold, rerank_top_n, file_name }) => {\n      const custom_filters = file_name\n        ? { file_name: { operator: 'eq' as const, value: file_name } }\n        : undefined\n\n      const response = await client.beta.retrieval.retrieve({\n        index_id: indexId,\n        project_id: projectId,\n        query,\n        top_k,\n        score_threshold,\n        rerank: rerank_top_n != null ? { enabled: true, top_n: rerank_top_n } : undefined,\n        custom_filters,\n      })\n\n      // Return a model-readable list plus citations that drive the UI chips.\n      const citations = response.results.map((r) => ({\n        id: makeCitationId(),                    // e.g. \"c7f2qa\"\n        fileName: r.metadata?.file_name,\n        score: r.rerank_score ?? r.score ?? null,\n        preview: r.content.slice(0, 500),\n      }))\n      const formatted = response.results\n        .map((r, i) => `### Result #${i + 1}\\n\\n${r.content.slice(0, 600)}`)\n        .join('\\n\\n---\\n\\n')\n      return { formatted, citations }\n    },\n  })\n\n  // findFiles / readFile / grepFile follow the same shape, backed by\n  // client.beta.retrieval.find / .read / .grep\n  return { retrieve /* , findFiles, readFile, grepFile */ }\n}\n\nexport function buildAgent(model, apiKey: string, projectId: string, indexId: string) {\n  return new ToolLoopAgent({\n    model,\n    tools: createLlamaParseTools(apiKey, projectId, indexId),\n    instructions:\n      'Always call findFiles first, ground every answer in the documents, ' +\n      'and cite ids inline as `cite:<id>`.',\n  })\n}\n```\n\nAnswers carry visual citations. Each retrieved chunk gets a short id, such as `cite:c7f2qa`\n\n. The agent references that id inline, and the UI renders a clickable citation chip. Clicking it opens the source page screenshot with bounding-box rectangles over the cited text.\n\n## Naive RAG vs the agentic Retrieval Harness\n\nThe harness is a different execution model from single-shot RAG. **The comparison below focuses on behavior.**\n\n| Dimension | Naive / single-shot RAG | Agentic Retrieval Harness (Index v2) |\n|---|---|---|\n| Retrieval flow | One vector search per query | Multi-step tool loop: find → retrieve → read/grep |\n| Search modes | Vector similarity only | Hybrid semantic search, keyword, and regex grep |\n| Context | Fixed top-k chunks | Agent reads full files or windows on demand |\n| Freshness | Static index | Persistent pipeline with sync and versioning |\n| Precision control | Mostly hidden | `top_k` , `score_threshold` , `rerank_top_n` exposed |\n| Citations | Chunk ids | Visual citations with page screenshots and bboxes |\n| Best fit | Short question answering | Long-horizon document tasks |\n\n**Use cases, with examples**\n\nThe design targets domains where agents navigate large document sets. Legal and fintech are the stated examples.\n\n- Consider a contract question: ‘What notice is needed to terminate the MSA?’ The agent lists files, runs\n`retrieve`\n\n, then greps the exact clause. It answers with a citation to the specific page. - Consider due diligence across a data room: An agent can\n`findFiles`\n\nby name, then`readFile`\n\neach candidate. It cross-checks clauses without a human opening every PDF. - Consider a versioned policy base: Because\n`retrieve`\n\naccepts a`file_version`\n\nfilter, an agent can query a specific version. This supports change tracking over time.\n\n**Reference implementation**\n\n**Key Takeaways**\n\n`legal-kb`\n\nis a public reference app showing agentic retrieval on LlamaIndex Index v2.- The agent gets four filesystem-style tools:\n`retrieve`\n\n(hybrid search),`findFiles`\n\n,`readFile`\n\n, and`grepFile`\n\n. - A persistent pipeline handles parsing, indexing, sync, and per-file version control.\n- Answers include visual citations: page screenshots with bounding boxes over the cited text.\n- The stack is TanStack Start, AI SDK 6, Prisma, and WorkOS, with per-user encrypted keys.\n\nCheck out the** GitHub Repo**.\n\n**Also, feel free to follow us on**\n\n**and don’t forget to join our**[Twitter](https://x.com/intent/follow?screen_name=marktechpost)\n\n**and Subscribe to**\n\n[150k+ML SubReddit](https://www.reddit.com/r/machinelearningnews/)**. Wait! are you on telegram?**\n\n[our Newsletter](https://www.aidevsignals.com/)\n\n[now you can join us on telegram as well.](https://t.me/machinelearningresearchnews)Need to partner with us for promoting your GitHub Repo OR Hugging Face Page OR Product Release OR Webinar etc.? [Connect with us](https://forms.gle/wbash1wF6efRj8G58)\n\nMichal Sutter is a data science professional with a Master of Science in Data Science from the University of Padova. With a solid foundation in statistical analysis, machine learning, and data engineering, Michal excels at transforming complex datasets into actionable insights.\n\n- Michal Sutter\n- Michal Sutter\n- Michal Sutter\n- Michal Sutter\n- Michal Sutter\n- Michal Sutter", "url": "https://wpnews.pro/news/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and", "canonical_source": "https://www.marktechpost.com/2026/07/05/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools/", "published_at": "2026-07-05 07:50:19+00:00", "updated_at": "2026-07-07 01:55:23.462064+00:00", "lang": "en", "topics": ["ai-tools", "ai-agents", "large-language-models", "ai-research"], "entities": ["LlamaIndex", "LlamaCloud", "Vercel AI SDK", "OpenAI", "Anthropic", "TanStack Start", "PostgreSQL", "Prisma"], "alternates": {"html": "https://wpnews.pro/news/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and", "markdown": "https://wpnews.pro/news/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and.md", "text": "https://wpnews.pro/news/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and.txt", "jsonld": "https://wpnews.pro/news/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and.jsonld"}}