LlamaIndex ‘legal-kb’: Agentic Retrieval over Index v2 with retrieve, find, read, and grep Tools

Editor
2 Min Read


import { LlamaCloud } from '@llamaindex/llama-cloud'
import { tool, ToolLoopAgent } from 'ai'
import { z } from 'zod'
import { makeCitationId } from './citations'

// 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: 'Run a semantic retrieval query against an index.',
    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 }) => {
      const custom_filters = file_name
        ? { file_name: { operator: 'eq' 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) => ({
        id: makeCitationId(),                    // e.g. "c7f2qa"
        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) => `### Result #${i + 1}\n\n${r.content.slice(0, 600)}`)
        .join('\n\n---\n\n')
      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:
      'Always call findFiles first, ground every answer in the documents, ' +
      'and cite ids inline as `cite:<id>`.',
  })
}
Share this Article
Please enter CoinGecko Free Api Key to get this plugin works.