2026年再谈AI大模型应用开发,重点已经不是背诵几个名词,而是能不能把一个模型真正接入业务系统并稳定运行。很多开发者在学习时容易走两条弯路:要么只刷提示词技巧,一碰到工程化就断掉;要么一上来就研究微调,结果连上下文溢出和检索问题都解决不了。这里按两周训练营的思路,把大模型应用开发的主线拆成模型接入、提示词工程、RAG、Agent、评估与部署六个部分,每一部分都给出可运行的最小示例、验证方式和常见坑。学完后,你至少能独立完成一个带有本地知识库和工具调用的小应用,也具备继续深入微调、分布式推理和复杂Agent的工程基础。
1. 先搞清楚大模型应用开发到底在开发什么
1.1 与CRUD应用的区别
传统Web应用开发的核心是“状态和事务”:用户登录、写入数据库、读取列表、更新状态,流程是确定的。大模型应用开发的核心变成了“模型输入输出和不确定性”:同一个问题,模型可能给出不同答案;同一个提示词,换一个模型可能表现完全不同。
这带来两个直接影响。
第一,开发重心从写业务逻辑变成了写“模型周边工程”。模型本身是黑盒,你无法通过改代码让模型“学会”某个私有知识点,只能通过提示词、检索增强、外部工具和必要的微调来引导它。第二,验证方式从单测变成了“评估体系”。你不能只断言返回了200 OK,还需要判断答案是否相关、是否准确、是否有幻觉。
1.2 一条主线:模型、数据、流程、交付
大模型应用开发看起来包罗万象,但主线很清晰,可以拆成四层。
第一层是模型层,解决“用哪个模型、用云端还是本地、怎么接入”。第二层是数据层,解决“模型不知道的私有知识怎么补进来”,常见方案是RAG和微调。第三层是流程层,解决“模型如何完成多步任务、如何调用外部工具”,也就是Agent。第四层是交付层,解决“如何稳定上线、监控、评估、回滚”。
两周学习路线按这四层展开,不追求把所有模型API都看一遍,而是把每一层的关键动作做一遍。只要任意一层有短板,最终应用都跑不稳。
1.3 两周学习目标
第一周目标:能调用大模型API,掌握提示词工程,跑通一个基于RAG的私有知识库问答应用。第二周目标:能实现带工具调用的Agent,理解微调适用场景,把一个应用以较完整的方式部署到服务器,并建立基本评估能力。
这个目标不是“学会所有模型”,而是建立一条可复用的项目骨架。后续换成任何新模型、新框架,都可以往这条主线上填。
2. 环境准备:先跑通一次大模型调用
2.1 开发环境清单
学习阶段不需要昂贵的服务器。一台普通开发机能跑代码,再按需选择云端API或本地模型即可。建议环境如下。
| 工具 | 版本建议 | 用途 |
|---|---|---|
| Python | 3.10 以上 | 编写调用、数据处理和Agent逻辑 |
| Node.js | 18 以上 | 前端页面或服务端集成,按需准备 |
| Ollama | 最新稳定版 | 本地运行大模型和嵌入模型 |
| Git | 2.30 以上 | 保存代码版本 |
| VS Code | 最新版本 | 开发调试 |
| Docker | 20.10 以上 | 部署阶段使用,可按需安装 |
实际项目里还要准备Python虚拟环境。这里推荐在项目根目录下运行:
python -m venv .venv source .venv/bin/activate # Windows 使用 .venv\Scripts\activate pip install openai python-dotenv chromadbopenai包不只是给OpenAI官方服务用,很多云端和本地服务都提供OpenAI兼容接口,统一用这个SDK可以降低切换成本。chromadb用于RAG阶段的向量存储。
2.2 云端API与本地部署怎么选
模型获取方式直接决定开发体验。云端API的好处是开箱即用,不需要关心显存和推理性能;本地部署的好处是数据不出内网、按次调用成本低,适合定制化场景。
| 维度 | 云端API | 本地Ollama部署 |
|---|---|---|
| 上手速度 | 快,注册后即可调用 | 需要下载模型,受网络和磁盘影响 |
| 硬件要求 | 低,只需要网络请求 | 至少16GB内存,7B模型可用CPU运行但较慢 |
| 数据隐私 | 依赖服务商数据政策 | 数据保留在本地,相对可控 |
| 成本 | 按Token或额度计费 | 主要是硬件和电费,使用量大时更便宜 |
| 适合场景 | 快速原型、生产高并发 | 离线环境、隐私敏感业务 |
学习阶段建议两种方式都跑通。先通过云端API验证业务逻辑,再在本机用Ollama跑通同一个OpenAI兼容接口,这样能理解不同模型服务之间的差异。
2.3 用Ollama本地跑通最小调用
首先安装Ollama并按要求拉取模型,常见命令如下:
ollama pull qwen2.5:7b ollama run qwen2.5:7bollama run可以进入交互式对话,先确认模型能正常回复。然后写一个最小Python调用。Ollama本地启动后默认监听11434端口,并暴露OpenAI兼容接口。
from openai import OpenAI client = OpenAI( base_url="http://localhost:11434/v1", api_key="ollama", # 本地服务不检查key,但SDK要求非空 ) resp = client.chat.completions.create( model="qwen2.5:7b", messages=[ {"role": "system", "content": "你是一个简洁的技术助手。"}, {"role": "user", "content": "用一句话解释RAG。"} ], temperature=0.7 ) print(resp.choices[0].message.content)这段代码的关键是base_url。本地模型和云端模型的接口路径通常都是/v1,所以只需换base_url、api_key和model,项目里的其他调用逻辑基本不用改。
不要理所当然以为api_key随便填就行。部分本地代理服务会校验Key格式,如果报401,改成服务端要求的占位符或真实Key。
2.4 用OpenAI兼容接口接入云端API
云端API只需要把base_url换成服务商地址,api_key换成真实Key。生产环境不要硬编码在源码里,推荐用环境变量。
from openai import OpenAI import os client = OpenAI( api_key=os.getenv("LLM_API_KEY"), base_url=os.getenv("LLM_BASE_URL"), ) resp = client.chat.completions.create( model=os.getenv("LLM_MODEL"), messages=[{"role": "user", "content": "你好"}] ) print(resp.choices[0].message.content)在项目根目录创建.env文件保存密钥,然后使用python-dotenv加载:
LLM_API_KEY=your_key_here LLM_BASE_URL=https://your-provider.example.com/v1 LLM_MODEL=your-model-name调用脚本前先运行:
pip install python-dotenv注意:不要只验证程序能输出一句话,还要测试错误情况,比如Key错误、模型名错误、网络超时分别会抛出什么异常。
3. 第一周上半场:提示词工程与结构化输出
3.1 提示词工程的基本作用
提示词工程不是简单堆话术,而是通过限定角色、任务、约束和示例,让模型输出更接近预期。模型本身没有“理解业务规则”的能力,它只会根据上下文预测最可能的输出。提示词本质上是把业务规则翻译成模型能理解的形式。
一个容易忽略的点是:提示词也会影响性能和成本。提示词越长,每次请求消耗的Token越多,响应可能越慢。因此在设计提示词时,要同时考虑效果、延迟和费用,不能只追求“写得更详细”。
3.2 设计高质量提示词的模板
一个可复用的提示词框架建议包含五个部分:
- 角色:模型以什么身份回答。
- 任务:模型要完成什么动作。
- 约束:不能做什么,必须做什么。
- 上下文:提供给模型的外部信息。
- 示例:一两个输入输出样例。
例如:
system_prompt = """ 你是一个产品工单分类助手。 任务:将用户工单划分到【网络故障、账号问题、支付问题、其他】四类之一。 约束:只输出分类名称,不要输出解释。 示例: 用户问题:我的余额没有到账。 输出:支付问题 """有了角色、任务、约束、示例,模型输出稳定性会明显提高。真实项目中可以把这个模板保存为常量或配置文件,方便调整。
3.3 拿到稳定JSON输出
大模型应用很少只输出给人看的文字,更多时候需要程序继续处理。如果让模型输出JSON,最好使用结构化输出能力,同时用提示词约束。
resp = client.chat.completions.create( model="qwen2.5:7b", messages=[ {"role": "system", "content": "你是信息抽取助手。请从用户内容中抽取人物、地点、时间,只输出JSON,不要输出解释。"}, {"role": "user", "content": "张三昨天下午在上海参加了AIGC技术沙龙。"} ], response_format={"type": "json_object"}, temperature=0 ) content = resp.choices[0].message.content print(content)输出可能如下:
{ "person": "张三", "location": "上海", "time": "昨天下午" }注意:部分本地模型对response_format支持不稳定。稳妥做法是在提示词里要求JSON,然后在代码里加一层解析和兜底:
import json try: data = json.loads(content) except json.JSONDecodeError: # 在这里做一次清洗或重新请求 print("输出不是合法JSON,原内容:", content)3.4 这一阶段最容易踩的坑
第一个坑是幻觉式使用JSON模式。不是所有兼容接口都支持response_format,调用前必须看文档或试跑,否则可能静默返回普通文本。
第二个坑是忽略temperature的影响。分类、抽取类任务建议设为0或接近0;文案生成可以适当调到0.7以上。不能一套参数走天下。
第三个坑是把所有内容都塞进提示词。当私有知识很多时,提示词会超出上下文限制,而且费用上涨。正确做法是引入检索,只把相关内容放入提示词,这就是下一章的RAG。
4. 第一周下半场:RAG帮你把私有知识接进大模型
4.1 RAG解决什么问题
大模型训练完成之后,知识就固定了。它不知道你公司的内部规章、最新产品文档,也容易混淆近期事件。RAG(Retrieval-Augmented Generation)的思路是:不直接让模型硬记,而是先从知识库中检索出和用户问题最相关的片段,再把这些片段作为上下文交给模型生成答案。
RAG的优势是知识可更新。文档改了,只需要更新向量库,不需要重新训练模型。这也让它成为大多数私有知识库应用的首选方案。
4.2 最小RAG系统的四步实现
最小RAG系统只需要四条链路:文档分块、向量化、相似度检索、生成回答。
先准备嵌入模型并封装一个函数:
from openai import OpenAI llm = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama") emb_model = "nomic-embed-text" def embed_text(text: str): resp = llm.embeddings.create(model=emb_model, input=text) return resp.data[0].embedding然后把文档写入向量库:
import chromadb vector_client = chromadb.PersistentClient(path="./rag_db") collection = vector_client.get_or_create_collection(name="docs") collection.add( ids=["doc_1"], embeddings=[embed_text("检索增强生成是一种把外部知识接入大模型的方法。")], documents=["检索增强生成是一种把外部知识接入大模型的方法。"] )用户提问时先检索:
query = "什么是RAG?" query_vec = embed_text(query) results = collection.query( query_embeddings=[query_vec], n_results=1 ) context = results["documents"][0][0] print(context)最后把检索结果和问题一起拼进提示词,调用模型生成答案:
prompt = f"""请根据下面的资料回答问题。 资料:{context} 问题:{query} 如果资料无法回答,请直接说不知道。""" answer = llm.chat.completions.create( model="qwen2.5:7b", messages=[{"role": "user", "content": prompt}] ) print(answer.choices[0].message.content)这个示例虽然简单,但已经覆盖了RAG全流程。真实项目还需要处理PDF解析、文本清洗、分块策略和增量更新。
4.3 向量数据库选型建议
向量数据库不是只有一种选择,关键是看数据量、部署方式和运维成本。
| 方案 | 适合场景 | 说明 |
|---|---|---|
| Chroma | 本地学习、原型验证 | 轻量,可直接嵌入Python进程 |
| FAISS | 中等规模向量检索 | 库式使用,无独立服务 |
| Milvus | 生产海量向量检索 | 分布式,需要独立部署 |
| pgvector | PostgreSQL已有场景 | 复用数据库,减少组件 |
学习阶段先选Chroma,因为它安装简单、无额外服务,能让你专注理解RAG逻辑。进入生产后,再根据QPS和数据量评估是否需要独立向量数据库。
4.4 RAG效果不好时先查这几处
RAG常见问题基本集中在三处。
第一,检索不准确。检查分块大小是否合适,块太大噪音多,块太小语义不完整;还要确认使用的嵌入模型是否与文档语言匹配。第二,上下文拼装混乱。检索到的片段不能直接堆在一起,要加分隔符,并按相关性排序。第三,模型对资料理解不足。有时需要明确告诉模型“优先使用资料,不要编造”,并且当资料不相关时要允许回答“不知道”。
建议:RAG上线前准备10个典型问题和预期答案,每次调整后都跑一遍,再判断修改是否有效。不能只凭一两个例子下结论。
5. 第二周上半场:从问答走向Agent
5.1 Agent的本质是循环而不是聊天框
很多初学者把Agent理解为“能对话的机器人”,这并不准确。Agent的核心在于“模型—工具—环境”的循环:模型根据用户目标生成下一步动作,应用执行动作并返回结果,模型再根据新结果决定下一步,直到完成目标。
与一次性的问答不同,Agent需要自己决定调用哪个工具、工具参数是什么、结果如何判断。这个决策过程会让应用从“会说话”变成“能办事”。
5.2 用工具调用扩展模型能力
要让Agent调用外部能力,第一步是定义工具。以查天气为例,定义一个结构化工具描述:
tools = [ { "type": "function", "function": { "name": "get_weather", "description": "获取指定城市的当前天气", "parameters": { "type": "object", "properties": { "city": {"type": "string", "description": "城市名称"} }, "required": ["city"] } } } ]调用模型时传入tools参数:
messages = [{"role": "user", "content": "上海今天适合穿短袖吗?"}] resp = llm.chat.completions.create( model="qwen2.5:7b", messages=messages, tools=tools, tool_choice="auto" ) message = resp.choices[0].message print(message.tool_calls)模型并不真正执行函数,它只返回一个工具调用请求,包含函数名和参数。应用需要自己执行对应函数,然后把结果作为新的消息传给模型,让模型生成最终回答。
5.3 最小Agent示例
实现一个最小Agent,核心是一次“工具调用—结果回填—最终生成”流程。
先写一个模拟天气函数:
def get_weather(city: str): # 生产环境应接入天气服务API return {"city": city, "weather": "多云", "temperature": 26}收到模型的工具调用请求后执行函数:
if message.tool_calls: # 将模型请求追加到消息历史 messages.append(message) for tool_call in message.tool_calls: tool_name = tool_call.function.name args = json.loads(tool_call.function.arguments) if tool_name == "get_weather": result = get_weather(args["city"]) messages.append({ "role": "tool", "tool_call_id": tool_call.id, "content": json.dumps(result) }) # 把工具结果交回模型,生成最终回答 second = llm.chat.completions.create( model="qwen2.5:7b", messages=messages, tools=tools ) print(second.choices[0].message.content)这个流程体现了Agent的最基本形态:模型提出调用请求,应用执行,结果回传,模型生成回答。后续可以扩展为多轮工具调用、并行工具调用,以及对工具结果的异常处理。
5.4 Agent的安全边界
Agent越强大,越要控制风险。必须限制工具集,不能让模型随意调用删除、支付、发送消息等敏感操作。工具入参要做校验,不能直接信任模型生成的参数;执行端要加权限校验,并对每一次工具调用记录日志。
此外,模型可能会重复调用同一个工具,或陷入循环。生产环境建议设置最大循环次数,比如3到5轮,超过后强制终止并给出失败提示。不要把一个没有任何校验的Agent直接暴露到公网。
6. 第二周下半场:微调、评估与部署
6.1 什么时候才需要微调
微调看起来是“让模型学会新知识”,但它并不适合所有场景。如果你的目标是补充私有知识,RAG通常更快速、更容易更新。微调更适合改变模型的“行为风格”或“输出格式”,例如让模型始终使用固定术语、深度模仿某种语气、或者稳定输出特定行业报告。
以下情况可以优先考虑微调:
- 提示词无论怎么设计,模型仍然无法稳定输出目标格式。
- 需要模型具备特定领域的表达风格和专业术语。
- 已经积累了大量高质量的成对问答数据。
- 推理成本可以接受,希望降低提示词长度。
如果只是告诉模型“知道某个新文档”,不要直接微调。先把RAG做好,再判断是否有剩余问题。
6.2 微调的基本流程
微调的典型流程是:数据准备、数据格式转换、训练、评估、部署。
首先准备一批样本,每条样本通常是对话格式:
[ { "messages": [ {"role": "system", "content": "你是工厂设备诊断助手。"}, {"role": "user", "content": "设备报E202错误怎么办?"}, {"role": "assistant", "content": "请先检查传感器连接线,再查看驱动版本。"} ] } ]然后选择基座模型和训练平台。学习阶段可以先用小规模数据集跑通流程,不要一开始就追求效果。训练完成后仍要做评估,确认微调没有破坏原有能力。
微调不是一次到位,通常要对比基座模型和微调模型的输出,才能判断投入是否值得。如果数据质量不高,微调后的效果可能反而更差。
6.3 模型评估不能只看感觉
大模型应用最容易犯的错误是“试了几个例子觉得效果不错就上线”。正确做法是建立固定的评估集,包含正常输入、边界输入和错误输入三类。
评估维度建议包括:
- 相关性和准确性:回答是否切题,事实是否有误。
- 稳定性:同一问题多次回答是否一致。
- 格式遵守度:是否严格输出JSON或固定结构。
- 安全性和合规性:是否输出违规内容。
- 延迟和成本:单次请求耗时和Token消耗。
可以先用Excel或CSV维护一批测试用例,每次修改代码、提示词或模型后统一跑一遍,把结果记录下来。条件成熟后再引入自动化评测框架。
6.4 生产部署还需要补哪些环节
开发环境跑通只是第一步。生产部署至少还要补上以下环节:
- 配置外置化,API Key、模型名、向量库地址不能写死在代码里。
- 日志和监控,记录请求、响应、Token用量、错误类型和耗时。
- 内容安全过滤,不能把未加审核的模型输出直接展示给用户。
- 超时、重试、熔断,防止上游模型服务不可用拖垮整个应用。
- 权限和限流,防止接口被刷,保护模型调用成本。
- 回滚方案,新模型或新提示词上线后如果效果变差,要能快速切回旧版本。
生产环境还有一个常被忽略的问题:模型服务和应用服务要解耦。尽量把模型调用封装成独立模块,后续更换模型或接入多个模型时,不用改动业务层代码。
7. 常见问题排查:从报错到根因
7.1 API调用与本地部署的典型报错
落到实际开发中,你会遇到大量报错。下面这张表可以作为排查起点。
| 问题现象 | 可能原因 | 检查方式 | 处理建议 |
|---|---|---|---|
| 请求返回401/403 | API Key错误、过期或无权限 | 检查环境变量和密钥状态 | 重新生成密钥,确认请求头携带正确 |
| 返回model not found | 模型名与平台不匹配 | 查看模型列表或本地ollama list | 使用正确模型标识,或先拉取模型 |
| 请求超时 | 模型过大、网络不稳定或接口无响应 | 查看耗时曲线和服务器日志 | 增加超时时间,换小模型,检查网络连通性 |
| 上下文长度超限 | 输入和输出总Token超过模型限制 | 统计Token数,查看报错内容 | 减少文档长度,使用检索只传入相关片段 |
| 输出不是合法JSON | 模型或兼容接口不支持结构化输出 | 打印原始返回内容 | 在提示词中约束JSON,并加代码解析兜底 |
| 向量检索结果无关 | 分块过大、嵌入模型不匹配 | 打印检索片段人工判断 | 调整分块大小和重叠,更换嵌入模型 |
| 本地Ollama响应很慢 | CPU推理或模型过大 | 观察CPU、内存占用 | 换量化小模型,或使用GPU推理 |
排查顺序建议按照“输入是否正确 → 环境变量和路径 → 模型名和接口地址 → 依赖版本 → 日志异常 → 工具自身限制”去推进,不要一上来就怀疑模型效果。很多时候问题出在base_url少写了一个/v1,或者.env文件没有被加载。
7.2 模型效果差的常规检查顺序
效果不好时,先不要急着换模型或开始微调。按以下顺序排查:
- 检查提示词是否足够明确,约束是否具体。
- 检查输入上下文是否包含足够有效的资料。
- 如果是RAG,检查检索结果与问题是否相关。
- 检查温度参数是否过高。
- 检查是否缺少示例,特别是输出格式示例。
- 最后再考虑更换模型或尝试微调。
这个顺序能解决大部分“模型不听话”的问题。
7.3 上线前检查清单
发布前把下面清单过一遍,能避免大多数低级故障。
- 密钥是否通过环境变量或配置中心管理,而不是写死在代码里。
- 是否设置了最大输出Token限制。
- 是否对用户输入做了长度限制和内容校验。
- 是否对模型输出做了非空、格式和安全性检查。
- 是否记录了请求日志和异常堆栈。
- 是否配置了超时和重试,且重试不会导致重复扣费或重复操作。
- 是否对向量数据库和模型服务做了可用性监控。
- 是否准备了一键回滚方案。
- 是否用固定评估集验证过新版本效果。
这份清单在新模型上线、提示词调整、依赖升级时都要重新检查一遍。
8. 两周后的复盘与下一步
8.1 两周验收清单
学习结束后,用下面这份清单自测是否达到目标。
- 能通过OpenAI兼容接口调用云端API和本地Ollama模型。
- 能设计包含角色、任务、约束、示例的提示词。
- 能拿到并解析结构化JSON输出,且能处理解析失败。
- 能完成一个RAG流程:文档写入、向量检索、拼接上下文、生成回答。
- 能实现一个带工具调用的最小Agent。
- 能说清楚RAG和微调各自的适用场景。
- 能根据报错信息快速定位是Key、模型名、上下文还是网络问题。
- 能完成一个包含日志、配置外置和基本异常处理的部署流程。
如果每项都能做到,你已经具备独立开发大模型应用的基础能力。如果某项卡住了,建议回到对应章节,把最小示例重新跑一遍,再继续下一个目标。
8.2 可以继续深入的方向
完成两周主线路程后,可以按兴趣选择突破口。
- 工程方向:继续学习LangChain、LlamaIndex、Spring AI等框架,了解它们如何封装模型调用和Agent生命周期。
- 算法方向:深入嵌入模型、重排序、微调和量化技术,优化RAG效果和推理性能。
- 架构方向:研究多Agent协作、事件驱动架构、模型网关和可观测性。
- 数据方向:针对PDF、表格、扫描件等复杂文档设计更可靠的数据解析与分块策略。
- 安全方向:关注提示词注入、工具权限管控、输出内容审核等生产级问题。
每个方向都能和已有的两周基础衔接,不会从零开始。
8.3 对新手的学习建议
AI大模型应用开发更新很快,但核心主线相对稳定:模型接入、上下文管理、检索增强、工具调用、评估部署。不要迷信“换个新框架就能解决所有问题”,框架只是工具,真正的判断力来自你对模型特性和业务需求的理解。
建议保持一个小而完整的项目,比如个人知识库问答助手,每次学到新能力就往项目里加。这样既能巩固知识,也能在面试或工作中拿出真实作品。如果时间有限,不要贪多,先跑通一个最小闭环,再逐步扩展。这样比收藏大量教程但不动手要有效得多。