• RAG学习笔记(2):关于rag和模型微调,同一个问题它们分别怎么处理


    微调和RAG学习笔记:同一个问题它们分别怎么处理

    好家伙,

    今天我们来聊一个很容易混在一起的问题:

    模型微调 和 RAG 到底有什么区别?

    这两个东西看起来都能让大模型回答得更贴近业务.

    但它们解决的问题其实不一样.

    我之前很容易把它们都理解成:

    让模型懂我的项目

    但这样理解太粗了.

    更准确一点应该是:

    微调 = 让模型学会某种能力、格式、风格或领域表达
    RAG = 让模型回答前去查外部资料

    一句话总结:

    微调改变模型本身.
    RAG不改模型,而是给模型临时补资料.

    这篇文章就用同一个问题来看:

    tsu_engine 的战斗监控接口怎么部署?

    如果用微调,它会怎么处理?

    如果用 RAG,它又会怎么处理?

    0.背景:为什么会拿微调和RAG比较

    先看一个真实一点的场景.

    我现在有一个后端项目,里面有一些部署文档:

    Go 后端服务
    Docker Compose
    PostgreSQL
    战斗监控接口
    Nginx 反向代理

    用户可能会问:

    tsu_engine 的战斗监控接口怎么部署?

    这个问题对普通大模型来说就比较尴尬.

    因为它不知道我的本地项目.

    它也不知道:

    1. 服务端口是多少
    2. Docker Compose 文件叫什么
    3. PostgreSQL 怎么配置
    4. 健康检查接口是什么
    5. 战斗监控接口怎么验证

    那么要让模型回答这个问题,大概有两种思路:

    1. 把这些知识训练进模型
    2. 回答前先去文档里查这些知识

    第一种就是微调.

    第二种就是 RAG.

    它们看起来都能解决"模型不知道"的问题.

    但底层路线完全不一样.

    1.先定义同一个问题

    为了方便比较,我们固定一个问题:

    tsu_engine 的战斗监控接口怎么部署?

    这个问题需要的信息可能包括:

    1. 需要启动 api 和 postgres
    2. 使用 docker compose 启动
    3. API 端口是 18088
    4. 健康检查接口是 /api/health
    5. 监控接口是 /api/battle-monitor/status
    6. 请求监控接口要带 Authorization token
    7. PostgreSQL 用来保存战斗监控数据

    如果回答得更完整一点,还要说明:

    1. Dockerfile 里 Go 版本要和 go.mod 匹配
    2. Docker Hub 可能需要镜像源
    3. Go 依赖下载可能需要 GOPROXY
    4. 生产环境不能用本地默认 token
    5. PostgreSQL 不应该直接暴露到公网

    也就是说,这不是一个纯通用问题.

    它明显依赖项目文档.

    下面我们分别看微调和 RAG 会怎么处理.

    2.微调是怎么处理这个问题的

    微调的思路是:

    准备训练数据
    -> 把问题和标准答案交给模型训练
    -> 模型参数发生更新
    -> 以后遇到类似问题,按训练中学到的方式回答

    比如我们准备一条训练样本:

    {
    "question": "tsu_engine 的战斗监控接口怎么部署?",
    "answer": "先通过 Docker Compose 启动 api 和 postgres,然后访问 /api/health 验证后端在线,再带 Authorization token 请求 /api/battle-monitor/status 验证战斗监控状态..."
    }

    只准备一条肯定不够.

    实际微调需要很多类似样本.

    比如:

    怎么部署战斗监控?
    tsu_engine 本地 Docker 怎么启动?
    PostgreSQL 监控库怎么配置?
    怎么验证 /api/battle-monitor/status?
    生产环境 token 怎么设置?

    每个问题都配一个标准答案.

    模型训练以后,会学到几类东西:

    1. 这类问题应该怎么回答
    2. 回答应该按什么格式组织
    3. 哪些术语经常一起出现
    4. 面对部署问题时先讲启动,再讲验证,最后讲注意事项

    也就是说,微调更像是在训练模型的"习惯".

    它让模型更像一个已经学过这些问答范式的助手.

    2.1 微调回答时发生了什么

    当用户再次问:

    tsu_engine 的战斗监控接口怎么部署?

    微调后的模型不会去查文档.

    它直接根据参数里学到的东西生成答案.

    流程大概是:

    用户问题
    -> 微调后的模型
    -> 根据训练中学到的模式生成回答

    这里没有检索.

    也没有实时读取最新文档.

    答案来自模型参数.

    2.2 微调的好处

    微调的优势是:

    1. 可以让模型稳定输出某种格式
    2. 可以让模型更熟悉某个领域的表达
    3. 可以让模型学会特定任务
    4. 可以减少每次 prompt 里重复写规则

    比如客服机器人,你希望它永远用固定语气回答.

    或者代码助手,你希望它总是按某种模板输出.

    这种就适合微调.

    2.3 微调的问题

    但微调有一个很大的问题:

    知识更新不方便.

    假设部署方式改了.

    比如:

    端口从 18088 改成 19088
    接口从 /api/battle-monitor/status 改成 /api/monitor/status
    token 环境变量改名了
    PostgreSQL 配置改了

    微调后的模型不会自动知道.

    因为它回答时没有去读最新文档.

    除非你重新整理训练数据,再微调一次.

    所以微调不适合频繁变化的项目知识.

    3.RAG是怎么处理这个问题的

    RAG 的思路完全不一样.

    它不要求模型提前记住 tsu_engine.

    它的做法是:

    用户提问
    -> 把问题变成向量
    -> 去知识库检索相关文档
    -> 找到 Docker 部署、PostgreSQL、战斗监控接口相关片段
    -> 把这些片段交给大模型
    -> 大模型基于片段回答
    -> 返回答案和来源

    也就是说,RAG 不是把知识训练进模型.

    而是让模型回答前先查资料.

    3.1 RAG会检索到什么

    还是这个问题:

    tsu_engine 的战斗监控接口怎么部署?

    RAG 可能会检索到这些片段:

    docker compose -f docker-compose.backend-local.yml up -d --build
    curl http://127.0.0.1:18088/api/health
    curl -H "Authorization: Bearer local-monitor-token" http://127.0.0.1:18088/api/battle-monitor/status
    TSU_MONITOR_POSTGRES_PASSWORD=强密码
    BATTLE_MONITOR_ADMIN_TOKEN=强token
    TSU_ENGINE_API_PORT=18088

    然后模型拿到这些资料以后,再组织成回答.

    3.2 RAG回答时发生了什么

    RAG 的回答流程大概是:

    用户问题:
    tsu_engine 的战斗监控接口怎么部署?
    检索结果:
    1. Docker Compose 启动命令
    2. API 健康检查接口
    3. 战斗监控状态接口
    4. PostgreSQL 配置
    5. 生产环境注意事项
    大模型:
    根据这些资料组织答案

    最后回答可能是:

    先启动 api 和 postgres:
    docker compose -f docker-compose.backend-local.yml up -d --build
    然后验证健康检查:
    curl http://127.0.0.1:18088/api/health
    再验证战斗监控接口:
    curl -H "Authorization: Bearer local-monitor-token" http://127.0.0.1:18088/api/battle-monitor/status
    生产环境需要替换强密码和强 token,不要暴露 PostgreSQL 到公网.

    更关键的是,RAG 可以附上来源:

    来源:
    docs/docker-go-backend-deploy-blog.md / Docker Compose 部署部分
    docs/docker-go-backend-deploy-blog.md / 战斗监控验证部分

    这个来源很重要.

    因为用户可以回到原文验证.

    4.同一个问题下的本质区别

    现在我们把两者放在一起看.

    同一个问题:

    tsu_engine 的战斗监控接口怎么部署?

    微调的路径:

    问题
    -> 模型根据训练过的参数回答
    -> 答案来自模型内部

    RAG 的路径:

    问题
    -> 检索外部知识库
    -> 找到当前文档
    -> 模型基于文档回答
    -> 答案可以带来源

    一个是"记住".

    一个是"查找".

    这就是核心区别.

    5.微调更适合解决什么问题

    我现在更倾向这样理解:

    如果问题的关键是模型不会某种能力,考虑微调.

    比如:

    1. 模型不会按你的固定格式输出
    2. 模型不熟悉你的行业表达
    3. 模型回答风格不稳定
    4. 模型需要学习某类固定任务
    5. 模型需要更好地遵守某种输出规范

    举个例子.

    你希望模型永远按这种格式回答:

    问题复述:
    原因分析:
    处理步骤:
    风险提醒:
    下一步:

    如果这个格式要长期稳定使用,微调就有意义.

    再比如你希望模型学习你的写作风格:

    好家伙开场
    编号标题
    先需求分析
    再逐步拆解
    最后总结踩坑

    这种也可以考虑微调.

    因为它更像风格和格式问题.

    6.RAG更适合解决什么问题

    RAG 更适合这种情况:

    如果问题的关键是模型不知道资料,考虑 RAG.

    比如:

    1. 项目文档问答
    2. 内部知识库
    3. 配置表查询
    4. 部署文档查询
    5. 经常变化的业务资料
    6. 需要给出来源的回答

    这里的重点是:

    资料会变.

    比如部署文档今天改了.

    RAG 只要重新导入文档,下次检索就是新内容.

    但微调模型不会自动更新.

    所以项目知识库这种场景,RAG 通常更合适.

    7.能不能一起用

    可以.

    而且很多时候,更合理的方案就是一起用.

    比如:

    微调负责回答风格和任务格式
    RAG负责检索最新资料

    流程可以是:

    用户问题
    -> RAG 检索项目文档
    -> 把资料放进上下文
    -> 微调过的模型按固定格式回答

    这样模型既能查到最新资料,又能按我们希望的方式输出.

    举个例子:

    RAG 找到 tsu_engine 部署文档.
    微调模型按"背景 -> 步骤 -> 验证 -> 注意事项"格式回答.

    这样就比单独使用其中一个更稳.

    8.用一个表总结区别

    简单做个对比:

    维度 微调 RAG
    知识来源 模型参数 外部知识库
    是否改模型 改 不改
    更新资料 需要重新训练或继续微调 重新导入资料即可
    是否给来源 不天然支持 天然适合给来源
    适合场景 风格、格式、固定任务 文档问答、知识库、资料查询
    风险 学到过时知识 检索不到就答不好
    成本 训练成本更高 工程链路更复杂

    我觉得最核心的区别还是这句:

    微调让模型学会怎么答.
    RAG让模型知道该查什么资料再答.

    9.常见误区

    9.1 误区一:有RAG就不需要好模型

    不是.

    RAG 只是把资料找出来.

    模型还要负责理解资料,组织答案.

    如果模型理解能力太差,检索结果再好,回答也可能不行.

    9.2 误区二:微调可以替代知识库

    也不是.

    把所有项目文档都微调进模型,听起来很爽.

    但资料一更新,模型就过时了.

    更何况微调后也不容易知道答案来源.

    9.3 误区三:RAG一定不会胡编

    这个也不对.

    如果检索结果不相关,或者 prompt 没有限制模型,它还是可能胡编.

    所以 RAG 需要:

    1. 文档处理质量
    2. 检索相关度阈值
    3. prompt 约束
    4. 来源展示
    5. 资料不足时明确说不知道

    10.总结

    这次对比微调和 RAG,我最大的收获是:

    它们不是同一个层面的东西.

    微调解决的是:

    模型能力、风格、格式、任务习惯

    RAG 解决的是:

    外部知识、最新资料、来源可追溯

    如果用一句话判断:

    模型不会这种回答方式 -> 微调
    模型不知道这些资料 -> RAG

    再实际一点:

    微调解决"怎么答".
    RAG解决"根据什么资料答".

    回到最开始的问题:

    tsu_engine 的战斗监控接口怎么部署?

    如果我希望模型永远用固定结构解释部署问题,可以微调.

    如果我希望模型回答最新的部署命令、接口地址、环境变量和注意事项,应该用 RAG.

    更好的方案是:

    用 RAG 查最新文档.
    用微调或提示词保证回答格式.

    这样模型既不会脱离资料乱说,也能保持稳定的输出风格.

    最后一句话总结:

    微调不是知识库.
    RAG也不是训练模型.
    它们一个改模型,一个查资料.
    真正落地时,要看问题到底缺的是能力,还是资料.
  • 相关阅读:
    多模块初始化解决方案
    kernel 劫持seq_operations && 利用pt_regs
    uni-app (通过HBuilderX 和 VS Code 开发)详细连接过程教学。
    openocd stm32 telnet 调试
    Shiro 550、721
    React基础详解(一)
    剑指 Offer 11. 旋转数组的最小数字
    RDD持久化
    JavaScript 71 JavaScript JSON 71.9 JSON 服务器
    HTTPS工作过程,国家为什么让http为什么要换成https,Tomcat在MAC M1电脑如何安装,Tomcat的详细介绍
  • 原文地址:https://www.cnblogs.com/FatTiger4399/p/20065831