AI工程从零到上线:RAG、Agent与vLLM部署实战指南
2026/9/18 17:20:53 网站建设 项目流程

先聊个比较实在的话题:现在到处都在说 AI 工程、AI 应用开发,打开招聘软件满屏都是“大模型工程师”“AI Agent 开发”这类岗位,可真正能把一条 AI 应用从零到一、从代码到线上跑通的人,其实比想象中少很多。

原因很简单,市面上绝大多数教程只教你调 API、套模板,最多教你招一个聊天机器人,但真实工程里你遇到的问题往往是:回答质量不稳定怎么办、检索出来的东西不对怎么办、模型响应太慢怎么办、上线之后怎么观察它有没有退化。

我把“ai-engineering-from-scratch”这条路线从头到尾走了一遍,从对一个语言模型只知道“输入一句话就能返回一句话”,到做出带知识库的 RAG 问答、带工具调用的 Agent,再把它容器化部署上线做监控评估。这篇文章就是把这条路线上的核心知识点、选型逻辑、实操步骤和踩过的坑一次性讲清楚,希望能帮你少走几个月的弯路。

1. 先想清楚:AI 工程到底在解决什么问题

1.1 它和“调 API”不是一回事

很多人有个误解:AI 工程就是拿大模型 API 拼聊天窗口。如果真这么简单,那这个岗位就不会开出这么高的薪资了。

我理解的 AI 工程,是把一个大模型从一个“试用阶段的东西”变成“稳定生产系统”的全部工作。它至少包含五个板块:

  • 提示工程:把业务需求翻译成模型能理解、能稳定执行的输入。
  • 检索增强(RAG):把外部知识、私有数据交给模型,让它回答得准而不是瞎编。
  • Agent 能力:让模型不只是“说”,而是能调工具、执行动作、完成多步任务。
  • 部署与推理优化:把模型放到服务里,控制延迟、吞吐和成本。
  • 评估与监控:用数据说话,保证每次改动不会让效果变差。

这五块不是割裂的,是一条完整链路。从零开始学的时候,千万别光抓着“提示词”这一个点死磕,提示词是基本功,但不是全部。

1.2 从零开始的正确路径是什么

我见过太多人一上来就啃 Transformer 论文、从头复现 LLaMA,结果被数学公式劝退,然后就没有然后了。

作为一个过来人,我给的建议是**“应用驱动,倒推知识”**:

  1. 先跑通一个最简单的调用。
  2. 做一个带知识库的问答系统,理解 RAG。
  3. 再做带工具调用的 Agent,理解模型怎么和外部世界交互。
  4. 然后把它部署成服务,理解并发、延迟、成本。
  5. 最后回来补基础,比如注意力机制、token 原理、采样参数,这时候你再看理论,会觉得全都对得上。

这条路最大的好处是:每个阶段都有看得见的成果,人不容易放弃。

2. 入门技术栈与工具选型:别被“全家桶”忽悠了

2.1 提示工程先打底,这是性价比最高的投入

我至今觉得,提示工程是 AI 工程里“投入产出比”最高的一项技能。不需要显卡,不需要买课,不需要复杂的代码,把模型的行为逻辑理解透就行。

核心要掌握的四个方法:

  • 角色设定:给模型一个明确的身份和行为边界。
  • 少样本示例(Few-shot):与其解释一堆抽象规则,不如直接给 2-3 个输入输出例子。
  • 思维链(Chain-of-thought):让模型“先分析再输出”,对复杂推理任务效果提升非常明显。
  • 结构化输出:用 JSON Schema 或 XML 标签约束输出格式,方便后续代码解析。

我自己写提示词有个习惯:先写“你是做什么的、你能做什么、不能做什么”,然后给 2 个示例,再进入正式输入。不要写“请”“亲爱的”这些废话,模型不需要礼貌,需要的是清晰。

2.2 应用框架怎么选:别一上来就上框架

现在主流的框架有 LangChain、LlamaIndex,还有 Spring AI 这类偏向 Java 生态的(如果你的团队是 Java 技术栈,Spring AI 很值得关注)。

但我的建议是:前两周亲自用裸 Python 代码调模型,不要碰框架。因为你只有先用纯代码体验过“把文本切开、转成向量、塞进向量库、搜出来、拼给模型”这个过程,你才能真正理解框架帮你省了什么工作量。不然框架对你来说就是一个黑盒,出问题你完全不知道从哪排查。

之后再用框架,也不是全盘照抄。LangChain 我常用到的其实就那几个:DocumentLoader、TextSplitter、Embedding、VectorStore、Retriever、ChatPromptTemplate。其余概念网上吹得天花乱坠,实际生产里用得很少。

2.3 模型部署和推理工具链是分水岭

