96SEO 2026-05-24 12:37 1
基于Eino框架,构建RAG系统实战教程
RAG是一种为了解决大语言模型幻觉问题而诞生的技术方案。它的核心思想hen简单:用户提问 → 先去"知识库"里找相关资料 → 把资料塞给大模型 → 模型基于真实资料回答。就像一场开卷考试:学生Ke以翻阅课本和笔记再作答,答案自然geng准确、geng有据可查。
我们的RAG系统由多个核心环节串联而成,项目文件结构如下:

AwesomeEino/
├── cmd/run_RAG/
│ ├── main.go # 入口:串联全部组件
│ ├── .env # API 密钥配置
├── RAG/
│ ├── MilvusCli.go # Milvus 客户端初始化
│ ├── embedder.go # ARK 嵌入模型封装
│ ├── indexer.go # Indexer 创建 + Schema 定义
│ ├── indexer_binary.go # 自定义 DocumentConverter
│ ├── retriever.go # Retriever 创建
│ ├── mdOpenFs.go # 文件读取
│ ├── md_Splitter.go # 文档切分逻辑
└── docker-compose.yml # Milvus 服务编排
运行指南
确保Milvus正在运行:
# . 确保 Milvus 正在运行
docker compose up -d
# . 进入运行目录
cd cmd/run_RAG
# . 运行
go run .
RAG系统构建步骤
第一步:文档加载与切分
一篇几万字的长文不Neng直接作为一个整体处理——既浪费Token,也会导致检索精度下降。我们需要把它切成语义独立的小段:
func MdOpenFs {
bs, err := os.ReadFile // 读文件为字节数组
return MdSplitter // 交给切分器处理
}
第二步:向量化
当Embedder收到文本时内部流程是这样的:
输入文本: "刘氏家族:粉丝根据他对职业选手Device的喜爱..."
↓调用 ARK doubao-embedding-vision- API
↓返回: 共 个整数
↓通过 DocumentConverter 转换为 byte:
共 字节
↓存入 Milvus BinaryVector 字段
第三步:定义Milvus Schema
在往Milvus存数据前,需要先定义"表长什么样"。这和MySQL里建表CREATE TABLE是同一个概念:
var fields = *entity.Field{
{Name: "id", DataType: entity.FieldTypeVarChar,
TypeParams: mapstring{"max_length": ""}, PrimaryKey: true},
// ↑ 主键,唯一标识每条记录
{Name: "vector", DataType: entity.FieldTypeBinaryVector,
TypeParams: mapstring{"dim": ""}},
// ↑ 二进制向量列!dim 单位是比特, bit = byte = 维
{Name: "content", DataType: entity.FieldTypeVarChar,
TypeParams: mapstring{"max_length": ""}},
// ↑ 存储原文内容
{Name: "metadata", DataType: entity.FieldTypeJSON},
// ↑ 存储元数据,JSON格式
}
第四步:自定义DocumentConverter
Eino-ext的Milvus indexer组件提供了DocumentConverter钩子,让我们控制如何将模型输出转换为Milvus可接受的格式:
func binaryDocumentConverter(_ context.Context, docs *schema.Document,
vectors float64) {
rows := make)
for i, doc := range docs {
metadata, _ := json.Marshal
// 核心:每个float64 → byte
byteVec := make)
for j, v := range vectors {
byteVec = byte
}
rows = append(rows, &binaryRow{
ID: doc.ID,
Content: doc.Content,
Vector: byteVec, // byte → BinaryVector
Metadata: metadata,
})
}
return rows, nil
}
第五步:存入Milvus
调用方只需一行:
indexer.Store // 将切分后的文档全部存入
第六步:执行检索
用户提问:"刘氏家族是什么?",系统会先将其向量化,然后在Milvus中进行相似度搜索:
results, _ := retriever.Retrieve
for _, doc := range results {
println
println // Zui相关的文档片段
println
}
第七步:基于检索结果生成回答
检索只是RAG的一半。完整的RAG还包括把检索到的上下文喂给大模型,让它生成自然语言回答:
// 使用ARK大模型
model, _ := ark.NewChatModel(ctx, &ark.ChatModelConfig{
APIKey: os.Getenv,
Model: os.Getenv,
Timeout: &timeout,
})
messages := *schema.Message{
schema.SystemMessage,
schema.UserMessage),
}
response, _ := model.Generate
println
RAG系统的关键设计决策
为什么用BinaryVector而不是FloatVector?
存储效率geng高 : 个float32需要*4=160字节,而BinaryVector只需字节——节省了1/20的存储空间。 计算geng快 : 汉明距离计算在硬件层面有极大优化,比欧式距离快得多。 召回率不降反升 : 二值化后的向量反而Neng过滤掉部分噪声,提升检索质量。
Eino框架在RAG系统中的作用Eino框架极大地简化了RAG系统的搭建过程。它提供了丰富的组件和接口,使得开发者Ke以专注于业务逻辑的实现,而无需关心底层的细节。例如Eino框架提供了MilvusIndexer, MilvusRetriever等模块,直接支持向量数据库的操作。
Eino框架的模块化设计使得RAG系统的 和维护变得geng加容易。
希望通过本教程,你Neng够掌握使用Eino框架构建RAG系统的基本方法,并在实际项目中加以应用。
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback