☰
AI工程从零到一:从API调用到系统化落地的完整路径
2026/9/29 19:16:38 网站建设 项目流程

从标题ai-engineering-from-scratch说开去:如果你以为 AI 工程就是把模型 API 接进来、调一调提示词就行,那大概率会在第一个真实项目里卡住。我自己就是从“能跑通”到“能上线”之间反复摩擦过来的,这中间真正值钱的不是某个大模型本身,而是一整套围绕模型的工程能力——提示词设计、上下文管理、检索增强、Agent 编排、部署监控、成本控制。这篇文章不打算铺开讲机器学习理论,而是直接给你一条从零到一、能落地复现的 AI 工程路径,适合刚入门的技术人,也适合已经写了几年业务代码、准备往 AI 方向转的开发者。

1. AI 工程到底在“工程”什么

1.1 从“调 API”到“做工程”的分水岭

很多新手第一次跑通大模型接口时都很兴奋,觉得 AI 应用不过如此:构造请求、拿到回复、渲染到页面上。但真正进入工程化之后,需要面对的是一堆和“模型能力”无关、却又决定成败的问题:用户并发上来时接口会不会超时、上下文越来越长时怎么控制成本、模型答错时有没有兜底、同样的需求换个说法结果怎么就不稳定了、线上出问题能不能定位到是哪一轮 Prompt 引起的。

这就是 AI 工程的第一课:模型是核心,但不是全部。你可以把大模型理解成一个能力很强但脾气古怪的实习生,AI 工程做的事,是把这个实习生的输入输出管起来,给它配好检索工具、记忆体、工作流程、质检机制,让它在一个可控的框架里发挥价值。评判一个 AI 系统的标准,也不再只是“回答得对不对”,而是稳定性、可维护性、可观测性、成本和用户体验的综合指标。

这个阶段最重要的转变,是从“我该怎么问”变成“系统该怎么设计”。同样是做一个问答机器人,初级做法是让用户直接提问、模型直接回答;工程化做法会拆成多级链路:先判断用户意图,再决定是走知识库检索、工具调用还是闲聊兜底,检索结果要经过重排过滤,上下文要按 token 预算裁剪,最后模型生成时还要做格式校验和引用溯源。

1.2 一条清晰的自学路线

如果现在让我重新规划一条“从零开始学 AI 工程”的路线,我会分成五个阶段,每个阶段都有明确的产出物,避免学了一堆概念却做不出东西。

  • 阶段一:模型基础与提示词入门。搞清楚 token、temperature、top_p、system/user/assistant 消息结构,学会写结构清晰的 Prompt。产出:一个能在命令行跑起来的问答脚本。
  • 阶段二:API 封装与上下文管理。自己实现会话历史、流式输出、超时重试、错误分类。产出:一个带多轮记忆的 Web 聊天后端。
  • 阶段三:RAG 与向量检索。理解 Embedding、向量库、切片策略,做文档问答。产出:一个能基于本地文档回答问题的知识库机器人。
  • 阶段四:Agent 与工具调用。掌握 Function Calling 原理,让模型自主决定何时调用外部工具,处理多步任务。产出:一个能查天气、查数据库、发通知的智能助手。
  • 阶段五:工程化落地。加入评估集、监控日志、成本核算、并发限流、缓存策略。产出:一个可以上线给真实用户使用的稳定服务。

我见过不少人一上来就啃 Agent 框架,结果连消息结构都没搞懂,出了问题根本不知道是框架的问题还是模型的问题。按这个路线走,每层都亲手实现一遍,后面用任何框架都会快很多。

2. 工具链选型:模型、框架与本地部署

2.1 模型怎么选:API 调用还是本地部署

模型选型是所有 AI 工程的第一个岔路口。市面上主流的选择不少,闭源 API 有 OpenAI 的 GPT 系列、Anthropic 的 Claude 系列,国内的 DeepSeek、通义千问、文心一言、Kimi 也都有开放的接口;开源阵营则有 Llama 系列、Qwen 系列、DeepSeek 开源版本、GLM 等。对大多数团队来说,选型可以从三个维度权衡:效果、成本、数据安全。

API 调用的好处是省心,最新最强的模型能力随开随用,不需要管 GPU、显存、运维。缺点是数据出站和不菲的长文本费用,还有一个容易被忽略的问题——你依赖的模型接口随时可能调整,版本升级、限流策略、定价变动都会影响业务。我建议从零起步的新人首选 API,先把产品逻辑和用户体验跑通,等真的有了稳定的需求场景,再评估要不要本地部署。

本地部署适合两种场景:一是数据绝对不能出内网,比如企业内部文档问答、医疗或金融数据;二是调用量特别大、API 成本高到难以承受。做法是拿开源模型配合推理框架自己跑。效果上,开源模型和顶级闭源模型在复杂推理上还有差距,但中等规模模型配合好的 RAG 和 Prompt 设计,很多场景已经足够用。

