{"id":102071,"date":"2026-07-05T18:51:36","date_gmt":"2026-07-05T18:51:36","guid":{"rendered":"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/"},"modified":"2026-07-05T18:51:36","modified_gmt":"2026-07-05T18:51:36","slug":"llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools","status":"publish","type":"post","link":"https:\/\/youzum.net\/es\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/","title":{"rendered":"LlamaIndex \u2018legal-kb\u2019: Agentic Retrieval over Index v2 with retrieve, find, read, and grep Tools"},"content":{"rendered":"<p class=\"wp-block-paragraph\">LlamaIndex has published <code><a href=\"https:\/\/github.com\/run-llama\/legal-kb\" target=\"_blank\" rel=\"noreferrer noopener\">legal-kb<\/a><\/code>, 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.<\/p>\n<p class=\"wp-block-paragraph\">The 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.<\/p>\n<h2 class=\"wp-block-heading\"><strong>What is legal-kb?<\/strong><\/h2>\n<p class=\"wp-block-paragraph\"><code>legal-kb<\/code> is 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.<\/p>\n<h2 class=\"wp-block-heading\"><strong>The Retrieval Harness, in plain terms<\/strong><\/h2>\n<p class=\"wp-block-paragraph\">The 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.<\/p>\n<p class=\"wp-block-paragraph\">Those 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.<\/p>\n<h2 class=\"wp-block-heading\"><strong>The four agent tools<\/strong><\/h2>\n<p class=\"wp-block-paragraph\">The agent in <code>src\/lib\/agent.ts<\/code> is given four tools. Each maps to an Index v2 retrieval API. The table below lists them as implemented.<\/p>\n<figure class=\"wp-block-table\">\n<table class=\"has-fixed-layout\">\n<thead>\n<tr>\n<th>Tool<\/th>\n<th>Backing API<\/th>\n<th>Key parameters<\/th>\n<th>What it does<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>retrieve<\/code><\/td>\n<td><code>beta.retrieval.retrieve<\/code><\/td>\n<td><code>query<\/code>, <code>top_k<\/code>, <code>score_threshold<\/code>, <code>rerank_top_n<\/code>, <code>file_name<\/code>, <code>file_version<\/code><\/td>\n<td>Runs hybrid semantic search; optional reranking; returns chunks plus citations<\/td>\n<\/tr>\n<tr>\n<td><code>findFiles<\/code><\/td>\n<td><code>beta.retrieval.find<\/code><\/td>\n<td><code>file_name<\/code>, <code>file_name_contains<\/code><\/td>\n<td>Searches files by exact name or substring; paginates automatically<\/td>\n<\/tr>\n<tr>\n<td><code>readFile<\/code><\/td>\n<td><code>beta.retrieval.read<\/code><\/td>\n<td><code>file_id<\/code>, <code>offset<\/code>, <code>max_length<\/code><\/td>\n<td>Reads raw file content, with offset and length windows<\/td>\n<\/tr>\n<tr>\n<td><code>grepFile<\/code><\/td>\n<td><code>beta.retrieval.grep<\/code><\/td>\n<td><code>file_id<\/code>, <code>pattern<\/code>, <code>context_chars<\/code>, <code>limit<\/code><\/td>\n<td>Matches a pattern in one file; returns character positions<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<p class=\"wp-block-paragraph\">The system prompt enforces an order. The agent must call <code>findFiles<\/code> first to establish the document inventory. It then narrows with <code>retrieve<\/code>, and confirms exact wording with <code>readFile<\/code> or <code>grepFile<\/code> before citing.<\/p>\n<h2 class=\"wp-block-heading\"><strong>How it works under the hood<\/strong><\/h2>\n<p class=\"wp-block-paragraph\">Uploads follow a clear pipeline in <code>src\/lib\/files.ts<\/code>. Bytes are pushed to the project\u2019s LlamaCloud source directory. A <code>File<\/code> and <code>ProjectFile<\/code> row are written to PostgreSQL via Prisma. An index sync is triggered but not awaited; the UI polls status until ready.<\/p>\n<p class=\"wp-block-paragraph\">Versioning is scoped to the (project, filename) pair. Re-uploading <code>nda.pdf<\/code> to the same project produces v1, v2, v3 side by side. The retrieval layer filters on the <code>version<\/code> metadata field. This gives version control over the knowledge base itself.<\/p>\n<p class=\"wp-block-paragraph\">The agent uses the <code>ToolLoopAgent<\/code> from 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.<\/p>\n<p class=\"wp-block-paragraph\">Here is a condensed but faithful view of the <code>retrieve<\/code> tool and the agent.<\/p>\n<div class=\"dm-code-snippet dark dm-normal-version default no-background-mobile\">\n<div class=\"control-language\">\n<div class=\"dm-buttons\">\n<div class=\"dm-buttons-left\">\n<div class=\"dm-button-snippet red-button\"><\/div>\n<div class=\"dm-button-snippet orange-button\"><\/div>\n<div class=\"dm-button-snippet green-button\"><\/div>\n<\/div>\n<div class=\"dm-buttons-right\"><a><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\">Copied<\/span><span class=\"dm-error-message\">Use a different Browser<\/span><\/a><\/div>\n<\/div>\n<pre class=\"no-line-numbers\"><code class=\"no-wrap language-php\">import { 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 }) =&gt; {\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) =&gt; ({\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) =&gt; `### Result #${i + 1}nn${r.content.slice(0, 600)}`)\n        .join('nn---nn')\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:&lt;id&gt;`.',\n  })\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<p class=\"wp-block-paragraph\">Answers carry visual citations. Each retrieved chunk gets a short id, such as <code>cite:c7f2qa<\/code>. 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.<\/p>\n<h2 class=\"wp-block-heading\">Naive RAG vs the agentic Retrieval Harness<\/h2>\n<p class=\"wp-block-paragraph\">The harness is a different execution model from single-shot RAG. <strong>The comparison below focuses on behavior.<\/strong><\/p>\n<figure class=\"wp-block-table is-style-stripes\">\n<table class=\"has-fixed-layout\">\n<thead>\n<tr>\n<th>Dimension<\/th>\n<th>Naive \/ single-shot RAG<\/th>\n<th>Agentic Retrieval Harness (Index v2)<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Retrieval flow<\/td>\n<td>One vector search per query<\/td>\n<td>Multi-step tool loop: find \u2192 retrieve \u2192 read\/grep<\/td>\n<\/tr>\n<tr>\n<td>Search modes<\/td>\n<td>Vector similarity only<\/td>\n<td>Hybrid semantic search, keyword, and regex grep<\/td>\n<\/tr>\n<tr>\n<td>Context<\/td>\n<td>Fixed top-k chunks<\/td>\n<td>Agent reads full files or windows on demand<\/td>\n<\/tr>\n<tr>\n<td>Freshness<\/td>\n<td>Static index<\/td>\n<td>Persistent pipeline with sync and versioning<\/td>\n<\/tr>\n<tr>\n<td>Precision control<\/td>\n<td>Mostly hidden<\/td>\n<td><code>top_k<\/code>, <code>score_threshold<\/code>, <code>rerank_top_n<\/code> exposed<\/td>\n<\/tr>\n<tr>\n<td>Citations<\/td>\n<td>Chunk ids<\/td>\n<td>Visual citations with page screenshots and bboxes<\/td>\n<\/tr>\n<tr>\n<td>Best fit<\/td>\n<td>Short question answering<\/td>\n<td>Long-horizon document tasks<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<h2 class=\"wp-block-heading\"><strong>Use cases, with examples<\/strong><\/h2>\n<p class=\"wp-block-paragraph\">The design targets domains where agents navigate large document sets. Legal and fintech are the stated examples.<\/p>\n<ul class=\"wp-block-list\">\n<li>Consider a contract question: \u2018What notice is needed to terminate the MSA?\u2019 The agent lists files, runs <code>retrieve<\/code>, then greps the exact clause. It answers with a citation to the specific page.<\/li>\n<li>Consider due diligence across a data room: An agent can <code>findFiles<\/code> by name, then <code>readFile<\/code> each candidate. It cross-checks clauses without a human opening every PDF.<\/li>\n<li>Consider a versioned policy base: Because <code>retrieve<\/code> accepts a <code>file_version<\/code> filter, an agent can query a specific version. This supports change tracking over time.<\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\"><strong>Reference implementation<\/strong><\/h2>\n<p><!-- Marktechpost \u2014 Agentic Retrieval Harness interactive demo. Paste into a WordPress Custom HTML block. --><\/p>\n<div>\n  &lt;\/div&gt;<br \/>\n        &lt;div&gt;&lt;div class=&quot;&rdquo;fn&rdquo;&quot;&gt;Mutual_NDA.pdf&lt;span class=&quot;&rdquo;ver&rdquo;&quot;&gt;v2&lt;\/span&gt;&lt;\/div&gt;&lt;div class=&quot;&rdquo;meta&rdquo;&quot;&gt;parsed &middot; indexed &middot; ready&lt;\/div&gt;&lt;\/div&gt;<br \/>\n      &lt;\/div&gt;<br \/>\n      &lt;div class=&quot;&rdquo;file&rdquo;&quot; data-fn=&quot;&rdquo;MSA_Acme_Vendor.pdf&rdquo;&quot;&gt;<br \/>\n        &lt;div class=&quot;&rdquo;doc&rdquo;&quot;&gt;<img decoding=\"async\" src=\"https:\/\/s.w.org\/images\/core\/emoji\/17.0.2\/72x72\/1f4c4.png\" alt=\"\ud83d\udcc4\" class=\"wp-smiley\" \/>&lt;\/div&gt;<br \/>\n        &lt;div&gt;&lt;div class=&quot;&rdquo;fn&rdquo;&quot;&gt;MSA_Acme_Vendor.pdf&lt;span class=&quot;&rdquo;ver&rdquo;&quot;&gt;v1&lt;\/span&gt;&lt;\/div&gt;&lt;div class=&quot;&rdquo;meta&rdquo;&quot;&gt;parsed &middot; indexed &middot; ready&lt;\/div&gt;&lt;\/div&gt;<br \/>\n      &lt;\/div&gt;<br \/>\n      &lt;div class=&quot;&rdquo;file&rdquo;&quot; data-fn=&quot;&rdquo;Employment_Agreement.pdf&rdquo;&quot;&gt;<br \/>\n        &lt;div class=&quot;&rdquo;doc&rdquo;&quot;&gt;<img decoding=\"async\" src=\"https:\/\/s.w.org\/images\/core\/emoji\/17.0.2\/72x72\/1f4c4.png\" alt=\"\ud83d\udcc4\" class=\"wp-smiley\" \/>&lt;\/div&gt;<br \/>\n        &lt;div&gt;&lt;div class=&quot;&rdquo;fn&rdquo;&quot;&gt;Employment_Agreement.pdf&lt;span class=&quot;&rdquo;ver&rdquo;&quot;&gt;v1&lt;\/span&gt;&lt;\/div&gt;&lt;div class=&quot;&rdquo;meta&rdquo;&quot;&gt;parsed &middot; indexed &middot; ready&lt;\/div&gt;&lt;\/div&gt;<br \/>\n      &lt;\/div&gt;<br \/>\n      &lt;div class=&quot;&rdquo;tools&rdquo;&quot;&gt;<br \/>\n        &lt;h2&gt;Agent Tools&lt;\/h2&gt;<br \/>\n        &lt;div class=&quot;&rdquo;tool&rdquo;&quot;&gt;&lt;code&gt;retrieve&lt;\/code&gt; hybrid semantic search&lt;\/div&gt;<br \/>\n        &lt;div class=&quot;&rdquo;tool&rdquo;&quot;&gt;&lt;code&gt;findFiles&lt;\/code&gt; file search by name&lt;\/div&gt;<br \/>\n        &lt;div class=&quot;&rdquo;tool&rdquo;&quot;&gt;&lt;code&gt;readFile&lt;\/code&gt; read raw content&lt;\/div&gt;<br \/>\n        &lt;div class=&quot;&rdquo;tool&rdquo;&quot;&gt;&lt;code&gt;grepFile&lt;\/code&gt; regex pattern match&lt;\/div&gt;<br \/>\n      &lt;\/div&gt;<br \/>\n    &lt;\/div&gt;\n<p>    &lt;div class=&quot;&rdquo;main&rdquo;&quot;&gt;<br \/>\n      &lt;div class=&quot;&rdquo;chips&rdquo;&quot; id=&quot;&rdquo;chips&rdquo;&quot;&gt;&lt;\/div&gt;<br \/>\n      &lt;div class=&quot;&rdquo;feed&rdquo;&quot; id=&quot;&rdquo;feed&rdquo;&quot;&gt;<br \/>\n        &lt;div class=&quot;&rdquo;empty&rdquo;&quot; id=&quot;&rdquo;empty&rdquo;&quot;&gt;Pick a question above, or type your own. The agent always calls &lt;code&gt;findFiles&lt;\/code&gt; first to establish the document inventory, then narrows with &lt;code&gt;retrieve&lt;\/code&gt;, then confirms exact wording with &lt;code&gt;readFile&lt;\/code&gt; or &lt;code&gt;grepFile&lt;\/code&gt; before citing.&lt;\/div&gt;<br \/>\n      &lt;\/div&gt;<br \/>\n      &lt;div class=&quot;&rdquo;composer&rdquo;&quot;&gt;<br \/>\n        &lt;input id=&#8221;q&#8221; placeholder=&#8221;Ask about termination, non-compete, payment terms\u2026&#8221; autocomplete=&#8221;off&#8221;&gt;<br \/>\n        &lt;button id=&#8221;go&#8221;&gt;Run&lt;\/button&gt;<br \/>\n      &lt;\/div&gt;<br \/>\n    &lt;\/div&gt;<br \/>\n  &lt;\/div&gt;<\/p>\n<p>  &lt;div class=&quot;&rdquo;ftr&rdquo;&quot;&gt;<br \/>\n    &lt;div&gt;Interactive demo &middot; &lt;b&gt;Marktechpost&lt;\/b&gt; &mdash; modeled on run-llama\/legal-kb (Index v2 \/ LlamaParse Platform)&lt;\/div&gt;<br \/>\n    &lt;div&gt;&lt;a href=&quot;\/es\/&rdquo;https:\/\/github.com\/run-llama\/legal-kb&rdquo;\/&quot; target=&quot;&rdquo;_blank&rdquo;&quot; rel=&quot;&rdquo;noopener&rdquo;&quot;&gt;github.com\/run-llama\/legal-kb <img decoding=\"async\" src=\"https:\/\/s.w.org\/images\/core\/emoji\/17.0.2\/72x72\/2197.png\" alt=\"\u2197\" class=\"wp-smiley\" \/>&lt;\/a&gt;&lt;\/div&gt;<br \/>\n  &lt;\/div&gt;<\/p>\n<p>  &lt;div class=&quot;&rdquo;modal&rdquo;&quot; id=&quot;&rdquo;modal&rdquo;&quot;&gt;<br \/>\n    &lt;div class=&quot;&rdquo;card&rdquo;&quot;&gt;<br \/>\n      &lt;div class=&quot;&rdquo;ch&rdquo;&quot;&gt;&lt;div class=&quot;&rdquo;t&rdquo;&quot; id=&quot;&rdquo;mt&rdquo;&quot;&gt;Citation&lt;\/div&gt;&lt;div class=&quot;&rdquo;x&rdquo;&quot; id=&quot;&rdquo;mx&rdquo;&quot;&gt;\u2715&lt;\/div&gt;&lt;\/div&gt;<br \/>\n      &lt;div class=&quot;&rdquo;shot&rdquo;&quot; id=&quot;&rdquo;shot&rdquo;&quot;&gt;&lt;\/div&gt;<br \/>\n      &lt;div class=&quot;&rdquo;pv&rdquo;&quot;&gt;&lt;div class=&quot;&rdquo;lab&rdquo;&quot;&gt;Retrieved chunk&lt;\/div&gt;&lt;div id=&quot;&rdquo;mpv&rdquo;&quot;&gt;&lt;\/div&gt;&lt;\/div&gt;<br \/>\n    &lt;\/div&gt;<br \/>\n  &lt;\/div&gt;<br \/>\n&lt;\/div&gt;<\/p>\n<p>&lt;script&gt;<br \/>\n(function(){<br \/>\n  var root=document.getElementById(&#8216;mtp-harness&#8217;);<br \/>\n  \/\/ &#8212; Knowledge base (illustrative content) &#8212;<br \/>\n  var INTENTS=[{<br \/>\n    key:&#8217;termination&#8217;,kw:[&#8216;terminat&#8217;,&#8217;cancel&#8217;,&#8217;convenience&#8217;,&#8217;notice&#8217;,&#8217;end the contract&#8217;,&#8217;exit&#8217;],<br \/>\n    file:&#8217;MSA_Acme_Vendor.pdf&#8217;,ver:1,page:6,score:0.912,<br \/>\n    query:&#8217;termination rights and required notice period&#8217;,<br \/>\n    chunk:&#8217;Either party may terminate this Master Services Agreement for convenience upon thirty (30) days prior written notice. Termination for cause is effective immediately upon written notice of a material breach that remains uncured after fifteen (15) days.&#8217;,<br \/>\n    grep:&#8217;terminate this Master Services Agreement for convenience upon thirty (30) days&#8217;,<br \/>\n    answer:&#8217;The MSA allows either party to terminate for convenience with thirty (30) days prior written notice \u00a7CITE\u00a7. Termination for cause is immediate after an uncured material breach of fifteen (15) days \u00a7CITE2\u00a7.&#8217;,<br \/>\n    bbox:{x:14,y:38,w:78,h:20}<br \/>\n  },{<br \/>\n    key:&#8217;confidential&#8217;,kw:[&#8216;confidential&#8217;,&#8217;nda&#8217;,&#8217;term&#8217;,&#8217;how long&#8217;,&#8217;duration&#8217;,&#8217;secret&#8217;,&#8217;disclos&#8217;],<br \/>\n    file:&#8217;Mutual_NDA.pdf&#8217;,ver:2,page:2,score:0.934,<br \/>\n    query:&#8217;confidentiality obligations and survival term&#8217;,<br \/>\n    chunk:&#8217;The confidentiality obligations set forth herein shall survive for a period of three (3) years following the termination or expiration of this Agreement. Confidential Information excludes information that becomes publicly available through no fault of the receiving party.&#8217;,<br \/>\n    grep:&#8217;shall survive for a period of three (3) years following the termination&#8217;,<br \/>\n    answer:&#8217;Confidentiality obligations survive three (3) years after termination or expiration of the NDA \u00a7CITE\u00a7. Publicly available information is excluded from Confidential Information \u00a7CITE2\u00a7.&#8217;,<br \/>\n    bbox:{x:12,y:30,w:80,h:22}<br \/>\n  },{<br \/>\n    key:&#8217;payment&#8217;,kw:[&#8216;payment&#8217;,&#8217;net&#8217;,&#8217;invoice&#8217;,&#8217;pay&#8217;,&#8217;fees&#8217;,&#8217;billing&#8217;,&#8217;net 45&#8242;],<br \/>\n    file:&#8217;MSA_Acme_Vendor.pdf&#8217;,ver:1,page:4,score:0.897,<br \/>\n    query:&#8217;payment terms and invoicing schedule&#8217;,<br \/>\n    chunk:&#8217;Vendor shall invoice monthly in arrears. Undisputed invoices are payable within forty-five (45) days of receipt (Net 45). Late payments accrue interest at 1.0% per month or the maximum rate permitted by law, whichever is lower.&#8217;,<br \/>\n    grep:&#8217;payable within forty-five (45) days of receipt (Net 45)&#8217;,<br \/>\n    answer:&#8217;Undisputed invoices are payable Net 45, within forty-five (45) days of receipt \u00a7CITE\u00a7. Late payments accrue 1.0% monthly interest or the legal maximum \u00a7CITE2\u00a7.&#8217;,<br \/>\n    bbox:{x:14,y:34,w:76,h:18}<br \/>\n  },{<br \/>\n    key:&#8217;noncompete&#8217;,kw:[&#8216;non-compete&#8217;,&#8217;noncompete&#8217;,&#8217;compete&#8217;,&#8217;restrict&#8217;,&#8217;employ&#8217;,&#8217;12 month&#8217;],<br \/>\n    file:&#8217;Employment_Agreement.pdf&#8217;,ver:1,page:5,score:0.921,<br \/>\n    query:&#8217;non-compete restriction scope and duration&#8217;,<br \/>\n    chunk:&#8217;For twelve (12) months following the termination of employment, the Employee shall not engage in any business that directly competes with the Company within the territories where the Company actively operates.&#8217;,<br \/>\n    grep:&#8217;For twelve (12) months following the termination of employment&#8217;,<br \/>\n    answer:&#8217;The non-compete restricts the Employee for twelve (12) months after termination of employment \u00a7CITE\u00a7. It is limited to territories where the Company actively operates \u00a7CITE2\u00a7.&#8217;,<br \/>\n    bbox:{x:13,y:40,w:78,h:16}<br \/>\n  },{<br \/>\n    key:&#8217;liability&#8217;,kw:[&#8216;liabilit&#8217;,&#8217;cap&#8217;,&#8217;damages&#8217;,&#8217;indemnif&#8217;,&#8217;limitation&#8217;],<br \/>\n    file:&#8217;MSA_Acme_Vendor.pdf&#8217;,ver:1,page:8,score:0.905,<br \/>\n    query:&#8217;limitation of liability and damages cap&#8217;,<br \/>\n    chunk:&#8221;Each party&#8217;s aggregate liability under this Agreement shall not exceed the total fees paid or payable in the twelve (12) months preceding the claim. Neither party is liable for indirect, incidental, or consequential damages.&#8221;,<br \/>\n    grep:&#8217;aggregate liability under this Agreement shall not exceed the total fees&#8217;,<br \/>\n    answer:&#8217;Aggregate liability is capped at the fees paid or payable in the prior twelve (12) months \u00a7CITE\u00a7. Indirect, incidental, and consequential damages are excluded \u00a7CITE2\u00a7.&#8217;,<br \/>\n    bbox:{x:12,y:36,w:80,h:20}<br \/>\n  },{<br \/>\n    key:&#8217;governing&#8217;,kw:[&#8216;governing&#8217;,&#8217;law&#8217;,&#8217;jurisdiction&#8217;,&#8217;delaware&#8217;,&#8217;venue&#8217;,&#8217;court&#8217;],<br \/>\n    file:&#8217;Mutual_NDA.pdf&#8217;,ver:2,page:3,score:0.888,<br \/>\n    query:&#8217;governing law and jurisdiction clause&#8217;,<br \/>\n    chunk:&#8217;This Agreement shall be governed by and construed in accordance with the laws of the State of Delaware, without regard to its conflict-of-laws principles. The parties consent to exclusive jurisdiction in the state and federal courts located in Delaware.&#8217;,<br \/>\n    grep:&#8217;governed by and construed in accordance with the laws of the State of Delaware&#8217;,<br \/>\n    answer:&#8217;The NDA is governed by the laws of the State of Delaware \u00a7CITE\u00a7. The parties consent to exclusive jurisdiction in Delaware state and federal courts \u00a7CITE2\u00a7.&#8217;,<br \/>\n    bbox:{x:13,y:32,w:78,h:18}<br \/>\n  }];<\/p>\n<p>  var CHIPS=[<br \/>\n    [&#8216;How much notice is needed to terminate the MSA?&#8217;,&#8217;termination&#8217;],<br \/>\n    [&#8216;How long do confidentiality obligations last?&#8217;,&#8217;confidential&#8217;],<br \/>\n    [&#8216;What are the payment terms?&#8217;,&#8217;payment&#8217;],<br \/>\n    [&#8216;What is the non-compete duration?&#8217;,&#8217;noncompete&#8217;],<br \/>\n    [&#8216;What is the liability cap?&#8217;,&#8217;liability&#8217;],<br \/>\n    [&#8216;Which law governs the NDA?&#8217;,&#8217;governing&#8217;]<br \/>\n  ];<\/p>\n<p>  var feed=root.querySelector(&#8216;#feed&#8217;), empty=root.querySelector(&#8216;#empty&#8217;);<br \/>\n  var input=root.querySelector(&#8216;#q&#8217;), go=root.querySelector(&#8216;#go&#8217;);<br \/>\n  var chipWrap=root.querySelector(&#8216;#chips&#8217;);<br \/>\n  var busy=false;<\/p>\n<p>  CHIPS.forEach(function(c){<br \/>\n    var b=document.createElement(&#8216;div&#8217;);b.className=&#8217;chip&#8217;;b.textContent=c[0];<br \/>\n    b.onclick=function(){ if(!busy){ input.value=c[0]; run(c[1]); } };<br \/>\n    chipWrap.appendChild(b);<br \/>\n  });<\/p>\n<p>  function rid(){var s=&#8217;abcdef0123456789&#8242;,o=&#8217;c&#8217;;for(var i=0;i&lt;5;i++)o+=s[Math.floor(Math.random()*s.length)];return o;}<br \/>\n  function esc(t){return t.replace(\/&amp;\/g,&#8217;&amp;amp;&#8217;).replace(\/&lt;\/g,&#8217;&amp;lt;&#8217;).replace(\/&gt;\/g,&#8217;&amp;gt;&#8217;);}<\/p>\n<p>  function match(text){<br \/>\n    var t=text.toLowerCase(),best=null,hit=0;<br \/>\n    INTENTS.forEach(function(it){<br \/>\n      var c=0; it.kw.forEach(function(k){ if(t.indexOf(k)&gt;-1)c++; });<br \/>\n      if(c&gt;hit){hit=c;best=it;}<br \/>\n    });<br \/>\n    return best;<br \/>\n  }<\/p>\n<p>  function litFile(fn){<br \/>\n    root.querySelectorAll(&#8216;.file&#8217;).forEach(function(f){<br \/>\n      f.classList.toggle(&#8216;lit&#8217;, f.getAttribute(&#8216;data-fn&#8217;)===fn);<br \/>\n    });<br \/>\n  }<\/p>\n<p>  function addStep(cls,label,html,delay){<br \/>\n    return new Promise(function(res){<br \/>\n      setTimeout(function(){<br \/>\n        var s=document.createElement(&#8216;div&#8217;);s.className=&#8217;step&#8217;;<br \/>\n        s.innerHTML=&#039;&lt;div class=&quot;&rdquo;bubble&quot; &lsquo;+cls+&#039;&rdquo;&gt;&rsquo;+label+&#039;&lt;\/div&gt;&rsquo;+html;<br \/>\n        feed.appendChild(s); ping(); res();<br \/>\n      },delay);<br \/>\n    });<br \/>\n  }<\/p>\n<p>  var C1,C2;<br \/>\n  function run(forceKey){<br \/>\n    if(busy)return; busy=true; go.disabled=true;<br \/>\n    if(empty)empty.style.display=&#8217;none&#8217;;<br \/>\n    feed.innerHTML=&#8221;;<br \/>\n    var it = forceKey ? INTENTS.filter(function(x){return x.key===forceKey;})[0] : match(input.value||&#8221;);<br \/>\n    C1=rid(); C2=rid();<\/p>\n<p>    if(!it){<br \/>\n      addStep(&#8216;find&#8217;,&#8217;findFiles&#8217;,callHTML(&#8216;findFiles&#8217;,{},&#8217;3 files: Mutual_NDA.pdf (v2), MSA_Acme_Vendor.pdf (v1), Employment_Agreement.pdf (v1)&#8217;),150)<br \/>\n      .then(function(){ return addStep(&lsquo;ans&rsquo;,&rsquo;answer&rsquo;,&#039;&lt;div class=&quot;&rdquo;answer&rdquo;&quot;&gt;The indexed documents do not contain enough information to answer that. Try termination, confidentiality, payment terms, non-compete, liability, or governing law.&lt;\/div&gt;&rsquo;,700); })<br \/>\n      .then(done); return;<br \/>\n    }<\/p>\n<p>    litFile(it.file);<\/p>\n<p>    \/\/ 1) findFiles (always first)<br \/>\n    addStep(&#8216;find&#8217;,&#8217;findFiles&#8217;,callHTML(&#8216;findFiles&#8217;,{},&#8217;3 files listed \u00b7 &#8216;+it.file+&#8217; (v&#8217;+it.ver+&#8217;) is a candidate&#8217;),150)<br \/>\n    \/\/ 2) retrieve (hybrid search)<br \/>\n    .then(function(){ return addStep(&#8221;,&#8217;retrieve&#8217;,callHTML(&#8216;retrieve&#8217;,{query:it.query,top_k:5,rerank_top_n:3},null),820); })<br \/>\n    .then(function(){ return addStep(&#8221;,&#8217;results&#8217;,retrieveResults(it),780); })<br \/>\n    \/\/ 3) grep to confirm exact wording<br \/>\n    .then(function(){ return addStep(&#8216;grep&#8217;,&#8217;grepFile&#8217;,callHTML(&#8216;grepFile&#8217;,{file:it.file,pattern:it.grep.slice(0,32)+&#8217;\u2026&#8217;},&#8217;1 match confirmed on p.&#8217;+it.page),820); })<br \/>\n    \/\/ 4) grounded answer with citations<br \/>\n    .then(function(){ return addStep(&lsquo;ans&rsquo;,&rsquo;answer&rsquo;,&#039;&lt;div class=&quot;&rdquo;answer&rdquo;&quot;&gt;&rsquo;+answerHTML(it)+&#039;&lt;\/div&gt;&rsquo;,780); })<br \/>\n    .then(done);<br \/>\n  }<\/p>\n<p>  function done(){ busy=false; go.disabled=false; }<\/p>\n<p>  function callHTML(name,args,note){<br \/>\n    var a=Object.keys(args).map(function(k){<br \/>\n      var v=args[k];<br \/>\n      var val = typeof v===&rsquo;number&rsquo; ? &lsquo;&lt;span class=&quot;&rdquo;n&rdquo;&quot;&gt;&rsquo;+v+&#039;&lt;\/span&gt;&rsquo; : &lsquo;&lt;span class=&quot;&rdquo;s&rdquo;&quot;&gt;&rdquo;&lsquo;+esc(String(v))+&#039;&rdquo;&lt;\/span&gt;&rsquo;;<br \/>\n      return &lsquo;&lt;span class=&quot;&rdquo;k&rdquo;&quot;&gt;&rsquo;+k+&#039;&lt;\/span&gt;: &lsquo;+val;<br \/>\n    }).join(&lsquo;&lt;span class=&quot;&rdquo;dim&rdquo;&quot;&gt;, &lt;\/span&gt;&rsquo;);<br \/>\n    var line=&#039;&lt;div class=&quot;&rdquo;call&rdquo;&quot;&gt;&lt;span class=&quot;&rdquo;dim&rdquo;&quot;&gt;&rarr; tool&lt;\/span&gt; &lsquo;+name+&#039;(&lt;span class=&quot;&rdquo;dim&rdquo;&quot;&gt;{ &lt;\/span&gt;&rsquo;+a+&#039;&lt;span class=&quot;&rdquo;dim&rdquo;&quot;&gt; }&lt;\/span&gt;)&rsquo;;<br \/>\n    if(note) line+=&#039;&lt;br&gt;&lt;span class=&quot;&rdquo;dim&rdquo;&quot;&gt;\u2713 &lsquo;+esc(note)+&#039;&lt;\/span&gt;&rsquo;;<br \/>\n    line+=&#039;&lt;\/div&gt;&rsquo;;<br \/>\n    return line;<br \/>\n  }<\/p>\n<p>  function retrieveResults(it){<br \/>\n    var s2=(it.score-0.14).toFixed(3);<br \/>\n    var h=&#039;&lt;div class=&quot;&rdquo;result&rdquo;&quot;&gt;&rsquo;+<br \/>\n      &lsquo;&lt;div class=&quot;&rdquo;rrow&rdquo;&quot;&gt;&lt;div class=&quot;&rdquo;top&rdquo;&quot;&gt;&lt;span&gt;Result #1 &middot; &lsquo;+it.file+&rsquo; &middot; p.&rsquo;+it.page+&#039;&lt;\/span&gt;&lt;span class=&quot;&rdquo;score&rdquo;&quot;&gt;score &lsquo;+it.score.toFixed(3)+&rsquo; &middot; &lt;span class=&quot;&rdquo;cid&rdquo;&quot;&gt;cite:&rsquo;+C1+&#039;&lt;\/span&gt;&lt;\/span&gt;&lt;\/div&gt;&rsquo;+esc(it.chunk.slice(0,150))+&rsquo;&hellip;&lt;\/div&gt;&rsquo;+<br \/>\n      &lsquo;&lt;div class=&quot;&rdquo;rrow&rdquo;&quot;&gt;&lt;div class=&quot;&rdquo;top&rdquo;&quot;&gt;&lt;span&gt;Result #2 &middot; &lsquo;+it.file+&rsquo; &middot; p.&rsquo;+it.page+&#039;&lt;\/span&gt;&lt;span class=&quot;&rdquo;score&rdquo;&quot;&gt;score &lsquo;+s2+&rsquo; &middot; &lt;span class=&quot;&rdquo;cid&rdquo;&quot;&gt;cite:&rsquo;+C2+&#039;&lt;\/span&gt;&lt;\/span&gt;&lt;\/div&gt;&rsquo;+esc(it.chunk.slice(120,250))+&rsquo;&hellip;&lt;\/div&gt;&rsquo;+<br \/>\n      &lsquo;&lt;\/div&gt;&rsquo;;<br \/>\n    return h;<br \/>\n  }<\/p>\n<p>  function answerHTML(it){<br \/>\n    var html=esc(it.answer)<br \/>\n      .replace(&lsquo;&sect;CITE&sect;&rsquo;,&#039;&lt;span class=&quot;&rdquo;citechip&rdquo;&quot; data-c=&quot;&rdquo;1&Prime;&quot;&gt;cite:&rsquo;+C1+&#039;&lt;\/span&gt;&rsquo;)<br \/>\n      .replace(&lsquo;&sect;CITE2&sect;&rsquo;,&#039;&lt;span class=&quot;&rdquo;citechip&rdquo;&quot; data-c=&quot;&rdquo;2&Prime;&quot;&gt;cite:&rsquo;+C2+&#039;&lt;\/span&gt;&rsquo;);<br \/>\n    \/\/ stash for modal<br \/>\n    root._cur=it;<br \/>\n    return html;<br \/>\n  }<\/p>\n<p>  \/\/ citation modal<br \/>\n  var modal=root.querySelector(&#8216;#modal&#8217;), shot=root.querySelector(&#8216;#shot&#8217;),<br \/>\n      mpv=root.querySelector(&#8216;#mpv&#8217;), mt=root.querySelector(&#8216;#mt&#8217;);<br \/>\n  feed.addEventListener(&#8216;click&#8217;,function(e){<br \/>\n    var chip=e.target.closest(&#8216;.citechip&#8217;); if(!chip)return;<br \/>\n    var it=root._cur; if(!it)return;<br \/>\n    mt.textContent=it.file+&#8217; \u00b7 page &#8216;+it.page+&#8217; \u00b7 v&#8217;+it.ver;<br \/>\n    shot.innerHTML=&#039;&lt;div style=&quot;&rdquo;opacity:.55&Prime;&quot;&gt;&rsquo;+esc(it.chunk)+&#039;&lt;\/div&gt;&rsquo;+<br \/>\n      &lsquo;&lt;div class=&quot;&rdquo;bbox&rdquo;&quot; style=&quot;&rdquo;left:&rsquo;+it.bbox.x+&rsquo;%;top:&rsquo;+it.bbox.y+&rsquo;%;width:&rsquo;+it.bbox.w+&rsquo;%;height:&rsquo;+it.bbox.h+&rsquo;%&rdquo;&quot;&gt;&lt;\/div&gt;&rsquo;;<br \/>\n    mpv.textContent=it.chunk;<br \/>\n    modal.classList.add(&#8216;on&#8217;); ping();<br \/>\n  });<br \/>\n  root.querySelector(&#8216;#mx&#8217;).onclick=function(){modal.classList.remove(&#8216;on&#8217;);ping();};<br \/>\n  modal.onclick=function(e){ if(e.target===modal){modal.classList.remove(&#8216;on&#8217;);ping();} };<\/p>\n<p>  go.onclick=function(){ run(null); };<br \/>\n  input.addEventListener(&#8216;keydown&#8217;,function(e){ if(e.key===&#8217;Enter&#8217;)run(null); });<\/p>\n<p>  \/\/ auto-resize for WordPress embed<br \/>\n  function ping(){<br \/>\n    try{<br \/>\n      var h=document.getElementById(&#8216;mtp-harness&#8217;).offsetHeight+40;<br \/>\n      parent.postMessage({type:&#8217;mtp-harness-height&#8217;,height:h},&#8217;*&#8217;);<br \/>\n    }catch(e){}<br \/>\n  }<br \/>\n  window.addEventListener(&#8216;load&#8217;,ping);<br \/>\n  window.addEventListener(&#8216;resize&#8217;,ping);<br \/>\n  setTimeout(ping,300);<br \/>\n})();<br \/>\n&lt;\/script&gt;<br \/>\n&lt;\/body&gt;<br \/>\n&lt;\/html&gt;<br \/>\n&#8220;<br \/>\n    style=&#8221;width:100%;height:600px;border:0;overflow:hidden;&#8221;<br \/>\n    scrolling=&#8221;no&#8221;<br \/>\n    loading=&#8221;lazy&#8221;<br \/>\n    title=&#8221;Agentic Retrieval Harness \u2014 Interactive Demo&#8221;&gt;\n<\/p><\/div>\n<p class=\"wp-block-paragraph\">\n<h2 class=\"wp-block-heading\"><strong>Key Takeaways<\/strong><\/h2>\n<ul class=\"wp-block-list\">\n<li><code>legal-kb<\/code> is a public reference app showing agentic retrieval on LlamaIndex Index v2.<\/li>\n<li>The agent gets four filesystem-style tools: <code>retrieve<\/code> (hybrid search), <code>findFiles<\/code>, <code>readFile<\/code>, and <code>grepFile<\/code>.<\/li>\n<li>A persistent pipeline handles parsing, indexing, sync, and per-file version control.<\/li>\n<li>Answers include visual citations: page screenshots with bounding boxes over the cited text.<\/li>\n<li>The stack is TanStack Start, AI SDK 6, Prisma, and WorkOS, with per-user encrypted keys.<\/li>\n<\/ul>\n<\/p><p class=\"wp-block-paragraph\">\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n<\/p><p class=\"wp-block-paragraph\">\n<\/p><p class=\"wp-block-paragraph\">Check out the<strong>\u00a0<a href=\"https:\/\/github.com\/run-llama\/legal-kb\" target=\"_blank\" rel=\"noreferrer noopener\">GitHub Repo<\/a><\/strong>.<strong>\u00a0<\/strong>Also,\u00a0feel free to follow us on\u00a0<strong><a href=\"https:\/\/x.com\/intent\/follow?screen_name=marktechpost\" target=\"_blank\" rel=\"noreferrer noopener\"><mark>Twitter<\/mark><\/a><\/strong>\u00a0and don\u2019t forget to join our\u00a0<strong><a href=\"https:\/\/www.reddit.com\/r\/machinelearningnews\/\" target=\"_blank\" rel=\"noreferrer noopener\">150k+ML SubReddit<\/a><\/strong>\u00a0and Subscribe to\u00a0<strong><a href=\"https:\/\/www.aidevsignals.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">our Newsletter<\/a><\/strong>. Wait! are you on telegram?\u00a0<strong><a href=\"https:\/\/t.me\/machinelearningresearchnews\" target=\"_blank\" rel=\"noreferrer noopener\">now you can join us on telegram as well.<\/a><\/strong><\/p>\n<p class=\"wp-block-paragraph\">Need to partner with us for promoting your GitHub Repo OR Hugging Face Page OR Product Release OR Webinar etc.?\u00a0<strong><a href=\"https:\/\/forms.gle\/wbash1wF6efRj8G58\" target=\"_blank\" rel=\"noreferrer noopener\"><mark>Connect with us<\/mark><\/a><\/strong><\/p>\n<p>The post <a href=\"https:\/\/www.marktechpost.com\/2026\/07\/05\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/\">LlamaIndex \u2018legal-kb\u2019: Agentic Retrieval over Index v2 with retrieve, find, read, and grep Tools<\/a> appeared first on <a href=\"https:\/\/www.marktechpost.com\/\">MarkTechPost<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>LlamaIndex has published legal-kb, 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. The 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. What is legal-kb? legal-kb is 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. The Retrieval Harness, in plain terms The 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. Those 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. The four agent tools The agent in src\/lib\/agent.ts is given four tools. Each maps to an Index v2 retrieval API. The table below lists them as implemented. Tool Backing API Key parameters What it does 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 findFiles beta.retrieval.find file_name, file_name_contains Searches files by exact name or substring; paginates automatically readFile beta.retrieval.read file_id, offset, max_length Reads raw file content, with offset and length windows grepFile beta.retrieval.grep file_id, pattern, context_chars, limit Matches a pattern in one file; returns character positions The system prompt enforces an order. The agent must call findFiles first to establish the document inventory. It then narrows with retrieve, and confirms exact wording with readFile or grepFile before citing. How it works under the hood Uploads follow a clear pipeline in src\/lib\/files.ts. Bytes are pushed to the project\u2019s LlamaCloud source directory. A File and ProjectFile row are written to PostgreSQL via Prisma. An index sync is triggered but not awaited; the UI polls status until ready. Versioning is scoped to the (project, filename) pair. Re-uploading nda.pdf to the same project produces v1, v2, v3 side by side. The retrieval layer filters on the version metadata field. This gives version control over the knowledge base itself. The agent uses the ToolLoopAgent from 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. Here is a condensed but faithful view of the retrieve tool and the agent. Copy CodeCopiedUse a different Browser import { LlamaCloud } from &#8216;@llamaindex\/llama-cloud&#8217; import { tool, ToolLoopAgent } from &#8216;ai&#8217; import { z } from &#8216;zod&#8217; import { makeCitationId } from &#8216;.\/citations&#8217; \/\/ One tool closure per index. Wraps Index v2 retrieval APIs. function createLlamaParseTools(apiKey: string, projectId: string, indexId: string) { const client = new LlamaCloud({ apiKey }) const retrieve = tool({ description: &#8216;Run a semantic retrieval query against an index.&#8217;, inputSchema: z.object({ query: z.string(), top_k: z.number().nullable(), score_threshold: z.number().nullable(), rerank_top_n: z.number().nullable(), \/\/ set to enable reranking file_name: z.string().nullable(), \/\/ metadata filter file_version: z.number().nullable(), }), execute: async ({ query, top_k, score_threshold, rerank_top_n, file_name }) =&gt; { const custom_filters = file_name ? { file_name: { operator: &#8216;eq&#8217; as const, value: file_name } } : undefined const response = await client.beta.retrieval.retrieve({ index_id: indexId, project_id: projectId, query, top_k, score_threshold, rerank: rerank_top_n != null ? { enabled: true, top_n: rerank_top_n } : undefined, custom_filters, }) \/\/ Return a model-readable list plus citations that drive the UI chips. const citations = response.results.map((r) =&gt; ({ id: makeCitationId(), \/\/ e.g. &#8220;c7f2qa&#8221; fileName: r.metadata?.file_name, score: r.rerank_score ?? r.score ?? null, preview: r.content.slice(0, 500), })) const formatted = response.results .map((r, i) =&gt; `### Result #${i + 1}nn${r.content.slice(0, 600)}`) .join(&#8216;nn&#8212;nn&#8217;) return { formatted, citations } }, }) \/\/ findFiles \/ readFile \/ grepFile follow the same shape, backed by \/\/ client.beta.retrieval.find \/ .read \/ .grep return { retrieve \/* , findFiles, readFile, grepFile *\/ } } export function buildAgent(model, apiKey: string, projectId: string, indexId: string) { return new ToolLoopAgent({ model, tools: createLlamaParseTools(apiKey, projectId, indexId), instructions: &#8216;Always call findFiles first, ground every answer in the documents, &#8216; + &#8216;and cite ids inline as `cite:&lt;id&gt;`.&#8217;, }) } Answers carry visual citations. Each retrieved chunk gets a short id, such as cite:c7f2qa. 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. Naive RAG vs the agentic Retrieval Harness The harness is a different execution model from single-shot RAG. The comparison below focuses on behavior. Dimension Naive \/ single-shot RAG Agentic Retrieval Harness (Index v2) Retrieval flow One vector search per query Multi-step tool loop: find \u2192 retrieve \u2192 read\/grep Search modes Vector similarity only Hybrid semantic search, keyword, and regex grep Context Fixed top-k chunks Agent reads full files or windows on demand Freshness Static index Persistent pipeline with sync and versioning Precision control Mostly hidden top_k, score_threshold, rerank_top_n exposed Citations Chunk ids Visual citations with page screenshots and bboxes Best fit Short question answering Long-horizon document tasks Use cases, with examples The design targets domains where agents navigate large document sets. Legal and fintech are the stated examples. Consider a contract question: \u2018What notice is needed to terminate the MSA?\u2019 The agent lists files, runs retrieve, then greps the exact clause. It answers with a citation to the specific page. Consider due diligence across a data room: An agent can findFiles by name, then readFile each candidate. It cross-checks clauses without a human opening every PDF. Consider a versioned policy base:<\/p>","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"pmpro_default_level":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"_pvb_checkbox_block_on_post":false,"footnotes":""},"categories":[52,5,7,1],"tags":[],"class_list":["post-102071","post","type-post","status-publish","format-standard","hentry","category-ai-club","category-committee","category-news","category-uncategorized","pmpro-has-access"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v25.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>LlamaIndex \u2018legal-kb\u2019: Agentic Retrieval over Index v2 with retrieve, find, read, and grep Tools - YouZum<\/title>\n<meta name=\"description\" content=\"\u0e01\u0e34\u0e08\u0e01\u0e23\u0e23\u0e21\u0e40\u0e01\u0e35\u0e48\u0e22\u0e27\u0e01\u0e31\u0e1a\u0e42\u0e14\u0e23\u0e19\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/youzum.net\/es\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"LlamaIndex \u2018legal-kb\u2019: Agentic Retrieval over Index v2 with retrieve, find, read, and grep Tools - YouZum\" \/>\n<meta property=\"og:description\" content=\"\u0e01\u0e34\u0e08\u0e01\u0e23\u0e23\u0e21\u0e40\u0e01\u0e35\u0e48\u0e22\u0e27\u0e01\u0e31\u0e1a\u0e42\u0e14\u0e23\u0e19\" \/>\n<meta property=\"og:url\" content=\"https:\/\/youzum.net\/es\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/\" \/>\n<meta property=\"og:site_name\" content=\"YouZum\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/DroneAssociationTH\/\" \/>\n<meta property=\"article:published_time\" content=\"2026-07-05T18:51:36+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/s.w.org\/images\/core\/emoji\/17.0.2\/72x72\/1f4c4.png\" \/>\n<meta name=\"author\" content=\"admin NU\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin NU\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tiempo de lectura\" \/>\n\t<meta name=\"twitter:data2\" content=\"17 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/\"},\"author\":{\"name\":\"admin NU\",\"@id\":\"https:\/\/yousum.gpucore.co\/#\/schema\/person\/97fa48242daf3908e4d9a5f26f4a059c\"},\"headline\":\"LlamaIndex \u2018legal-kb\u2019: Agentic Retrieval over Index v2 with retrieve, find, read, and grep Tools\",\"datePublished\":\"2026-07-05T18:51:36+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/\"},\"wordCount\":2928,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/yousum.gpucore.co\/#organization\"},\"image\":{\"@id\":\"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/s.w.org\/images\/core\/emoji\/17.0.2\/72x72\/1f4c4.png\",\"articleSection\":[\"AI\",\"Committee\",\"News\",\"Uncategorized\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/\",\"url\":\"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/\",\"name\":\"LlamaIndex \u2018legal-kb\u2019: Agentic Retrieval over Index v2 with retrieve, find, read, and grep Tools - YouZum\",\"isPartOf\":{\"@id\":\"https:\/\/yousum.gpucore.co\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/s.w.org\/images\/core\/emoji\/17.0.2\/72x72\/1f4c4.png\",\"datePublished\":\"2026-07-05T18:51:36+00:00\",\"description\":\"\u0e01\u0e34\u0e08\u0e01\u0e23\u0e23\u0e21\u0e40\u0e01\u0e35\u0e48\u0e22\u0e27\u0e01\u0e31\u0e1a\u0e42\u0e14\u0e23\u0e19\",\"breadcrumb\":{\"@id\":\"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/#primaryimage\",\"url\":\"https:\/\/s.w.org\/images\/core\/emoji\/17.0.2\/72x72\/1f4c4.png\",\"contentUrl\":\"https:\/\/s.w.org\/images\/core\/emoji\/17.0.2\/72x72\/1f4c4.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/youzum.net\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"LlamaIndex \u2018legal-kb\u2019: Agentic Retrieval over Index v2 with retrieve, find, read, and grep Tools\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/yousum.gpucore.co\/#website\",\"url\":\"https:\/\/yousum.gpucore.co\/\",\"name\":\"YouSum\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/yousum.gpucore.co\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/yousum.gpucore.co\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/yousum.gpucore.co\/#organization\",\"name\":\"Drone Association Thailand\",\"url\":\"https:\/\/yousum.gpucore.co\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/yousum.gpucore.co\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/youzum.net\/wp-content\/uploads\/2024\/11\/tranparent-logo.png\",\"contentUrl\":\"https:\/\/youzum.net\/wp-content\/uploads\/2024\/11\/tranparent-logo.png\",\"width\":300,\"height\":300,\"caption\":\"Drone Association Thailand\"},\"image\":{\"@id\":\"https:\/\/yousum.gpucore.co\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/DroneAssociationTH\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/yousum.gpucore.co\/#\/schema\/person\/97fa48242daf3908e4d9a5f26f4a059c\",\"name\":\"admin NU\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/yousum.gpucore.co\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/youzum.net\/wp-content\/uploads\/avatars\/2\/1746849356-bpfull.png\",\"contentUrl\":\"https:\/\/youzum.net\/wp-content\/uploads\/avatars\/2\/1746849356-bpfull.png\",\"caption\":\"admin NU\"},\"url\":\"https:\/\/youzum.net\/es\/members\/adminnu\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"LlamaIndex \u2018legal-kb\u2019: Agentic Retrieval over Index v2 with retrieve, find, read, and grep Tools - YouZum","description":"\u0e01\u0e34\u0e08\u0e01\u0e23\u0e23\u0e21\u0e40\u0e01\u0e35\u0e48\u0e22\u0e27\u0e01\u0e31\u0e1a\u0e42\u0e14\u0e23\u0e19","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/youzum.net\/es\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/","og_locale":"es_ES","og_type":"article","og_title":"LlamaIndex \u2018legal-kb\u2019: Agentic Retrieval over Index v2 with retrieve, find, read, and grep Tools - YouZum","og_description":"\u0e01\u0e34\u0e08\u0e01\u0e23\u0e23\u0e21\u0e40\u0e01\u0e35\u0e48\u0e22\u0e27\u0e01\u0e31\u0e1a\u0e42\u0e14\u0e23\u0e19","og_url":"https:\/\/youzum.net\/es\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/","og_site_name":"YouZum","article_publisher":"https:\/\/www.facebook.com\/DroneAssociationTH\/","article_published_time":"2026-07-05T18:51:36+00:00","og_image":[{"url":"https:\/\/s.w.org\/images\/core\/emoji\/17.0.2\/72x72\/1f4c4.png","type":"","width":"","height":""}],"author":"admin NU","twitter_card":"summary_large_image","twitter_misc":{"Escrito por":"admin NU","Tiempo de lectura":"17 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/#article","isPartOf":{"@id":"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/"},"author":{"name":"admin NU","@id":"https:\/\/yousum.gpucore.co\/#\/schema\/person\/97fa48242daf3908e4d9a5f26f4a059c"},"headline":"LlamaIndex \u2018legal-kb\u2019: Agentic Retrieval over Index v2 with retrieve, find, read, and grep Tools","datePublished":"2026-07-05T18:51:36+00:00","mainEntityOfPage":{"@id":"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/"},"wordCount":2928,"commentCount":0,"publisher":{"@id":"https:\/\/yousum.gpucore.co\/#organization"},"image":{"@id":"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/#primaryimage"},"thumbnailUrl":"https:\/\/s.w.org\/images\/core\/emoji\/17.0.2\/72x72\/1f4c4.png","articleSection":["AI","Committee","News","Uncategorized"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/","url":"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/","name":"LlamaIndex \u2018legal-kb\u2019: Agentic Retrieval over Index v2 with retrieve, find, read, and grep Tools - YouZum","isPartOf":{"@id":"https:\/\/yousum.gpucore.co\/#website"},"primaryImageOfPage":{"@id":"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/#primaryimage"},"image":{"@id":"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/#primaryimage"},"thumbnailUrl":"https:\/\/s.w.org\/images\/core\/emoji\/17.0.2\/72x72\/1f4c4.png","datePublished":"2026-07-05T18:51:36+00:00","description":"\u0e01\u0e34\u0e08\u0e01\u0e23\u0e23\u0e21\u0e40\u0e01\u0e35\u0e48\u0e22\u0e27\u0e01\u0e31\u0e1a\u0e42\u0e14\u0e23\u0e19","breadcrumb":{"@id":"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/#primaryimage","url":"https:\/\/s.w.org\/images\/core\/emoji\/17.0.2\/72x72\/1f4c4.png","contentUrl":"https:\/\/s.w.org\/images\/core\/emoji\/17.0.2\/72x72\/1f4c4.png"},{"@type":"BreadcrumbList","@id":"https:\/\/youzum.net\/llamaindex-legal-kb-agentic-retrieval-over-index-v2-with-retrieve-find-read-and-grep-tools\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/youzum.net\/"},{"@type":"ListItem","position":2,"name":"LlamaIndex \u2018legal-kb\u2019: Agentic Retrieval over Index v2 with retrieve, find, read, and grep Tools"}]},{"@type":"WebSite","@id":"https:\/\/yousum.gpucore.co\/#website","url":"https:\/\/yousum.gpucore.co\/","name":"YouSum","description":"","publisher":{"@id":"https:\/\/yousum.gpucore.co\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/yousum.gpucore.co\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/yousum.gpucore.co\/#organization","name":"Drone Association Thailand","url":"https:\/\/yousum.gpucore.co\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/yousum.gpucore.co\/#\/schema\/logo\/image\/","url":"https:\/\/youzum.net\/wp-content\/uploads\/2024\/11\/tranparent-logo.png","contentUrl":"https:\/\/youzum.net\/wp-content\/uploads\/2024\/11\/tranparent-logo.png","width":300,"height":300,"caption":"Drone Association Thailand"},"image":{"@id":"https:\/\/yousum.gpucore.co\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/DroneAssociationTH\/"]},{"@type":"Person","@id":"https:\/\/yousum.gpucore.co\/#\/schema\/person\/97fa48242daf3908e4d9a5f26f4a059c","name":"admin NU","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/yousum.gpucore.co\/#\/schema\/person\/image\/","url":"https:\/\/youzum.net\/wp-content\/uploads\/avatars\/2\/1746849356-bpfull.png","contentUrl":"https:\/\/youzum.net\/wp-content\/uploads\/avatars\/2\/1746849356-bpfull.png","caption":"admin NU"},"url":"https:\/\/youzum.net\/es\/members\/adminnu\/"}]}},"rttpg_featured_image_url":null,"rttpg_author":{"display_name":"admin NU","author_link":"https:\/\/youzum.net\/es\/members\/adminnu\/"},"rttpg_comment":0,"rttpg_category":"<a href=\"https:\/\/youzum.net\/es\/category\/ai-club\/\" rel=\"category tag\">AI<\/a> <a href=\"https:\/\/youzum.net\/es\/category\/committee\/\" rel=\"category tag\">Committee<\/a> <a href=\"https:\/\/youzum.net\/es\/category\/news\/\" rel=\"category tag\">News<\/a> <a href=\"https:\/\/youzum.net\/es\/category\/uncategorized\/\" rel=\"category tag\">Uncategorized<\/a>","rttpg_excerpt":"LlamaIndex has published legal-kb, 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. The approach differs from single-shot retrieval. Instead of one embedding search per query,&hellip;","_links":{"self":[{"href":"https:\/\/youzum.net\/es\/wp-json\/wp\/v2\/posts\/102071","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/youzum.net\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/youzum.net\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/youzum.net\/es\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/youzum.net\/es\/wp-json\/wp\/v2\/comments?post=102071"}],"version-history":[{"count":0,"href":"https:\/\/youzum.net\/es\/wp-json\/wp\/v2\/posts\/102071\/revisions"}],"wp:attachment":[{"href":"https:\/\/youzum.net\/es\/wp-json\/wp\/v2\/media?parent=102071"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/youzum.net\/es\/wp-json\/wp\/v2\/categories?post=102071"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/youzum.net\/es\/wp-json\/wp\/v2\/tags?post=102071"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}