☰
从零搭建AI应用的完整工程路径:提示词、部署到Agent协作
2026/10/1 17:12:53 网站建设 项目流程

做AI工程,最怕的不是模型不够强,而是方向太散。我见过太多人从调一个API开始,到写完一个demo就停住,再往后就不知道该补什么了。这个“ai-engineering-from-scratch”项目,就是我把过去一年从零搭建AI应用踩过的坑、推翻重来的架构、重新设计的提示词,全部整理成的一条可复制的路径。它不教你背概念,而是从第一个能跑通的模型调用开始,一步步做到提示词工程、模型部署、工作流编排、Agent协作和线上排查。适合那些已经会写几行Python、但对“AI工程到底怎么做”还没有完整认知的开发者,也适合那些被网上碎片化教程弄晕的入门者。

我发现真正的门槛不在模型能力,而在工程思维。模型的输出是不确定的,链路是容易断的,数据是非结构化的,这跟传统软件开发完全是两种体验。下面我把这套从零开始的完整思路拆开讲,包括每一阶段做什么、为什么这么做、踩坑之后怎么修。

1. 项目整体设计与思路拆解

1.1 从“跑通接口”到“能上线”之间缺了什么

很多人以为AI工程就是调用大模型接口,把返回结果放到页面上。真上线过一个项目你就会明白,这只是最外面一层皮。一个能跑的AI应用,至少要同时解决四个问题:提示词怎么设计才稳定、模型怎么选才匹配业务、链路怎么编排才不容易断、效果怎么评估才知道有没有变好。

我在做这个项目时,第一个版本就是一个聊天机器人,直接调用公开接口,把用户问题原样丢给模型,再把回答原样返回。测试的时候觉得挺聪明,上线后发现用户问法一变,回答质量立刻崩。后来才意识到,模型不变,但每次输入都不一样,输出自然不稳定。这就像你让一个很专业的同事干活,但不告诉他背景、格式、边界和验收标准,他每次交回来的东西都长得不一样。

所以这个项目的设计思路是反过来的:不把精力全花在追新模型上,而是先固定一套工程框架,把提示词、数据、模型、评估四个环节都变成可维护的模块。模型可以换,提示词可以调,但框架不能散。

1.2 我如何定义这条从零开始的路径

我把整条路径分成五个阶段。第一阶段是提示词工程,学会用自然语言精确控制模型行为;第二阶段是上下文管理,理解窗口限制和信息检索的关系;第三阶段是模型选型与部署,搞清楚什么场景用API、什么场景要私有化;第四阶段是工作流与Agent,把多个模型调用串成有逻辑的系统;第五阶段是效果评估与线上排查,让系统在真实流量下保持稳定。

每个阶段都对应一个可验收的产物。提示词阶段产出一套可复用的提示词模板;上下文阶段产出一个带检索的知识库Demo;选型部署阶段产出一个私有化模型服务;工作流阶段产出一个多Agent协作的原型;评估阶段产出一份带量化指标的测试报告。这样走下来,每一步都有东西能拿得出手,而不是学了一堆概念却不知道用在哪儿。

为什么这么排?因为顺序一旦反了,学习成本会翻倍。我见过有人先搞私有化部署,折腾一周围绕显存和框架的环境问题,连模型的输入输出格式都没摸清,最后连业务逻辑都没写。先做提示词工程不是因为它最简单,而是因为它能最快建立你对模型行为的直觉。有了这份直觉,后面做部署和工作流时,你才知道哪些问题是模型本身的,哪些是工程引入的。

1.3 给不同基础读者的路线建议

如果你是编程基础薄弱的产品或运营同学,可以从提示词工程和Agent工作流开始,用可视化平台或低代码框架先跑通逻辑,再回头补Python。如果你是有经验的后端工程师,建议直接按五个阶段走,把重点放在模型部署和链路稳定性上。如果你是搞算法出身,反而要刻意补一补工程化那一部分,尤其是可观测性和评估体系。

这个项目里很多方案并不是唯一解。我尽量在每一次选型时解释背后的理由:为什么这个场景用提示词约束而不是微调、为什么这条链路用顺序编排而不是并行、为什么这个指标用人工评估而不是自动化。理解了这些取舍,你才算真正进入AI工程的语境。

2. 核心细节解析与实操要点

2.1 提示词工程的底层逻辑

