LlamaIndex 发布 legal-kb:基于 Index v2 的智能体检索参考应用
LlamaIndex ‘legal-kb’: Agentic Retrieval over Index v2 with retrieve, find, read, and grep Tools
LlamaIndex 发布 legal-kb,一个基于 Index v2(LlamaParse Platform)的法律文档知识库参考应用。采用 Retrieval Harness 模式,赋予 Agent 四个文件系统风格工具:retrieve(混合语义检索,支持 rerank 和引用)、findFiles(精确/模糊文件名搜索)、readFile(带偏移量的原始内容读取)和 grepFile(正则匹配并返回字符位置)。Agent 需先调用 findFiles 确定文件清单,再依次使用其他工具定位内容。底层基于 Vercel AI SDK 6 的 ToolLoopAgent,可选用 OpenAI 或 Anthropic 模型,支持用户自带 API key。项目以 TanStack Start web app 形式运行,上传文件自动解析索引,同一文件名重复上传可产生版本,检索时通过版本元数据字段过滤。
LlamaIndex 把 RAG 从一次搜索变成了‘先找文件、再搜、再读、再 grep’的多步循环,对做合同审查、尽调的团队来说是个可抄的模板。
LlamaIndex 发布了 legal-kb,这是一个托管在 GitHub 上的公开参考应用。它被描述为一个面向法律文档的知识库,由 LlamaIndex Index v2(即 LlamaParse 平台)驱动。该项目展示了一种团队称之为“检索 Harness”(Retrieval Harness)的模式,用于智能体式检索。
该方法不同于单次检索。它不是对每个查询执行一次嵌入向量搜索,而是为智能体提供文件系统风格的工具。智能体随后可以爬取一个庞大且不断演进的知识库来完成任务。这些工具与工程师们已经熟悉的操作相对应:语义搜索与关键词搜索、正则 grep、文件搜索以及读取。
什么是 legal-kb?
legal-kb 是一个可运行的 TanStack Start Web 应用,而不是一个库。你可以登录、创建项目、上传文件,并与智能体对话。每个项目都会以托管的 LlamaCloud Index v2 形式进行镜像。上传的文件会在后台自动解析并建立索引。随后,对话智能体在每一轮对话中都会实时查询该索引。
用通俗的话说,检索 Harness 是什么
该 Harness 在你的文档之上提供了一条持久化的数据管道。它连接到数据源,为其建立索引,并保持其更新。在这条管道之上,它向智能体暴露了一组工具。
这些工具有意设计得贴近文件系统操作。智能体可以列出文件、读取文件、在文件内执行 grep,或运行混合搜索。由于这些工具是通用的,你可以将该 Harness 接入你自己的智能体。
四个智能体工具
src/lib/agent.ts 中的智能体被赋予四个工具。每个工具对应一个 Index v2 检索 API。下表列出了它们按实现方式的情况。
| 工具 | 支撑 API | 关键参数 | 功能说明 |
|---|---|---|---|
retrieve | beta.retrieval.retrieve | query、top_k、score_threshold、rerank_top_n、file_name、file_version | 运行混合语义搜索;可选重排序;返回文本块及引用 |
findFiles | beta.retrieval.find | file_name、file_name_contains | 按精确名称或子字符串搜索文件;自动分页 |
readFile | beta.retrieval.read | file_id、offset、max_length | 读取原始文件内容,支持偏移量和长度窗口 |
grepFile | beta.retrieval.grep | file_id、pattern、context_chars、limit | 在单个文件中匹配某个模式;返回字符位置 |
系统提示词强制规定了一个顺序。智能体必须先调用 findFiles 来建立文档清单。随后用 retrieve 缩小范围,并在引用之前用 readFile 或 grepFile 确认确切措辞。
底层工作原理
在 src/lib/files.ts 中,上传遵循一条清晰的流水线。字节被推送到项目的 LlamaCloud 源目录。一条 File 和 ProjectFile 记录通过 Prisma 写入 PostgreSQL。索引同步被触发但不等待其完成;UI 轮询状态直到就绪。
版本控制以(项目、文件名)对为范围。将 nda.pdf 重新上传到同一项目会并排生成 v1、v2、v3。检索层根据 version 元数据字段进行过滤。这为知识库本身提供了版本控制。
该智能体使用了来自 Vercel AI SDK 6 的 ToolLoopAgent。每一轮你可以选择 OpenAI 或 Anthropic,并自带密钥。推理过程以流式输出:Claude 模型使用扩展思考;OpenAI 推理模型使用中等推理强度。
以下是对 retrieve 工具和该智能体的精简但忠实的呈现。
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>`.',
})
}回答带有可视化引用。每个检索到的文本块都会获得一个短 id,例如 cite:c7f2qa。智能体会在行内引用该 id,UI 则渲染出一个可点击的引用标签。点击它会打开来源页面截图,并在被引用的文本上叠加边界框矩形。
朴素 RAG 与智能体式检索 Harness 对比
该 harness 与单次 RAG 是截然不同的执行模型。下面的对比聚焦于行为表现。
| 维度 | 朴素 / 单次 RAG | 智能体式检索 Harness(Index v2) |
|---|---|---|
| 检索流程 | 每次查询一次向量搜索 | 多步工具循环:查找 → 检索 → 读取/grep |
| 搜索模式 | 仅向量相似度 | 混合语义搜索、关键词与正则 grep |
| 上下文 | 固定的 top-k 分块 | 智能体按需读取完整文件或窗口 |
| 新鲜度 | 静态索引 | 带同步与版本管理的持久化流水线 |
| 精度控制 | 大多隐藏 | top_k、score_threshold、rerank_top_n 暴露 |
| 引用 | 分块 id | 带页面截图和 bboxes 的可视化引用 |
| 最佳适配 | 简短问答 | 长周期文档任务 |
用例,附示例
该设计面向智能体需要浏览大规模文档集的领域。文中给出的示例是法律和金融科技。
- 设想一个合同问题:“终止 MSA 需要什么通知?”智能体列出文件,运行
retrieve,然后 grep 精确的条款。它给出答案并引用具体页面。 - 设想在数据室中进行尽职调查:智能体可以按名称
findFiles,然后对每个候选对象readFile。它交叉核对条款,无需人工打开每一个 PDF。 - 设想一个带版本的政策库:由于
retrieve接受file_version过滤器,智能体可以查询特定版本。这支持随时间进行变更追踪。
参考实现
核心要点
legal-kb是一个公开的参考应用,展示了基于 LlamaIndex Index v2 的智能体检索。- 该智能体获得四个文件系统风格的工具:
retrieve(混合搜索)、findFiles、readFile和grepFile。 - 一条持久化流水线负责解析、索引、同步以及按文件粒度的版本控制。
- 回答包含可视化引用:带有引用文本边界框的页面截图。
- 技术栈为 TanStack Start、AI SDK 6、Prisma 和 WorkOS,并采用按用户加密的密钥。
来源:MarkTechPost(RSS) · marktechpost.com