2.2 开发框架:Spring AI 与 TypeSafe AI 的取舍

语言选型和框架选型往往一起出现。Python 生态里 LangChain、LlamaIndex 名声最大,资料最多,适合快速验证想法;Java 生态里有 Spring AI 和 TypeSafe AI,后者脱胎于 ZIO,主打类型安全和函数式编程。

我自己在 Java 后端团队里做过一次框架选型对比,简单列一下观点:

框架语言核心特点适合场景学习成本
LangChainPython组件丰富、生态大快速原型、RAG、Agent中等
LlamaIndexPython数据管道强文档知识库中等
Spring AIJava和 Spring Boot 无缝集成企业后端集成中低
TypeSafe AIScala类型安全、函数式、可组合重工程化、追求可维护性高

这是一张非常多见的对比表。但在实际项目中,我的建议是:不要为了用框架而用框架。先拿原生 API 把一次对话、一次流式输出、一次工具调用写明白,再去看框架。否则框架帮你省掉的样板代码,会变成你排查问题时的黑盒。

Spring AI 的优势是让 Java 开发者在熟悉的依赖注入和资源配置方式下接入大模型,抽象了 ChatClient、EmbeddingModel 等接口。TypeSafe AI 则在复杂 Agent 和多步任务编排上更有想象力,但团队里得有能驾驭函数式编程的人。如果团队是 Java 背景,从 Spring AI 起步更稳。

2.3 本地部署实操要点

本地部署对新手来说最容易被网络上的各种“一键脚本”误导。我测下来最稳的组合是:Ollama 做轻量启动,vLLM 做高吞吐推理。前者适合个人电脑和开发环境,后者适合生产环境。

以 Ollama 为例,安装后拉取模型一条命令就能跑起来:

# 拉取 Qwen2.5:7B 模型 ollama pull qwen2.5:7b # 启动本地服务,默认监听 11434 端口 ollama serve

然后用任何语言调用本地 OpenAI 兼容接口:

from openai import OpenAI client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama") response = client.chat.completions.create( model="qwen2.5:7b", messages=[ {"role": "system", "content": "你是专业的AI工程助手。"}, {"role": "user", "content": "如何做RAG?"} ], stream=False ) print(response.choices[0].message.content)

注意一个关键点:显存不够时优先选量化版本,比如 Q4_K_M。7B 模型量化后大约 4.5GB 显存就能跑,Mac 上 M 系列芯片也能通过统一内存撑起来。我踩过的坑是盲目拉最大参数模型,结果加载阶段就 OOM,后来才意识到量化等级和模型参数量是两个维度的选择。生产环境如果有多人并发,Ollama 不一定够,vLLM 的连续批处理吞吐量要比它高一个量级。

3. 从零到一:一个可落地的 AI 应用实例拆解

3.1 需求锚定与方案设计

空谈技术架构没有意义,这里给你一个完整的最小案例:企业内部规章制度问答机器人。用户可以在对话框里问“年假折算是怎么规定的”“报销发票需要什么材料”,系统基于企业文档给出带出处的回答。

要满足这个需求,核心链路是文档解析、切片、向量化、语义检索、上下文组装、大模型生成。整体可以画成一个管线,但我不建议一上来就分布式,先用单机多进程把链路跑通,等数据量和并发上来再拆服务。

选型上,Embedding 模型可以用 OpenAI 的text-embedding-3-small,也可以用本地模型如bge-m3;向量库可以用 Chroma 起步,生产再切 Milvus 或 PostgreSQL 的 pgvector。选型的核心逻辑是:起步阶段用最少维护成本的组件,把核心链路的价值先验证掉。

3.2 核心链路实现:加载、切片、Embedding、检索、生成

下面这段代码是基于原生 API 的最小可运行版本,去掉了框架封装,方便你理解每一层在做什么:

import os from openai import OpenAI client = OpenAI() def load_docs(directory): """加载目录下所有文本文件""" docs = [] for filename in os.listdir(directory): if filename.endswith(".txt"): with open(os.path.join(directory, filename), encoding="utf-8") as f: docs.append(f.read()) return docs def chunk_text(text, chunk_size=500, overlap=50): """按固定窗口切片,overlap 保留上下文衔接""" chunks = [] start = 0 while start < len(text): end = start + chunk_size chunks.append(text[start:end]) start = end - overlap return chunks def embed_texts(chunks): resp = client.embeddings.create(model="text-embedding-3-small", input=chunks) return [item.embedding for item in resp.data] def retrieve(query, embeddings, chunks, top_k=5): """用向量点积做相似度检索(生产环境应使用向量数据库)""" query_vec = client.embeddings.create( model="text-embedding-3-small", input=[query] ).data[0].embedding scored = [] for i, emb in enumerate(embeddings): score = sum(a * b for a, b in zip(query_vec, emb)) scored.append((score, i)) scored.sort(reverse=True) return [chunks[i] for _, i in scored[:top_k]] def answer(query, docs): chunks = [] for doc in docs: chunks.extend(chunk_text(doc)) embeddings = embed_texts(chunks) top_chunks = retrieve(query, embeddings, chunks) context = "\n\n".join(top_chunks) prompt = f"""你是企业内部客服助手。请基于以下资料回答问题。 如果资料中没有相关内容,请明确说“资料库中未找到”,不要编造。 资料: {context} 问题:{query} 请提供简洁回答,并标注回答依据的原文片段。""" resp = client.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": prompt}], temperature=0.2, ) return resp.choices[0].message.content