提示词工程听起来很玄,本质就一句话:在模型的能力范围内,用信息组织方式提高它输出的成功率。模型不是理解你的意图,它是根据你提供的文字概率分布去生成后续内容。所以你给的信息越完整、越结构化,模型越不容易跑偏。

我推荐一套标准结构,按顺序写下来:角色定义、任务目标、输入数据、输出格式、边界条件、示例。这六个部分不是都要写,但核心场景建议写全。比如我让模型帮我整理会议纪要,提示词写成这样:

你是一名会议纪要整理助手。 任务:把下面的对话整理成结构化的会议纪要。 输出格式: - 议题列表(用数字编号) - 每个议题的关键结论(一句话) - 待办事项(格式:负责人|事项|截止时间) 边界条件:不要补充任何对话中没有提到的内容;不要在纪要中加入你的建议。 对话内容如下:

这么写和直接说“帮我整理一下这段会议记录”的区别很明显。模型知道自己的角色,知道按什么格式输出,知道哪些事不能做,产出就基本稳定在可以用的水平。很多人问我提示词要背多少模板,我说不用背,掌握这个结构,按需拼装就行。

2.2 少样本示例才是稳定的关键

结构化的任务描述能定方向,但真正让输出稳定的是示例。模型跟你一样,看一百句抽象描述,不如看两个具体例子。我管这叫“给模型打样”。

举个例子,我想要模型从用户评论里抽取情感倾向,并给出原因。那个领域里“无语”有时候是正面(比如“好吃到无语”),有时候是负面。只靠任务描述根本说不清这种情况,但我放两条示例:

示例1 输入:这家店的服务太棒了,等位的时候还送了小零食。 输出:情感=正面;原因=服务贴心,等位时有零食赠送。 示例2 输入:等了一个小时,结果菜还是凉的,真的无语。 输出:情感=负面;原因=等候时间长,菜品温度不达标。

放完这两个例子,模型对隐含规则的把握立刻上一个台阶。实际操作中,示例数量不用多,3到5个就够,关键是覆盖边界情况。你把最容易混淆的案例放上去,模型就能学会你的判断标准。

2.3 上下文窗口不只是一串数字

上下文窗口是所有做AI应用的人绕不开的硬约束。很多新手以为窗口大就能把全部资料塞进去,这是最大的误解。窗口包含的是这段对话里所有历史消息加你新输入的token总长度。对话一长,前面的内容可能被挤掉,模型就“失忆”了。

我的经验是:上下文里只放与当前任务强相关的信息。业务背景、用户历史、知识库文档,都通过检索只取最相关的片段拼进去。这就是RAG(检索增强生成)的核心思路。不要试图让模型记住所有东西,而是让它需要什么就能查到什么。

做个简单的算术:假设模型窗口是128K token,你塞进去100K背景资料,留给模型思考和输出的空间就只剩28K,不仅要承担生成答案,还要承担输入问题本身。一旦对话轮数变多,老问题就会反复出现。所以上下文管理的关键动作是裁剪和检索,而不是充值。内存再大,也不能无限塞东西,搜索才是解决信息过载的正确姿势。

3. 模型选型与部署:从API到私有化的完整路径

3.1 选模型先看场景,而不是参数大小

很多人选模型的第一反应是“哪个分高选哪个”,这在工程上是个危险的思路。模型不是越强越好,而是越匹配越好。我把选型维度拆成四个:效果、延迟、成本、可控性。这四个维度往往互相打架。

举个例子,一个实时客服场景,用户发消息后两秒内必须收到回复。这种情况下,一个响应速度快的轻量模型哪怕效果稍弱,也比一个动辄思考几十秒的大模型更合适。相反,一个离线生成营销文案的任务,对延迟没要求,就可以用效果更强的模型,哪怕成本高一点也值得。

我还会看模型的生态兼容性。同一个模型在不同推理框架下的表现可能有差异,工具链是否完善直接决定你能不能顺利调用、便捷地做量化或批处理。选型时我固定会做一个小测试:拿自己业务里最典型的20条输入,分别让候选模型跑一遍,人工打分。这个过程叫“效果基线测试”,虽然简单,但比任何排行榜都贴近真实需求。

3.2 私有化部署一套开源模型的完整流程

当业务有数据合规要求,或者API调用成本高到难以接受时,私有化部署就成了刚需。这个项目里我完整走了一遍流程,这里给出一个可以直接参考的路径。我选的是Qwen系列的开源模型,因为它中文效果稳定、生态成熟、量化方案也多。

