类低代码平台Agent开发实践:文档助手从零入门到精通实战指南
摘要
类低代码平台Agent开发中,文档助手通过RAG流程实现智能问答。技术选型采用ChromaDB向量库
最近正在开发仿真平台的Agent功能,越做越发现,这个场景的设计思路与大多数低代码平台高度相似。因此,这里分享一下我的实践方法,将Agent的核心能力拆分为两大块:文档助手与智能生成。

本文先聚焦文档助手模块。
文档助手
低代码平台通常配置项繁多、操作手册厚重、案例库庞杂——这正是智能文档助手最能简化开发过程、提升查询效率的切入点。
技术选型
在RAG技术栈中,向量数据库选择了ChromaDB,兼顾稳定性与轻量化部署。
import { Chroma } from "@langchain/community/vectorstores/chroma";
function getVectorStore(): Promise<Chroma> {
if (vectorStore) {
return vectorStore;
}
vectorStore = new Chroma(embeddings, {
collectionName: COLLECTION_NAME,
url: `http://${config.chromaHost}:${config.chromaPort}`,
});
return vectorStore;
}
ChromaDB 内置的默认嵌入模型是 all-MiniLM-L6-v2,但我替换为 Qwen3-Embedding-8B,它对中文语义的理解和检索准确度明显更优。如果知识库包含大量图片或图表,可考虑 Qwen3-VL-Embedding-8B 多模态模型——不过部署门槛较高,要么调用阿里云API,要么自备高性能机器本地运行,Ollama 目前还不支持这类多模态嵌入模型。
import { OpenAIEmbeddings } from "@langchain/openai";
import { config } from "../config/index.js";
export const embeddings = new OpenAIEmbeddings({
model: config.embeddingModel,
batchSize: 8,
timeout: 300_000,
configuration: {
baseURL: config.embeddingBaseUrl,
},
});
RAG 流程
RAG的标准管线通常包含五个环节:文档加载 → 文本分块 → 向量嵌入 → 向量存储 → 语义检索。下面逐一拆解实现细节。
载入文档
function loadDocuments(): Promise<Document[]> {
const files = await getFiles(DOCS_PATH);
const documents: Document[] = [];
for (const file of files) {
const rawContent = await readFile(file, 'utf-8');
// 非纯文本格式(如Excel、HTML)需转为纯文本
const text = convert(rawContent);
documents.push(
new Document({
pageContent: text,
metadata: {
source: file,
title,
},
})
);
}
return documents;
}
分词
文本分块推荐使用LangChain社区提供的 RecursiveCharacterTextSplitter(来自 @langchain/textsplitters),它在处理中文长文档时表现稳定。
import { RecursiveCharacterTextSplitter } from '@langchain/textsplitters';
import type { Document } from '@langchain/core/documents';
const CHUNK_SIZE = 1000;
const CHUNK_OVERLAP = 200;
export function createSplitter(): RecursiveCharacterTextSplitter {
return new RecursiveCharacterTextSplitter({
chunkSize: CHUNK_SIZE,
chunkOverlap: CHUNK_OVERLAP,
});
}
export async function splitDocuments(docs: Document[]): Promise<Document[]> {
const splitter = createSplitter();
return splitter.splitDocuments(docs);
}
简单归纳其核心逻辑——"分级降级,尽力保证段落完整性":
- 按优先级切分:优先使用段落分隔符(如
\n\n)进行切割,力求保留完整的语义段落。 - 检查块大小:若切分后的某一块仍然超出预设的
chunk_size,不强制截断,而是继续降级处理。 - 递归降级切分:对超长块自动降级,使用更低优先级的分隔符(例如句号
.或中文的。)再次切分。 - 迭代直至收敛:重复降级过程,直到所有分块符合大小要求。若最终降至最小分隔符(单个字符
"")后仍超长,则保留该超长块并抛出警告。
基于这一机制,我们还可以针对中文文档优化分隔符列表:
export function createSplitter(): RecursiveCharacterTextSplitter {
return new RecursiveCharacterTextSplitter({
separators: [
"\n\n", // 段落
"\n", // 换行
"。",
"!",
"?",
";", // 中文句子结束符
",",
"、", // 中文逗号/顿号
" ", // 空格
"", // 字符
],
chunkSize: CHUNK_SIZE,
chunkOverlap: CHUNK_OVERLAP,
});
}
嵌入和存储
Chroma.from_documents() 是一个将向量化与存储合并执行的便捷接口。调用后内部自动完成以下操作:
- 调用嵌入模型:对传入的每个
Document内容生成向量表示。 - 写入数据库:建立 Chroma 连接,将向量、原文以及元数据一并入库,构建完整的向量索引。
const store = await Chroma.fromDocuments(docs, embeddings, {
collectionName: COLLECTION_NAME,
url: `http://${config.chromaHost}:${config.chromaPort}`,
}).catch((error) => {
console.error("Error creating vector store:", error);
throw error;
});
这一步的耗时取决于文档规模和嵌入模型算力。文档内容更新时,务必实现增量 embedding 机制,避免全量重算带来的性能损耗。
查询
查询阶段同样需要将用户输入转为向量,不过 similaritySearch 方法内部自动完成向量化与相似度计算。
const llm = createLLM(0.3);
const docs: Document[] = await vectorStore.similaritySearch(query, 5);
const contextDocs: string[] = docs.map((doc: Document) => doc.pageContent);
// 源文档引用,可用于生成可点击链接
const sources: string[] = [...new Set(docs.map((doc: Document) => doc.metadata.source as string))];
// 将检索到的上下文拼入LLM的prompt
const prompt = buildPrompt(
query,
contextDocs,
projectContext,
conversationHistory
);
const response = await llm.invoke(prompt);
来源:互联网
本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。