很多人做 demo 很流畅,一到部署就卡壳。这里我给你一条可以直接照抄的选型路线:

场景工具说明
快速实验 / 个人项目云端模型 API成本低、上手快,适合验证想法
私有化部署 / 数据敏感vLLM 或 TGI高吞吐推理引擎,兼容 OpenAI 接口协议
中小团队推理服务vLLM + FastAPI部署灵活,可控性强
大规模集群KServe + K8s自动伸缩、多模型管理,运维成本高

这里我特别推荐 vLLM,它在吞吐优化上做得非常激进,连续批处理、PagedAttention 这些技术能让同样一张显卡跑出大几倍的请求量。后文我会专门演示怎么用它。

3. 实操:从零搭一个 RAG 知识问答系统

3.1 整体设计思路

假设咱们要做一个“公司内部规章制度问答机器人”。传统的做法是把文档放在某个目录里,让人自己翻,现在我们要让模型基于文档内容来回答。

整体流程拆开就三步:灌知识(索引)、搜知识(检索)、生成答案(生成)。每一步都有对应的工程决策。

我画一个最简链路给你看:

  • 读入 PDF / Word / 网页文本
  • 按语义切分成长度合适的片段
  • 每个片段用 Embedding 模型转成向量
  • 向量存入向量数据库
  • 用户提问时,把问题转成向量,做相似度检索
  • 把检索到的片段和问题拼接成 Prompt
  • 模型综合上下文给出答案,并标注来源

3.2 文档切分:细节决定 RAG 的上限

说实话,RAG 系统效果烂,八成问题出在切分上,而不是模型上。切分太粗,片段里包含大量噪声,检索召回不精确;切分太细,单个片段语义不完整,模型也答不到点上。

我在实际项目里常用的策略是**“按结构优先、按长度兜底”**:

  • 如果是 Markdown 或带标题的文档,先按标题层级切,尽量保证一个二级标题下的内容作为一个整体。
  • 如果没有结构,用固定长度切,中文一般 300-500 字一个 chunk,重叠 50-100 字。
  • 不要小看重叠部分,它能避免句子被拦腰截断导致语义丢失。

一个简单的切分代码骨架:

from langchain_text_splitters import RecursiveCharacterTextSplitter splitter = RecursiveCharacterTextSplitter( chunk_size=400, chunk_overlap=80, separators=["\n\n", "\n", "。", "!", "?", ".", "!", "?", " "], ) chunks = splitter.split_text(long_text) print(len(chunks))

这里的 separator 顺序很重要:先按段落,再按句子,最后按单词。这个顺序能最大程度保留语义完整性。

3.3 Embedding 与向量库选型

Embedding 模型负责把文本变成向量。选型标准有三个:维度中文效果部署成本

  • 目前中文场景比较常用的是 BGE、M3E 系列的 Embedding 模型,效果不错而且可以在本地跑。
  • 如果你的数据以英文为主,OpenAI 的 text-embedding-3-small 也够用。
  • 注意一个坑:检索用的 Embedding 模型要和生成模型区别对待,它不追求“会说话”,只追求“语义距离准确”。

向量数据库的选择,我从三个档位给你参考:

档位方案适用场景
入门Chroma / FAISS个人项目、文档量百万以下
生产Milvus / Qdrant需要高并发、复杂过滤
轻量运维PostgreSQL + pgvector团队已有 PG,不想引新组件

我个人最喜欢 pgvector。因为它不需要单独维护一套数据库,业务数据也在 PG 里,直接就能做 SQL 级别的过滤,比如“只检索部门 A 的文档”,非常方便。

3.4 检索:不是搜出来就完事

检索之后要不要重排序?我的答案是:如果你的数据量超过 1 万条,强烈建议加

第一次向量检索召回 Top 20,再用一个轻量的 Cross-Encoder 模型对这 20 条做精确打分,取 Top 5 给到模型。这样做的好处是,第一阶段向量检索负责“宽进”,把候选尽量捞全,第二阶段精排负责“精选”,把真正相关的排到前面。

这里附一个完整 RAG 检索端代码:

from qdrant_client import QdrantClient from qdrant_client.models import Distance, VectorParams from bge_embedding import BGEEncoder # 伪代码,按你的模型导入 encoder = BGEEncoder() client = QdrantClient(host="localhost", port=6333) # 建集合 client.create_collection( collection_name="company_docs", vectors_config=VectorParams(size=768, distance=Distance.COSINE), ) # 写入向量 points = [ {"id": i, "vector": encoder.encode(chunk), "payload": {"text": chunk}} for i, chunk in enumerate(chunks) ] client.upsert(collection_name="company_docs", points=points) # 查询 query_vec = encoder.encode("请假流程是什么") results = client.search( collection_name="company_docs", query_vector=query_vec, limit=20, )