第一步,准备推理环境。我的机器是单张24G显存的显卡,这个级别的显存跑7B到14B的量化模型刚刚好。先装好Python虚拟环境,然后安装transformers、accelerate、sentencepiece这几个核心依赖。第二步,下载模型权重,用Hugging Face的镜像站直接拉取官方权重。第三步,用vLLM起服务,因为它批处理能力强,并发响应性能比原生transformers高很多。

# 安装依赖 pip install transformers accelerate sentencepiece vllm # 启动模型服务(以Qwen2.5-7B-Instruct为例) python -m vllm.entrypoints.openai.api_server \ --model Qwen/Qwen2.5-7B-Instruct \ --gpu-memory-utilization 0.9 \ --max-model-len 8192 \ --port 8000

启动之后,你会得到一个兼容OpenAI接口格式的本地服务。这意味着你原来写的调用代码几乎不用改,只要把base_url换成http://localhost:8000/v1就行。这一步对工程迁移非常友好,不需要重写业务逻辑。

3.3 量化与并发:部署环节的必修课

私有化部署最常见的问题就是显存不够。我强烈建议上手先做量化。4比特量化能把模型体积压缩到原来的四分之一左右,7B模型量化后大约4到5GB,跑起来非常流畅,效果损失在大多数任务上可以接受。

关于并发,vLLM的连续批处理机制能把多个请求动态拼成一个批次,显存利用率高很多。但并发数不是越大越好,我实测下来,24G显存上7B模型,并发调到8到16之间比较安全,再往上就会触发显存溢出。另一个容易忽略的点是max-model-len设置。这个参数控制单次请求的最大长度,设得越大,能同时跑的请求数越少。业务场景如果多数是短对话,就没必要设成8192,设4096能显著提升并发能力。

部署完成后一定要做一次压测。我习惯用wrk或简单脚本并发请求,观察响应时间和错误率变化。这一步能帮你提前发现显存不足和队列堆积的问题,而不是等用户来投诉。

4. 工作流与Agent:把单点能力串成有逻辑的系统

4.1 单次调用与工作流的边界

单一模型的直接调用能解决“一问一答”型任务,但现实中很多需求是多步骤的。比如“分析用户投诉并生成处理建议”,完整流程是:先做意图识别,再抽取关键实体,再查历史工单,最后生成建议。每一步用不同的模型或不同的提示词,串在一起才是一个合格的AI应用。

我划分工作流边界的标准是:如果一次调用需要分成多个子任务,并且每个子任务的结果会影响下一步的逻辑分支,那就必须引入工作流。工作流工程的价值在于把不确定性拆成多个可控制的节点。每个节点做一件简单的事,要么成功要么失败,可重试可单独调试。相比之下,一个大而全的提示词像一锅乱炖,出了问题你都不知道是哪个配料坏了。

4.2 一个多Agent协作的小案例

多Agent协作通常是工作流的升级形态,核心思想是让多个专职的“角色”分工配合。这个项目里我搭了一个内容创作Agent小组,由三个角色组成:选题Agent负责根据热点收集素材并产出观点,写作Agent负责把观点扩展成完整文章,审校Agent负责检查事实性错误和表达问题。

三个Agent之间通过消息队列传递任务。选题Agent完成后把“选题卡片”发给写作Agent,写作Agent完成后把草稿发给审校Agent。关键设计是每个Agent都有独立的提示词和输出格式约束,互不干扰。比如审校Agent的提示词里明确要求“只输出问题清单,不重写文章”,这样它就不会越权改动内容。

# 简单的Agent调用示意 def run_content_pipeline(topic: str) -> dict: idea = topic_agent.run(topic) # 产出选题卡片 draft = writing_agent.run(idea) # 产出文章草稿 review = review_agent.run(draft) # 产出问题清单 if review.issues: draft = writing_agent.run(draft, review.issues) # 按问题修订 return {"draft": draft, "review": review}

这里有个工程细节:不要让Agent在同一个上下文里反复对话,而是用结构化数据传递中间结果。这样每个Agent的输入输出都是稳定可解析的JSON,流程可以被追踪,出错时也能定位到具体环节。

4.3 工程化关键:可观测性和重试机制

Agent多了之后,最怕的是链路悄悄失败。写代码的时候,模型不可用的报错会直接抛出来,但在Agent工作流里,模型“成功返回了一段废话”这个情况更难察觉。所以我给每个环节加了三个东西:输入输出日志、耗时与token消耗统计、状态标记。

