文章摄入与 EmbeddingService
约 453 字大约 2 分钟
布欧-Lewyon
2026-06-08
首页 › Agent Spring Boot › RAG 检索增强
知识库形态:Article 非文件上传
agent-rag 的知识单元是 文章(title + content JSON),不是 PDF multipart 上传。批量导入走 SQL + reindex。
表结构(sql/init.sql):
CREATE TABLE article (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
embedding LONGTEXT, -- JSON float 数组
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);创建与更新
ArticleService.createArticle():
Article article = new Article(title, content);
float[] vector = embeddingService.embedSync(title + " " + content);
article.setEmbedding(embeddingService.vectorToJson(vector));
articleRepository.save(article);更新时同样重新 embed。阻塞 JPA 包在 Mono.fromCallable(...).subscribeOn(Schedulers.boundedElastic())。
EmbeddingService(common 模块)
com.lewyon.common.llm.EmbeddingService:
- 请求
POST {deepseek.api.url}/v1/embeddings - 模型:
deepseek.embedding.model(配置项) embed(String)→Mono<float[]>embedSync供 JPA 同步路径- 失败时返回空向量,触发关键词检索降级
public String vectorToJson(float[] vector) { /* Jackson */ }
public float[] jsonToVector(String json) { /* 反序列化 */ }
public boolean isValid(float[] vector) { /* 维度检查 */ }SQL 批量导入 + reindex
- 执行
sql/data.sql插入样例文章(embedding为 NULL) - 调用
POST /api/articles/reindex
reindexAll() 遍历文章,为缺失或无效向量重新生成 embedding,返回 {total, indexed, skipped}。
API 一览(ArticleController)
| 方法 | 路径 |
|---|---|
| POST | /api/articles body {title, content} |
| GET | /api/articles |
| GET | /api/articles/{id} |
| PUT | /api/articles/{id} |
| DELETE | /api/articles/{id} |
| GET | /api/articles/search?query= |
| POST | /api/articles/reindex |
前端 Agent 模式不直接管理文章;运维用 curl 或 SQL。
摄入流程图
学习点
- 向量化文本常用
title + content拼接,提升检索命中。 - SQL 导入后必须 reindex,否则 embedding 为空只能走关键词兜底。
- JPA 阻塞调用要放
boundedElastic,别堵 Netty 线程。
小结
- 知识库 =
article表;Embedding 由 common 模块统一调 DeepSeek。 - CRUD +
reindex完成摄入闭环。 - 无文件解析器;扩展 PDF 可在 ingestion 层加 Tika(
ai-image模块有参考)。
上一节:RAG 架构
下一节:MySQL 向量检索
