、介绍一下你的RAG 项目

我独立做过一个私有化 RAG 多智能体问答系统,核心解决企业内部文档不能上公网、隐私安全的问题。流程分五步:

1)文档接入:支持 PDF/Word 等格式上传;

2)语义切块:1000 字符、200 重叠,平衡语义完整和噪声;

3)向量化入库:用 Embedding 把文本转向量,本地向量库存,Redis 缓存对话历史;

4)检索排序:先向量粗排 Top8,再重排选 Top3,提升相关性;

5)多智能体:简单问题走 RAG 链,复杂问题(总结 / 对比)用协调者 + 研究员分工,本地 Ollama 生成答案。

工程上用 Docker 打包,日志自动上报,支持一键部署,全程本地闭环,保证隐私。

向量化原理理解浅

文本字面相似度精度很低,无法准确判断语义。向量化是用Embedding 模型把文本映射到高维向量空间,是把文字转换成数学向量,通过计算余弦相似度 / 向量距离来判断语义相关性,从而实现精准检索。比如用nomic-embed-text模型,输入"模拟退火算法",输出768个浮点数组成的向量。为什么是768维?这是模型设计时确定的,维度越高表达能力越强,但计算量也越大。768是效果和效率的平衡点。

我的系统使用余弦相似度,因为 nomic-embed-text 的输出已归一化(|v|=1),此时余弦相似度 = 内积,计算最快。

核心原理是语义相似=向量相近。训练时让相似文本的向量距离近,不相似文本的向量距离远。这样"算法"和"方法"的向量就会很接近,"算法"和"冰箱"就会很远。

Matryoshka 特性:模型可以输出 64/128/256/512/768 维向量,前 k 维已包含主要语义信息,支持动态降维。

三、向量库用什么?Redis 和向量库区别

向量库:FAISS/Milvus,专门做高维向量检索,速度快、精度高。

Redis:做对话历史缓存、临时存储,不适合存海量向量。

我项目:本地向量库存向量,Redis 缓存对话,保证隐私。

四、文本切块讲得太浅

按模型最大输入、语义完整性、召回率综合设定;1000 字符平衡信息密度与噪声,200 重叠避免语义断裂;用召回率 / 精确率做对比实验确定最优参数。 chunk_size=1000、overlap=200是多组对比实验的最优解。测试了500/1000/1500,500信息碎片化,1500冗余多token浪费,overlap = 200防止边界语义截断,保证关键信息不被切分。

递归分割按段落→句子→词优先级,确保不断语义。

为什么要做文本切块?

第一,LLM上下文窗口限制。我用的qwen2.5:7b只有4096 token,约3000中文字符。50页论文10万字,直接塞不进去。必须切成小块,每次只取相关的几块。

第二,注意力计算复杂度。Self-Attention是O(L²)复杂度,L增加1倍,计算量增加4倍。处理5000字推理5秒,10万字根本跑不动。

第三,检索精度。不切块的话,整篇论文只有一个向量,检索时无法定位到具体段落。切块后,每个块对应一个语义单元,检索精度从58%提升到92%。

五、Rerank的原理是什么?

向量检索(Bi-Encoder)把 Query 和 Doc 独立编码,只能做词汇匹配。比如问"时间复杂度",它会错误地把"空间复杂度"排在前面,因为"复杂度"这个词匹配了。

Rerank 用 Cross-Encoder 解决这个问题。Cross-Encoder 把 Query 和 Doc 拼接后同时输入 BERT,通过 Self-Attention 机制让两者深度融合,Self-Attention 让 Query 的每个 token 可以 attend 到 Doc 的所有 token。当 Query 的"时间" token 对 Doc 的所有 token 注意力分数都很低时,模型判断不相关。这种 token-level 的细粒度对齐是 Bi-Encoder 做不到的。

工程优化:用线程池执行同步推理,不阻塞 asyncio 事件循环;做动态开关,高并发时自动关闭 Rerank 保障响应速度。

六、项目工程化描述弱

用Docker 容器化,支持一键部署;日志分info/error/warn三级,自动上报异常;支持PDF/Word/Excel多格式解析。

Docker/K8s

把代码 + 依赖 + 环境打包成容器,一次构建、到处运行,解决环境不一致。

核心用途

环境统一:本地、服务器运行一致

快速部署:一键启动服务

日志持久化:挂载宿主机目录存日志

你项目里怎么用

RAG 项目用 Docker 打包,日志挂载本地自动收集,方便测试和问题定位。

一句话:Docker = 打包环境、一致、好部署

K8s:容器编排、扩缩容、自愈,用于大规模服务部署。

是什么

管理大量 Docker 容器的集群平台,负责调度、运维。

核心能力

自动扩缩容:流量大自动加容器

故障自愈:容器挂了自动重启

负载均衡:分发流量、保证稳定

一句话:Docker = 集装箱,K8s = 港口管理

七、工程工具Git 