这段代码里的几个参数不是随手拍的:chunk_size=500对中文规范化文本是常用起点,太短会导致上下文碎片化,太长会稀释语义并推高 token 成本;overlap=50是为了避免切在完整句子中间,让相邻 chunk 共享边界信息。temperature=0.2在知识问答场景要调低,因为我们要的是稳定事实输出,不是创意写作。top_k=5意味着最多带入 5 段资料,超过这个量既浪费 token,还可能引入噪声。

3.3 升级到 Agent:让模型学会使用工具

RAG 能解决“从静态资料里找答案”,但真实业务里模型还得会“动手做事”。比如员工问“帮我查一下我的年假余额”,系统不能只翻文档,得去查 HR 系统;问“明天下午会议室有空吗”,得去查日历系统。这就轮到 Agent 上场了。

Agent 的关键机制是 Function Calling。模型不直接执行代码,而是根据对话内容输出一个结构化调用指令,你的程序负责真正执行它。比如用户问“今天北京天气怎么样”,模型可能输出:

{ "name": "get_weather", "arguments": {"city": "北京", "date": "今天"} }

你的系统捕获这个指令后去调天气 API,再把结果塞回对话,让模型基于真实数据生成最终回答。这个模式的价值在于:决策权交给模型,执行权留在系统。模型决定调用哪个工具、传什么参数,但工具权限、参数校验、出错兜底都由你的代码掌控。

最小可用 Agent 需要一个循环:调用模型 -> 判断是否有 tool_calls -> 有则执行并回传结果 -> 再次调用模型 -> 直到模型给出最终自然语言回答。我用 Python 原样实现过一次之后,再看 LangChain 的 AgentExecutor 和 Spring AI 的 ChatClient,思路就非常清晰了。新手最容易在这里绕晕,因为框架把循环封装得太深,出了问题根本不知道卡在哪一步。

3.4 工作流编排的补充

当任务链路越来越复杂,比如“读取邮件 -> 提取待办 -> 查询相关项目进度 -> 生成周报”,单个 Agent 循环就不够用了,需要引入工作流编排。我的观点是:能用确定性代码控制的步骤,就不要把自由度交给模型;只有那些真正需要语义理解的环节,才放模型进去。比如“判断用户意图”适合模型,而“查数据库表 A 再更新表 B”就应该写死成代码逻辑。工程上追求的是可预期,不是把每件事都 AI 化。

4. 提示工程:从写好 Prompt 到系统化调优

4.1 Prompt 不是“写作文”,而是接口设计

很多人把 Prompt 当作文案来写,追求“话术”漂亮。实际上,Prompt 是模型与你系统之间的接口规范。越正规的产品,越需要把 Prompt 当接口文档来设计:定义输入、定义输出格式、定义边界条件、定义拒绝策略。

我常用的 system prompt 五要素是角色、目标、上下文、约束、输出格式。举个例子:

角色:你是某公司 HR 助理,只回答与员工制度相关的问题。 目标:基于提供的企业内部资料回答问题,帮助员工快速找到制度依据。 上下文:资料由 RAG 检索得到,按相关度排序。 约束:不要编造资料中不存在的制度;如果资料不足,明确回复“资料库中未找到”,并建议联系 HR 邮箱。 输出格式:使用 Markdown 列表;每条回答后附上资料原文引用片段。

这样写的好处是方便调参和排查。比如模型老是把引用格式写错,你只需要修改输出格式那一行,而不是整段重写。系统提示越结构化,后续用评估集测试时越容易对比版本差异。

4.2 结构化输出和少样本示例

让模型输出可解析的 JSON 是工程落地的常见需求。除了在 Prompt 里写“输出JSON”,更好的做法是给模型一个明确的 JSON Schema,必要时加上一个少样本示例。像这样:

请从用户反馈中提取: - category(分类:bug/feature/complaint) - sentiment(情感:positive/neutral/negative) - summary(一句话摘要) 以 JSON 格式输出,例如: {"category": "bug", "sentiment": "negative", "summary": "登录按钮无响应"}

