项目经历
三个实战项目,从 RAG 到 Agent 到模型微调
LangChain
Chroma
RAG
BGE Embedding
Agent
DeepSeek
项目背景
学完 LangChain 的 LCEL 和 Agent 模块后,想找一个具体场景把 RAG 技术完整跑一遍,于是做了这个能根据旅游攻略回答问题的问答助手。
关键实现
- 收集并整理北京、上海、成都、西安、杭州、三亚 6 个城市约 3,800 字的结构化旅游攻略文本
- 使用 RecursiveCharacterTextSplitter 按「二级标题 → 换行 → 句号」优先级切分为 12 个语义块(平均 321 字符/块)
- 通过 BAAI/bge-base-zh-v1.5 模型(768维)生成向量,存入 Chroma 做持久化
- 用 LangChain LCEL 把检索器、提示词模板、DeepSeek Chat、输出解析器串成 RAG 管道,支持流式输出
- 使用 ChatMessageHistory + RunnableWithMessageHistory 实现多轮对话记忆,追问时能理解上下文指代
- 用 LangGraph create_react_agent 给助手接入知识库检索和计算器两个工具,Agent 自主判断调用时机
踩坑记录
- 默认 Embedding 模型 (all-MiniLM) 不支持中文 → 调研后换 BAAI/bge-base-zh-v1.5
- HuggingFace 官方源被墙 → 配置 HF_ENDPOINT=https://hf-mirror.com 镜像下载
- LangChain 1.0+ 重构导致旧 API 不可用 → 查阅官方文档适配新路径
- 追问时检索不准("那里"无法匹配"北京")→ 依赖对话历史让 LLM 理解上下文,后续可加查询改写
LangGraph
Flask
SSE
SQLite
Chroma
DeepSeek
项目背景
学完 LangGraph 后,想用它搭建一个比单链 RAG 更复杂的对话系统。尝试了"双链路并行"的思路:一条链路管内容(意图识别+素材获取),一条链路管用户(画像分析+回复策略),两条同时跑,最后汇合生成个性化回复。
关键实现
- 参考 LangGraph 并行执行机制,把系统拆成两条独立链路——链路一负责意图判断和素材获取,链路二负责用户画像和回复策略,利用 LangGraph DAG 自动并行,省去手写多线程
- 用 StateGraph 把对话流程抽象为 12 个状态字段、11 个处理节点和 1 个条件路由,编译为可执行 Agent
- 条件路由根据意图识别结果自动分发到网络搜索、RAG 检索或常规对话三个分支
- 用 Flask 封装 POST /chat(SSE 流式回复)、POST /knowledge/update、GET /health 三个接口
- SQLite 存用户画像和聊天记录,Chroma 按「行业知识」和「课程信息」分两个集合存向量
- 用 Mock LLM 写了数据库读写、向量检索、意图分类、端到端流程 4 个测试模块
技术选型记录
- 双链路并行 → LangGraph 自动判断 DAG,框架自动并行
- 向量库 → ChromaDB,本地跑不用搭服务
- 数据库 → SQLite,一个文件搞定
- 流式输出 → SSE,浏览器原生支持,比 WebSocket 简单
- 网络搜索 → 先用 Mock 占位,接口预留替换位置
LoRA
Qwen2.5-7B
vLLM
LLaMA-Factory
Flask
PyTorch
项目背景
学完模型微调理论(LoRA/QLoRA、Alpaca 格式、评估方法)后,实践完整流程:自己准备数据集 → 上服务器微调 → 部署成 API。选了多领域客服意图识别这个场景,因为数据容易获取,4 个行业的对话差别足够明显。
关键实现
- 从 CrossWOZ 和 RiSAWOZ 两个中文对话数据集提取客服对话,清洗格式不一致的样本、筛选目标领域对话、转换成 Alpaca 格式
- 针对某些意图样本太少(长尾分布),写脚本调用大模型补全生成约 1,900 条训练数据(约占训练集 25%)
- 最终数据集 9,540 条(训练 7,768 / 验证 868 / 测试 904),覆盖银行、电商、医院、物流 4 领域 33 种意图
- 在 LLaMA-Factory 上配置 LoRA 参数(rank=8, alpha=16, dropout=0.1),对 Qwen2.5-7B-Instruct 微调
- A800 训练 2 轮共 1,942 步,耗时约 47 分钟,可训练参数约 77MB(约占模型 0.5%)
- 训练后合并权重,vLLM 部署推理服务,Flask 封装中间层 API,LangChain 封装 vLLM OpenAI 兼容接口
- 在 904 条测试集上,微调后意图识别准确率 73.0%(微调前基础模型在 33 分类下仅约 3%)
踩坑记录
- 某些意图样本太少 → 编写 boost_thin_classes.py 脚本为大模型补全生成补充样本
- 原始数据集格式不一致 → 编写 clean_data.py 和 validate_datasets.py 脚本统一清洗校验
- 服务器部署 vLLM 与 Flask 端口通信 → 同机器 localhost 通信,LangChain 封装 vLLM OpenAI 兼容 API