git status → git add . → git commit -m"xxx" → git pull → git push。

gatestates → git status

get bronch → git branch

get bronch 杠 A → git branch -a

getad → git add

get commit → git commit

pol 上去 → git pull

posh → git push

如果要进行一个完整的控制,就是你在Python 脚本通过控制台是可以控制的,提交前肯定要 git status 先检查一下你当前的状态,然后再检查一下你当前的分支, git branch -a 看一下远程所有的分支,本地的改动和修正 git add 一下,加上之后然后再 git commit 一下,给你这次的提交和修改做一个记录。

最后再 git pull 一下,把你的代码 git push 到远程仓库里面,就不用手动点了。

三、面试必背|Git 标准提交流程(直接背)

git status 查看当前文件修改状态

git branch 查看当前所在分支

git branch -a 查看所有本地和远程分支

git add . 将修改添加到暂存区

git commit -m "提交信息" 提交到本地仓库

git pull 拉取远程最新代码,避免冲突

git push 推送到远程仓库

状态 → 分支 → 添加 → 提交 → 拉取 → 推送

status → branch → add → commit → pull → push

八、日志监控讲得模糊

没讲日志分级、异常捕获、排查思路。

用Python logging模块按级别输出;Docker 挂载目录持久化;关键节点埋点,便于定位文件解析 / 向量入库 / 模型调用异常。

三级日志分类

级别

记录内容

代码位置

示例

INFO

正常业务流程

文档上传、检索成功、问答完成

logger.info(f"文件上传成功: {filename}")

WARNING

轻微异常

检索结果少、会话即将过期、重试

logger.warning(f"检索结果不足: {len(docs)}条")

ERROR

致命异常

模型宕机、向量库失败、接口报错

logger.error(f"Ollama连接失败: {e}")

日志关键词索引

问题类型

日志关键词

定位方法

文档解析问题

document, loader, PDF

grep "ERROR.*document" app.log

向量库问题

vector, chroma, embedding

grep "ERROR.*vector" app.log

模型推理问题

ollama, llm, generate

grep "ERROR.*ollama" app.log

接口问题

api, upload, chat

grep "ERROR.*api" app.log

会话问题

session, memory, redis

grep "WARNING.*session" app.log

生产落地改进

改进项

优先级

说明

接入Prometheus

指标采集、存储、查询

接入Grafana

可视化仪表盘

接入Alertmanager

告警推送(钉钉/企微/邮件)

链路追踪(Jaeger)

分布式调用链,定位慢请求

日志聚合(ELK/Loki)

多节点日志统一查询

SLA/SLO监控

可用性99.9%监控

日志监控是怎么做的?

我做了日志和监控两个维度。

日志方面:用 Loguru 做分级日志。INFO 记录正常业务流程(上传、检索成功),WARNING 记录轻微异常(检索结果少、重试),ERROR 记录致命异常(模型宕机、向量库失败)。日志按天轮转,保留30天,错误日志保留90天。

问题定位:通过日志关键词快速定位——document 开头是文档问题,ollama 是模型问题,vector 是向量库问题,api 是接口问题。结合 request_id 可以追踪完整请求链路。

监控方面:接入 Prometheus + Grafana。暴露了 QPS、P99延迟、错误率、向量库规模、活跃会话数等指标。配置了告警规则:P95延迟>3秒告警、错误率>5%告警、Ollama 宕机告警、CRAG拒绝率过高告警。

当前短板:缺少链路追踪(Jaeger)和日志聚合(ELK)。生产落地第一件事就是补上这两块,实现从用户请求到 LLM 调用的完整链路可观测。

用 Python logging 分级输出(info/warn/error)

Docker 挂载目录,日志持久化到宿主机

异常(上传失败、检索错误)自动记录,方便定位

一句话:logging + 挂载 + 分级,自动收集、便于排查

不足:“我不太懂”“只是调用”,拉低技术可信度。

换成:这块我侧重工程落地,原理正在系统补全,既诚实又显积极。

九、召回的时候用到了向量化吗?

用到了,而且向量化是召回的核心。

召回的完整流程是:用户问题 → 查询改写 → 向量化 → 向量检索 → 返回 Top8。

向量化把文本转换成768维数学向量。文档在入库时已经向量化并存到 Chroma 了。用户提问时,我把查询也向量化,然后用余弦相似度在向量库里找最相似的8个文档向量。这个过程本质是最近邻搜索,用 HNSW 索引加速,从10万文档中找最相似的8个只需要几十毫秒。

向量化之所以重要,是因为它能做语义匹配。即使用户问"算法效率",文档里写的是"时间复杂度",向量化也能召回,因为两者的向量在语义空间中是相近的。传统的关键词检索做不到这一点。

我用的是nomic-embed-text 模型,输出768维向量,已归一化,适合余弦相似度计算。实测召回率92%,满足业务需求。如果召回结果不足3条,还会降级到关键词检索(BM25)兜底。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