3.5 生成环节:把 Prompt 拼对,答案质量翻倍

很多人以为生成环节就一段用户问题、一段检索内容拼一起就行了,实际上你把顺序和结构控制好,效果差异非常大。

我的 Prompt 模板长这样:

你是一家公司的行政助手,请根据【资料】中的内容回答用户的问题。 要求: 1. 只能基于资料回答,不要编造。 2. 如果资料里没有答案,明确说“资料中未找到相关信息”。 3. 用简洁的中文回答,可以分点。 4. 最后一行附上你参考的资料编号。 【资料】 [1] 请假三天以内,需部门主管审批... [2] 请假三天以上,需分管副总审批... 【用户问题】我要请一周假,应该找谁审批?

这句话其实是 RAG 组合的正确姿势,把检索到的内容放在用户问题之前。实测下来,上下文放在前面比放在后面,模型的回答稳定性更高。

4. 再进一步:把 RAG 升级成 Agent

4.1 为什么 RAG 还不够

RAG 能解决“知识型问答”,但它有个明显的天花板:它只会查,不会做

比如用户问“帮我查一下这个月的服务器账单,超过预算就发邮件给财务”。这里涉及到数据库查询、判断逻辑、发邮件这三个动作,这不是简单的检索生成能搞定的,你需要 Agent。

Agent 的核心思想叫ReAct:模型交替进行“思考(Reasoning)”和“行动(Acting)”。模型可以请求调用工具,工具返回结果后再决定下一步,直到任务完成。

用一句话说:RAG 是让模型“知道得多”,Agent 是让模型“做得了”

4.2 一个最小 Agent 的长什么样

以 OpenAI Function Calling 或通用工具调用协议为例,模型输入不再是纯文本,而是带有一组“工具说明”。模型在回答时会生成一个结构化的调用请求,我们解析这个请求,执行对应代码,把结果返回给模型。

一个工具调用的最小实现长这样:

import json from openai import OpenAI client = OpenAI() tools = [ { "type": "function", "function": { "name": "get_server_bill", "description": "获取指定月份的服务器账单金额", "parameters": { "type": "object", "properties": { "month": {"type": "string", "description": "月份,如 2026-01"}, }, "required": ["month"], }, }, } ] messages = [{"role": "user", "content": "一月份账单是多少?"}] response = client.chat.completions.create( model="gpt-4o", messages=messages, tools=tools, ) # 看模型是否想调用工具 print(response.choices[0].message.tool_calls)

经典的坑是:模型说出“我要调用 get_server_bill 工具”但代码里根本没有对应的执行逻辑,或者工具名称写错匹配不上。你需要在工具层做一层注册表,把函数名和实际函数绑定,并加超时和异常处理。

4.3 规划、记忆与人工兜底

Agent 在真实生产环境里,比 RAG 难得多。核心难点在三个地方:

  • 规划失败:模型在复杂任务上容易漏步骤,或者步骤顺序不对。我建议把复杂任务拆成子任务,别指望模型一次规划到底。
  • 记忆混淆:多轮对话中,模型容易把当前轮次和之前轮次的信息混在一起。每个 Agent 会话要有独立的记忆空间,按轮次组织。
  • 不可逆操作:涉及发邮件、删除数据、扣款这类高风险动作,一定要设计“二次确认”。我的做法是:工具调用先进入“待确认”队列,由用户在前端点击确认后才真正执行。

Agent 不是玩具,它需要你比做 RAG 的时候更谨慎。

5. 部署、评估与监控:让应用真正能上线

5.1 模型推理服务化

如果你用的是云端 API,这部分很简单,就是常规的 Web 服务开发。但如果你的场景要求私有化部署,那就绕不开推理引擎。

我强烈建议用 vLLM 部署开源模型。它极其适合中文场景,也支持 OpenAI 兼容接口,意味着你本地起一个服务后,代码里只需要改一个 base_url 就能把 API 调用平滑迁移到本地模型。

启动一个 vLLM 服务很简单:

pip install vllm vllm serve Qwen/Qwen2.5-7B-Instruct \ --host 0.0.0.0 \ --port 8000 \ --tensor-parallel-size 1 \ --gpu-memory-utilization 0.85 \ --max-model-len 8192

启动后,你的代码里只需要:

from openai import OpenAI client = OpenAI(base_url="http://localhost:8000/v1", api_key="EMPTY") resp = client.chat.completions.create( model="Qwen/Qwen2.5-7B-Instruct", messages=[{"role": "user", "content": "你好"}], )

前后端代码一行不改就能切换模型,这个统一接口标准的好处你越用越能体会到。

