从今年五月写《从零学大模型》到现在,这个系列已经更了十几篇:微调、RAG、部署、Function Calling、Agent 编排、安全、监控……每一篇都是我当时踩坑后总结的实操。但说实话,一直有个问题压在我心里:这些技能我都是”单点验证”的——微调是在 Colab 上试的,RAG 是本地脚本跑的,监控告警是在测试环境搭的,它们从来没有真正串成一个能上线的系统。直到上个月,我花了两周把一个”内部文档问答 + 工单处理”的 Agent 从零做到上线,才把整条链路彻底跑通。这篇就是完整复盘:数据准备、微调、部署、RAG、编排、安全、监控一条龙,每步都标注对应系列里的哪篇文章,你照着串就行。
一、先画架构图,别急着写代码
我的第一课是:先别写代码,把架构画出来。这个项目的链路是:用户消息 → 输入守卫 → LangGraph 编排 → 工具层(RAG 检索 + 工单 API)→ LLM(vLLM 部署)→ 输出守卫 → 响应;旁边挂着 OpenTelemetry 打点 → Prometheus → Alertmanager。画完这张图我才发现,整条链路上每一环都能在系列文章里找到对应:微调在 817,部署在 821,RAG 在 815,编排在 826,安全在 830–832,监控在 832。工具链早就齐了,缺的只是把它们焊在一起的顺序。
二、数据准备与微调:先有”会干活”的模型
我的顺序是先把模型定下来。因为要做多轮对话和工具调用,我在 QLoRA 微调(817)的基础上,用 820 的 Chat Template 把训练数据整理成带 system/user/assistant 三段的对话格式,工具调用样本按 825 的并行调用格式标注。数据量不用大,几千条高质量样本就够——我实测 2000 条比之前盲堆 2 万条效果还好,关键是每条都真实验证过。微调完别急着部署,先用 818 的评测工具箱跑一遍基准,确认模型没变笨再继续。
三、部署:vLLM 一行命令起服务
部署我选了 vLLM,因为它自带 OpenAI 兼容接口,后面接什么框架都不用改。官方文档的命令直接可用:
vllm serve NousResearch/Meta-Llama-3-8B-Instruct --dtype auto --api-key token-abc123
服务起在 8000 端口后,用 openai 库把 base_url 指到 http://localhost:8000/v1 就能调;模型名换成你微调后导出的路径也行,vLLM 支持直接 serve 本地目录。量化、并发和显存估算这些细节我写在 821,上线前值得重读一遍。
四、RAG:向量库一条命令,检索接进工具层
知识库问答是第一个工具。向量库我用 Qdrant,官方 README 里的一行命令就能起:
docker run -p 6333:6333 qdrant/qdrant
客户端连 localhost:6333,把文档切片、embedding 后写入,查询时取 top-k 片段拼进 prompt。单库够用就别上复杂方案——我一开始照搬 822 的 Agentic RAG,后来发现这个场景重排序加简单路由就够,反而更快更稳。评估用 823 那套指标,召回率和忠实度盯住就行。
五、编排:LangGraph 把节点串成图
整个 Agent 的骨架我用 LangGraph,官方文档的最小示例就是全部入门内容:
from langgraph.graph import StateGraph, MessagesState, START, END
def llm_node(state: MessagesState):
return {"messages": [{"role": "ai", "content": "hello"}]}
graph = StateGraph(MessagesState)
graph.add_node(llm_node)
graph.add_edge(START, "llm_node")
graph.add_edge("llm_node", END)
app = graph.compile()
我的图比这个多几个节点:route(决定走 RAG 还是调工单 API)、retrieve、call_tool、llm,节点之间用条件边连接。工具函数就是 824、825 里那种 function calling 写法,把检索和工单查询包成两个 tool 注册进去。选 LangGraph 而不是自己写 while 循环,是因为它自带状态管理和持久化,后面加记忆(827)和人工确认都省事。
六、安全加固:双守卫 + 权限最小化
安全不能等上线前才想。我的做法照搬 830–832 的结论:输入侧和输出侧各放一道检测,用户消息进来先过注入检测,命中直接拒绝;工具调用前再检一次参数,风险高就拦截。规则匹配只是基线方案,生产环境我换成了 Llama Guard 做分类检测(832 里有替换方法),两层叠加。工单 API 的 key 单独建一个只有查询权限的账号,绝不用管理员凭据——这是 830 里最便宜的保命操作。
七、监控告警:上线前先把眼睛装上
上线前一天,我按 832 的流程把 OpenTelemetry 打点接上:每个工具调用的延迟、成功失败计数、注入拦截次数,通过 OTLP 推到 Prometheus,再配 Alertmanager 告警。阈值不是拍脑袋定的,是先跑了一周基线再设的。上线当晚告警真的响了一次——是测试环境遗留的定时任务在调工单 API,虽然是个误报,但至少证明链路是通的。那一刻我才觉得这个系统”活”了。
八、全流程对照表
| 模块 | 工具 | 系列文章 |
|---|---|---|
| 入门路线 | — | 814 从零学大模型 |
| 微调 | QLoRA | 816、817、820、818 |
| 部署 | vLLM | 821 |
| RAG | Qdrant | 815、822、823 |
| 编排 | LangGraph | 824–829 |
| 安全 | 守卫 + Llama Guard | 830、831、832 |
| 监控 | OpenTelemetry + Prometheus | 832 |
总结
一句话:生产级 Agent = 微调过的模型 + vLLM 部署 + 向量检索 + LangGraph 编排 + 双守卫 + OTel 监控,缺一环都算不上”能上线”。行动建议:别追求一步到位,先 vllm serve 起一个模型,用 LangGraph 最小骨架接一个工具,跑通后再逐环加 RAG、安全、监控。我这两周就是这么干的,每一环都是系列里验证过的,串起来比想象中顺。
下期预告:这条”从零到上线”的主线到这就收官了。接下来我想开个新系列——上下文工程:怎么把有限的上下文窗口用出花来,KV Cache、提示压缩、长文档处理都会聊到,第一篇先聊聊为什么”上下文”正在成为最贵的资源。想一起折腾的,下篇见。
参考文献
- vLLM 官方文档(OpenAI 兼容服务):https://docs.vllm.ai/en/latest/serving/openai_compatible_server.html
- vLLM GitHub:https://github.com/vllm-project/vllm
- LangGraph 官方文档(Overview):https://docs.langchain.com/oss/python/langgraph/overview
- LangGraph GitHub:https://github.com/langchain-ai/langgraph
- Qdrant GitHub:https://github.com/qdrant/qdrant
- QLoRA 论文(arXiv:2305.14314):https://arxiv.org/abs/2305.14314
- LoRA 论文(arXiv:2106.09685):https://arxiv.org/abs/2106.09685
- Meta PurpleLlama(Llama Guard):https://github.com/meta-llama/PurpleLlama
- NVIDIA garak(LLM 漏洞扫描器):https://github.com/NVIDIA/garak
- OpenTelemetry Python 官方文档:https://opentelemetry.io/docs/languages/python/