少样本示例的威力在于给模型提供“参照系”,模型从模仿示例开始,远比从自然语言描述中猜测要稳定。我测试过,同样的分类任务,零样本时准确率大约 82%,加三个带说明的示例后能到 93% 以上。注意示例不能和实际输入太像,否则模型会照抄示例格式而忽略内容。

4.3 评估驱动的 Prompt 迭代

迭代 Prompt 最容易犯的错误是“感觉变好了”,然后改着改着把前面的能力改没了。正确做法是建一个固定的评估集:准备 30 到 50 条代表性用户问题,标注好期望答案的关键要素,每次改 Prompt 后跑一遍,记录三个指标:正确率、格式通过率、平均响应延迟。

这个评估集不需要多复杂,一个 JSON 文件加一个统计脚本就够了。但要确保覆盖边界情况:知识库能答的、不能答的、模糊表述的、带错别字的、多问题混合的。只有把这些情况固化下来,Prompt 调优才不会变成玄学。我现在每个项目的提示词都放在独立配置里做版本管理,和代码一起提交。

5. 常见问题与排查技巧实录

5.1 模型“答非所问”和幻觉问题

这是 AI 应用上线后收到最多的用户反馈。我排查这类问题时,通常按顺序看三件事:第一,检索到的上下文是否相关;第二,system prompt 的约束是否足够明确;第三,temperature 是不是设置得过高。

很多所谓“幻觉”,根源不在模型而在检索。RAG 系统里如果检索 top_k 返回的资料本身就不相关,模型再怎么聪明也只能编。所以我做了两条硬性控制:检索阶段加相关性阈值,低于阈值的 chunk 宁可空着也不送入上下文;回答阶段强制要求模型引用原文编号,并在后端校验回答内容里有几个引用标记,一个都没有就自动触发“资料不足”的默认回复。

5.2 Token 超限与性能优化

长对话和长文档是 token 超限的常见来源。现在很多模型支持长上下文,但成本会线性上涨,延迟也会跟着变高。工程上的处理手段是按优先级裁剪:优先保留 system prompt 和最近几轮对话,中间的早期历史压缩成摘要,检索的原始文档只保留 top_k 切片。判断依据很简单——我实测过,去掉中间 80% 的历史后,问答质量几乎不受影响,但 token 成本下降了 60% 以上。

另外,面向用户的真实产品一定要用流式输出。基于 SSE 实现流式,第一个 token 到用户眼前的感知延迟能压到 1 秒以内。很多新手把接口改成非流式,用户看到转圈 5 秒以上,体验直接崩了。流式实现也不复杂,后端按行转发模型返回的增量数据,前端用EventSource或fetch的ReadableStream接收即可。

5.3 成本控制与可观测性

AI 应用每回答一个问题都是要花钱的,这和传统后端有着本质区别。成本控制从设计阶段就要开始:问答场景能用小模型就先用小模型,复杂任务才路由到大模型;Embedding 结果要缓存,同一个问题重复提问直接命中;长文本处理优先走摘要而不是所有内容都塞进上下文。

可观测性方面,我在所有项目里都强制记录三类日志:prompt 内容、response 内容、token 用量和延迟。上线初期甚至可以每个请求都落盘,积累足够样本后再做采样。排查问题的时候,这几行日志能救命的次数远超你想象。值得提醒的是,日志里如果涉及用户输入,要做脱敏处理,尤其是身份证号、手机号这类敏感信息,别为了排查问题把隐私搞丢。

5.4 备好 Plan B:模型服务不可用怎么办

供应商的模型接口偶尔会有限流、超时甚至故障。我见过有些团队把大模型当成永不故障的数据库来用,结果线上服务悬挂一片。经验是:所有模型调用都要设置超时和重试;重试要加指数退避;连续失败要熔断,走预先准备好的兜底回复路径;兜底回复至少要给用户一个明确信号,比如“AI 服务暂时不可用,请稍后再试”。这套逻辑不复杂,但没有它就是生产事故。

写在最后:一条泥泞但值得走的路

从零开始做 AI 工程到现在,我最大的体会是:模型能力永远在进步,但工程能力才是你自己真正沉淀下来的资产。今天你学会的 RAG 链路设计、Agent 编排、Prompt 评估,换一个模型、换一个行业场景依然能复用。别急着追求“最强大模型”,先把手头最小闭环跑稳,把数据、日志、评估这些“不性感”的基础设施做实,后面再加什么新技术都会很顺。

再分享一个小技巧:给自己建一个“可复用工具箱”目录,把文档加载、切片、向量检索、工具调用这些代码做成标准函数,新项目直接复制改造。半年后你会发现,所谓 AI 工程能力,就是这些底层组件越用越顺手,组合它们的时候越来越有把握。这条路不算轻松,但每一步都看得见成长。

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

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

立即咨询