日志记录每一轮的输入长度、输出长度、延迟和使用的模型版本。token消耗直接和成本挂钩,这个必须量化。状态标记则区分四种情况:成功、失败、部分成功、需要人工介入。部分成功是我最关心的一个状态,比如审校Agent发现三条问题,其中一条无法确认,这时候就把它标记为需要人工检查,而不是让流程强行继续。

重试机制也不能是无脑重试。模型接口的错误分两种,一种是限流或超时,重试有意义;另一种是内容审核拦截或输出格式不对,重试十遍结果都一样。我的做法是设置分层重试:网络类错误重试三次,间隔递增;业务类错误直接跳到人工兜底逻辑。这个兜底逻辑可以是模板回复,也可以是降级到另一个更小的模型,总之不能把错误直接暴露给用户。

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

5.1 最常踩的五个坑

第一个坑是忽略输入输出的格式校验。模型是概率生成的,你告诉它输出JSON,它偶尔会在JSON前后多一行解释文字,直接json.loads就会报错。解决方式是抽取返回结果里的代码块再解析,同时写一个宽松的正则兜底。第二个坑是上线后才发现模型被“越狱”。用户可能会把一串精心构造的指令塞进输入,诱导模型说出不该说的话。因此无论什么场景,都必须加一层输入安全过滤和输出审核。

第三个坑是上下文越塞越多导致成本和延迟同步上涨。有个阶段我的调用量没增加,但账单涨了,排查后发现是有个历史记录功能把所有旧对话都拼进请求了。第四坑是忽略模型版本升级带来的输出变化。同一个提示词,换成新版本模型,输出风格可能明显改变。这要求你对线上模型版本做固定快照,不要跟随最新版自动升级。第五个坑是不做效果回归测试,改了一版提示词后,整体效果提升了,但某个旧场景反而变差了。没有回归用例,这种退化很难被发现。

5.2 排查工具箱:从日志到链路追踪

遇到问题,我第一件事永远是看日志,而不是重新读代码。我给每条请求分配一个request_id,从入口到每一个模型调用都带上它,这样就能把一次用户的完整链路串起来。日志里包含模型名、输入长度、输出长度、耗时、状态码。有了这些,多数问题都能定位到具体环节。

再进一步,我会用监控看板统计三类指标:成功率、平均延迟、token消耗趋势。成功率掉下来的时候,优先查是不是模型服务过载;延迟变高的时候,优先查上下文是不是变长了;token消耗异常上涨的时候,优先查是不是有循环调用或重试过多。

如果问题只在个别用户身上出现,就把那个用户的完整上下文导出来复跑。我用这个办法定位过一个特别隐蔽的问题:某个用户的历史对话特别长,超过了窗口限制,导致模型回复质量下降,但当时日志里并没有报错,因为调用本身是成功的。发现这类问题靠日志还不够,必须同时监控输入长度分布,提前发现靠近窗口上限的请求。

5.3 几个亲测有效的避坑技巧

关于提示词的迭代,我强烈建议每次只改一个变量。很多人一次改了角色描述、输出格式和示例,效果变好了,但不知道具体是哪个改动起的作用,下次复现不了。我做了一个简单模板版本管理,提示词存成文本文件,带版本号,实验时跑同一批测试用例对比。稳定之后,再改下一个变量。

关于小模型和大模型的分工,我习惯把简单任务交给轻量模型,复杂任务留给大模型。意图识别、实体抽取、标题生成这类标准化任务,轻量模型足够;需要创意、推理或长文生成的,才上调大模型。这样成本能省一大截,效果还不降。

关于上线前的检查清单,我的固定动作是:跑一遍全链路冒烟测试、检查输出格式解析率是否达到100%、验证未知输入的兜底逻辑、确认日志和监控已经接入。这套检查做完再上线,出问题的概率会小很多。

这个项目做到后期,我最大的体会是:AI工程的重点已经从“让模型更聪明”慢慢转向“让系统更可靠”。模型能力会不断进步,大家都会用的时候,拼的就是谁的工作流更稳、评估更准、排查更快。从零开始不是把流程从头学一遍,而是从一开始就把这些习惯刻进代码里。哪怕你的第一个项目只是一个简单的问答机器人,也值得按这套工程标准去做,因为你迟早会用得上。

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

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

立即咨询