5.2 评估:没有指标,改动就是开盲盒

我一直有个观点:没有评估体系的 AI 项目,等于没有刹车系统的车。你今天换了一个 Prompt,感觉回答“好像变好了”,但你不知道是不是只是这一条变好了,另外十条变差了。

我初期踩过最大的坑就是靠感觉调优,今天调调这个明天换换那个,效果时好时坏。后来我学乖了,花一天时间建了一个 100 条问题的评测集,每条问题包含:

  • 标准问题
  • 参考答案关键词
  • 期望来源文档

之后每次改动,跑一遍评测集,统计几个关键指标:

指标含义衡量方式
命中率回答里是否包含参考答案的关键信息关键词匹配或 LLM 评分
幻觉率回答里是否有材料外的编造内容人工抽检 + 引用溯源
检索召回正确文档是否被检索到计算命中比例

跑评测集这个过程很枯燥,但是它能帮你守住底线:每次改动至少不会让整体效果倒退。

5.3 线上监控:日志比你想的重要

上线第一天,你觉得一切完美。第三天,有用户反馈回答开始出错。你查了半天,发现是文档库被误更新了。这种事故我见过不止一次。

所以,一个 AI 应用上线前,必须把日志做全。我自己的日志体系分成三层:

  • 请求日志:用户问题、完整 Prompt、模型输出、耗时、token 数。
  • 链路日志:检索了哪些文档、每个文档的分数、重排序结果。
  • 反馈日志:用户是否有点赞/点踩、是否复制了回答、是否有二次提问。

有了这些数据,你才能做三件事:定位问题、分析用户真实需求、持续迭代。否则它就是个黑盒。

6. 常见问题与避坑实录

6.1 高频问题速查表

问题现象根本原因解决方案
回答内容跟给的材料无关检索失败,向量召回质量差检查 Embedding 模型、增加重排序、调整切分粒度
回答还没材料就结束了Prompt 对资料引用约束太弱强化“只能依据资料”的指令,并限制输出长度
同一问题多次回答不一致采样温度太高把 temperature 调到 0-0.3,或固定 seed
模型开始瞎编知识库没覆盖该问题加入“未知即未知”的 Prompt 兜底,并完善知识库
服务并发一高就超时推理引擎配置不足上 vLLM,开启连续批处理,或加节点

6.2 几个我反复踩过的坑

第一个坑:盲目追求大模型。我一开始直接用 72B 的模型,效果确实好,但成本爆炸。后来换成 7B + 做好的 RAG 和 Prompt,业务效果几乎没差。工程上,先优化数据,再优化 Prompt,最后才考虑换大模型,这个顺序别搞反。

第二个坑:把 Embedding 模型和业务模型混用。有的团队为了省事,直接用同一个模型做 Embedding 又做生成。这是彻头彻尾的错误,Embedding 模型追求表示学习,生成模型追求文本生成,两者任务完全不同,硬混用效果一定差。

第三个坑:对检索结果不加过滤。一开始我不管相似度分数多低,都塞给模型。结果就是明明没有相关内容,模型还要硬答。后来加了一个相似度最低阈值,低于阈值就提示“知识库暂无相关内容”,反而用户满意度提高了。

第四个坑:没有注意 token 消耗。检索回来的文档片段是越多越好吗?不是。3 个片段能讲清楚的,不要喂 10 个片段。因为上下文拉长以后,模型容易注意力发散,回答质量下降,还费钱。我的习惯是从少到多调,先给 3 个片段,不够再加。

6.3 给新人的几条建议

如果你也是从零开始,我很想告诉你三件事:

  • 不要跳过基础。至少要搞懂 Token 是什么、嵌入向量维度意味着什么、相似度是怎么算的、温度参数影响的是什么。这些基础不牢,后面每一步都像踩在棉花上。
  • 一定要亲手写一遍 RAG。不要复制。从读文件、切分、Embedding、向量检索,到拼 Prompt,跟着代码逐行走一遍,这个过程的价值远超刷十遍教程。
  • 多跟行业的人交流。AI 工程更新迭代太快,一个人闷头学容易走偏。找到同路的人互换经验,比自己闭门造车高效得多。

我自己刚入门那阵,也经常因为跑不通一个效果沮丧到想放弃。后面慢慢明白,AI 工程跟传统软件开发最大的不同是:它带有一层“不确定性”。你不能像写业务代码那样期望一次就对,你要学会用数据、日志和评估去逼近一个“稳定可用”的状态。

这条路没有终点,但每一步积累的能力都是真实的。希望这篇长文能帮你把 roadmap 看清楚,少踩几个我踩过的坑。动手永远是第一步,跑起来再说。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询