去中心化 AI 知识库搭建实战:基于 Chroma 向量数据库与 IPFS 的链上 RAG 原型
·
去中心化 AI 知识库搭建实战:基于 Chroma 向量数据库与 IPFS 的链上 RAG 原型

在构建专属垂直领域的 AI Agent(如智能合约漏洞库问答、DeFi 协议治理提案解读)时,检索增强生成(RAG, Retrieval-Augmented Generation)是提升回答专业度、彻底杜绝大模型幻觉的核心武器。
然而,传统的 RAG 系统严重依赖中心化云存储(如 AWS S3),文档随时面临被单点删除或篡改的风险,且缺乏透明可信的内容溯源链条。
本文复盘如何将 IPFS 去中心化内容寻址 与 Chroma 本地嵌入式向量数据库 结合,打造一套支持密码学存证、端到端可验证的“去中心化 RAG 知识库原型”。
一、去中心化 RAG 架构数据流图
graph TD
Docs[原始白皮书 / 审计报告 / EIP 规范 Markdown] --> Hash[计算 SHA-256 并上传至 IPFS]
Hash --> IPFSNode[获取不可篡改 IPFS CID: QmXyz...]
Docs --> Chunk[文本分块器: 递归字符分割 RecursiveCharacterTextSplitter]
Chunk --> Embed[Embedding 模型: text-embedding-3-small (1536 维)]
Embed --> Chroma[(Chroma 向量数据库: 存储 Vector + Metadata: ipfs_cid & line_range)]
Query[用户提问 Prompt] --> VectorSearch[Chroma 语义相似度 Top-K 检索]
VectorSearch --> AugmentedPrompt[拼接带可信 IPFS 溯源链接的 Context]
AugmentedPrompt --> LLM[大语言模型流式输出答案]
二、核心代码实现:从 IPFS 分块入库到语义召回
1. 文档入库与 IPFS 向量化管线
// rag/indexer.ts
import { ChromaClient } from 'chromadb';
import { OpenAIEmbeddings } from '@langchain/openai';
import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter';
import { create } from 'kubo-rpc-client';
const ipfs = create({ url: 'https://ipfs.infura.io:5001/api/v0' });
const chroma = new ChromaClient({ path: 'http://localhost:8000' });
const embeddings = new OpenAIEmbeddings({ modelName: 'text-embedding-3-small' });
export async function indexDocumentToDecentralizedRAG(docTitle: string, rawMarkdown: string) {
// 1. 将源文档发布至 IPFS,获得唯一的密码学内容哈希
const { cid } = await ipfs.add(rawMarkdown);
const ipfsCidStr = cid.toString();
console.log(`[IPFS Pinned] Document "${docTitle}" CID: ${ipfsCidStr}`);
// 2. 文本分块 (Chunk Size = 500 chars, Overlap = 50 chars)
const splitter = new RecursiveCharacterTextSplitter({
chunkSize: 500,
chunkOverlap: 50,
});
const chunks = await splitter.splitText(rawMarkdown);
// 3. 批量生成向量嵌入
const vectorEmbeddings = await embeddings.embedDocuments(chunks);
// 4. 存入 Chroma 向量集合并附加 IPFS 溯源元数据
const collection = await chroma.getOrCreateCollection({ name: 'web3_security_knowledge' });
const ids = chunks.map((_, i) => `${ipfsCidStr}-chunk-${i}`);
const metadatas = chunks.map((_, i) => ({
docTitle,
ipfsCid: ipfsCidStr,
chunkIndex: i,
ipfsViewerUrl: `https://ipfs.io/ipfs/${ipfsCidStr}`,
}));
await collection.add({
ids,
embeddings: vectorEmbeddings,
documents: chunks,
metadatas,
});
console.log(`[RAG Ready] Successfully indexed ${chunks.length} chunks for ${docTitle}`);
}
2. 结合可信溯源上下文的检索与问答
// rag/query.ts
import { ChromaClient } from 'chromadb';
import { OpenAIEmbeddings } from '@langchain/openai';
const chroma = new ChromaClient({ path: 'http://localhost:8000' });
const embeddings = new OpenAIEmbeddings({ modelName: 'text-embedding-3-small' });
export async function queryDecentralizedKnowledge(userPrompt: string) {
const collection = await chroma.getCollection({ name: 'web3_security_knowledge' });
// 1. 将用户提问转换为查询向量
const queryVector = await embeddings.embedQuery(userPrompt);
// 2. 检索语义最相关的 Top-3 知识片段
const searchResults = await collection.query({
queryEmbeddings: [queryVector],
nResults: 3,
});
const docs = searchResults.documents[0];
const metas = searchResults.metadatas[0];
// 3. 构造包含可信溯源引用的 Context
let contextText = '';
const citations: Array<{ title: string; ipfsUrl: string }> = [];
docs.forEach((doc, idx) => {
const meta = metas[idx] as any;
contextText += `[Document ${idx + 1} (来源: ${meta.docTitle})]:\n${doc}\n\n`;
citations.push({
title: meta.docTitle,
ipfsUrl: meta.ipfsViewerUrl,
});
});
// 4. 返回增强后的上下文与溯源清单
return {
augmentedContext: contextText,
citations,
};
}
三、极客调优与去中心化落地经验
- 向量维度的余弦距离(Cosine Distance)阈值裁剪:
在检索结果返回时,务必计算distance < 0.35的强相关过滤。对于低相关度的噪点片段直接丢弃,防止无关上下文污染 Prompt。 - IPFS 内容网关超时与双重缓存:
当用户在前端点击溯源链接查看原始 Markdown 白皮书时,公共 IPFS 网关有时会出现数十秒的加载延迟。在前端配置多节点 Fallback 策略(如优先尝试 Cloudflare IPFS Gateway,失败后切换至 Pinata Gateway)。 - 不可篡改的版本化迭代:
当协议白皮书发生版本升级时,旧版本的内容仍然保留在旧 CID 下,新版本生成新 CID,天然形成了清晰可比对的“历史版本知识演进树”。
通过 IPFS 的物理不可篡改性与向量检索的高效语义召回,我们打造了一套既聪明绝顶、又言之有据的去中心化可信知识引擎。
更多推荐


所有评论(0)