ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

从零构建AI工程:Prompt、模型部署与Agent工作流实战指南

从零构建AI工程:Prompt、模型部署与Agent工作流实战指南 先聊一个有代表性的问题很多朋友看到“ai-engineering-from-scratch”这个标题第一反应是“又要从Python语法开始学起了”。说实话早期我也是这么理解的但真正把一个AI项目从零推到可上线、可维护、可扩展的状态之后我发现自己当初最大的误解是把“会调模型”当成了“会做AI工程”。从零开始构建AI工程能力真正要解决的不是“怎么把大模型跑起来”而是“怎么让大模型在真实业务里稳定、可靠、可控地干活”。这中间隔着Prompt工程、Agent工作流设计、模型选型、部署策略、工具链整合等一系列环节。这篇文章就基于我个人从零搭建AI工程体系的完整经验把这条路上最核心的思路、最实操的步骤、最容易被忽略的坑一次性讲透。适合正在转型AI应用开发的工程师、想给业务接入AI能力的产品和技术负责人以及所有准备系统构建AI工程化能力的团队参考。1. 先想清楚从零开始构建AI工程本质在构建什么1.1 为什么是“from scratch”而不是“快速上手”市面上聊AI应用的文章绝大多数都在讲“5分钟接入一个模型API”“3步写出第一个对话机器人”。这些内容不是没有价值但它解决的是“能跑”的问题不是“能干活”的问题。从零开始构建核心差异在于你要亲手把AI能力从一段代码变成一套体系。这意味着要回答一串看似基础但绕不开的问题模型怎么选用闭源API还是开源模型本地部署两者的成本、延迟、数据安全边界在哪Prompt怎么写才稳定同一个Prompt换一批数据为什么效果就崩了Agent到底怎么设计任务分解、工具调用、记忆管理、异常恢复这些谁来负责应用怎么落地是嵌到现有系统里还是独立服务跟Spring等现有技术栈怎么融合效果怎么评估上线之后怎么知道模型变好了还是变差了谁来定义“好”“from scratch”的含义就是这些问题你都要自己趟一遍不能指望任何一家厂商帮你全部解决。我个人的体会是这个“趟一遍”的价值不在于你最终选了什么方案而在于你终于理解了每个环节为什么必须存在。1.2 一条可执行的路线图我用自己的项目经历把从零构建AI工程的过程拆成了四个阶段。这个拆分不一定适合所有人但至少能让你对整条路有个全景认知。第一阶段模型接入与环境准备。目标是让模型能稳定地被调用不管是API还是本地部署先有一条畅通的调用链路。第二阶段Prompt工程与效果调优。目标是让模型输出稳定、结构可控能复用、能迭代。第三阶段Agent工作流设计。目标是让模型不只是一个“问答机”而是能拆任务、调工具、完成多步骤操作的“执行者”。第四阶段工程化落地与维护。目标是让AI能力进入业务系统具备可观测、可回滚、可评估的特性。这个路线图的核心逻辑是先有稳定调用再有稳定输出再有复杂执行最后才进入业务系统。跳步的结果通常是——模型偶尔能跑通看起来很酷的Demo但一放到真实场景就各种翻车而且你还不知道问题出在哪一层。2. 第一道坎选模型、搞部署、打通环境2.1 大模型选型背后的逻辑很多初学者上来就问“哪个模型最强”这是个典型的误区。选模型本质上是选约束条件不是选性能天花板。我当时梳理下来核心决策维度就四个第一数据敏感性。业务数据能不能出域如果能接受第三方API那闭源模型的省心程度最高如果不行就必须本地部署开源模型。这一条就淘汰掉了一大批方案。第二调用频率与成本。每天调用的量级是几百次还是几百万次闭源API按Token计费调用量上来之后成本曲线非常陡峭。本地部署虽然前期要砸硬件成本但边际成本趋近于零。第三延迟要求。交互型应用要求首字延迟在1秒内批量处理型任务则无所谓。部署方案必须匹配延迟需求不能只看模型本身的能力。第四功能复杂度。纯文本对话、结构化抽取、多模态理解、复杂推理这些场景对模型的选型要求完全不同。一个连Function Calling都不支持的模型基本没法做Agent。我当时的选择是“双轨制”线上轻量任务走闭源API快速迭代不求人数据敏感的核心链路走本地部署的开源模型保证数据可控。这个策略牺牲了一部分统一性但换来了极大的灵活性。后续所有工程能力都是在这个双轨基础上搭建的。2.2 本地部署的关键细节本地部署这件事看着就是“下载权重、启动服务、调用API”三步实际踩坑最多。我以Windows环境下部署开源模型为例把关键步骤和参数说清楚。第一步部署框架选型。目前最主流的是Ollama和vLLM两者定位完全不同Ollama适合个人开发、轻量部署上手成本极低vLLM适合生产环境吞吐量优势明显但配置复杂度高。从零开始建议先用Ollama跑通全链路再根据场景决定要不要换vLLM。第二步模型量化选择。这里有个必须掌握的概念量化。模型权重用FP16存储占用显存巨大比如一个7B模型光权重就要14GB。通过量化压缩到INT4或INT8占用能降到4-8GB但会牺牲少量精度。我的经验是对话生成类任务用Q4量化完全够用精度损失几乎不可感知但如果要做信息抽取、分类等对精度敏感的任务至少用Q8或干脆上FP16。第三步推理参数配置。Ollama启动模型时可以指定上下文长度和GPU层数。上下文长度直接决定模型能“记住”多少对话内容默认的2048在工程实践里完全不够用我一般会设置到8192起步。GPU层数则影响计算是走显卡还是CPU同样是跑7B模型全量GPU推理和部分CPU推理的速度差距能到5倍以上。# 以Ollama部署qwen2.5:7b为例 # 安装Ollama后先拉取模型 ollama pull qwen2.5:7b # 启动服务时指定上下文长度和GPU层数 ollama run qwen2.5:7b --num-ctx 8192 --num-gpu 99第四步网络与端口规划。Ollama默认监听127.0.0.1:11434只有本机可以访问。如果要把模型服务给其他机器用需要修改环境变量OLLAMA_HOST。这个细节看似简单但在涉及Docker、局域网、内部网关的复杂环境里很容易成为排查半天也找不到原因的病根。部署这块的结论是不要迷信“最高配置”先把你手头的硬件资源跑满理解量化、上下文、推理速度三者之间的权衡再考虑上生产。3. Prompt工程与Agent让模型从“能聊”到“能干活”3.1 提示词工程的核心不是咒语是接口设计有一段时间网上把Prompt工程渲染得很玄学“咒语”“魔法词”这类说法满天飞。但我做了大量真实业务场景的Prompt之后得出一个结论Prompt工程本质是接口设计不是魔法咒语。理解这个定位很关键。你写Prompt的目的是让大模型稳定输出你想要的格式和内容这跟设计一个函数接口的目标完全一致输入清晰、约束明确、输出可预期。我个人总结出一套稳定的Prompt结构核心包含五个部分角色定义。告诉模型“你是谁”。这比很多人理解的“角色扮演”要实用得多——角色定义本质是划定了模型调用的知识领域和话语风格范围。任务说明。用一句话说清楚“要做什么”。越具体越好避免“分析一下”“处理一下”这种模糊动词。输入数据。把需要处理的内容显式传进来。注意这里有个常见误区很多人把输入数据和Prompt混在一起写导致模型分不清哪些是要处理的业务数据哪些是约束指令。输出格式约束。明确指定输出的结构比如JSON、Markdown表格、固定字段列表。这一步是工程化的关键没有结构约束的模型输出在真实系统里就是一堆需要二次解析的字符串。边界与兜底。告诉模型“遇到处理不了的情况怎么办”。比如“如果数据不完整返回error字段并说明原因”这能极大减少生产环境里的异常处理复杂度。# 一个可直接参考的Prompt结构示例 prompt f 你是一名专业的客户反馈分析助手。 请对以下客户反馈进行分类并提取关键信息。 客户反馈 {feedback_text} 要求 1. 判断反馈属于【投诉】【建议】【咨询】中的哪一类 2. 提取反馈中提到的产品名称和具体问题 3. 如果反馈信息不完整请在issue字段中说明缺失内容 输出格式严格JSON {{ category: 投诉, product: 产品A, issue: 充电速度慢, missing: }} 这里还有一个被反复验证有效的技巧Few-shot示例。与其长篇大论地描述你想要的输出格式不如直接给模型两个“输入-输出”的示例。模型对示例的模仿能力远强于对规则的理解能力。我在实践中给三个高质量示例的效果通常超过五百字的格式描述。3.2 从单轮到Agent工作流才是真正的工程化Prompt工程解决了单次调用的输出质量但真实业务场景几乎没有“问一句答一句”这么简单的事。用户说“帮我分析这份销售数据找出异常区域并生成一份摘要报告”这背后至少包含数据读取、数据清洗、异常检测、报告生成四个步骤。这就是Agent要解决的问题。Agent的核心不是“智能”而是“编排”。我在项目里对Agent结构的拆解是这样的第一层任务规划器Planner。接收用户的复杂指令拆解成多个子任务并确定子任务之间的依赖关系。这一层可以交给大模型做也可以基于规则做取决于任务的复杂程度。第二层工具执行器Executor。每个子任务对应一个工具调用比如数据库查询工具、HTTP请求工具、文件读写工具。关键点在于工具接口必须极其简单稳定最好是“一个函数做一件事”。第三层记忆管理器Memory。Agent需要在工作过程中记住中间结果。会话记忆走数据库任务状态走内存或Redis两类记忆要分开管理。第四层异常处理器Recover。任何一步执行失败都要有明确的分支逻辑。这个环节最容易被忽视但恰恰是工程化Agent和Demo Agent的分水岭。# Agent工作流的最小实现框架 class WorkflowAgent: def __init__(self, llm, tools): self.llm llm self.tools tools self.memory {} def run(self, task): # 1. 任务拆解 steps self.llm.plan(task) # 2. 逐步执行 results [] for step in steps: tool self.tools.get(step[tool]) if not tool: # 3. 异常处理无对应工具时求助模型 result self.llm.think(step) else: result tool.run(**step[params]) self.memory[step[id]] result results.append(result) # 4. 汇总输出 return self.llm.summarize(results)这个框架极其简陋但它揭示了一个重要原则Agent的每一层都可以用大模型来实现也可以用规则来实现关键是你要明确哪些环节依赖大模型的模糊处理能力哪些环节必须用确定性代码来保证可靠。凡是“非做对不可”的环节全部用代码控制只有“做到差不多就行”的环节才交给模型。4. 工程化落地把AI装进业务系统4.1 技术选型Spring AI、LangChain还是自研Agent搭建起来之后下一个问题就是怎么把AI能力嵌进现有系统这块市面上主流的方案有三类我逐一分析过它们的适用边界。第一类LangChain。生态最丰富组件最全社区最大。但它的抽象层很多版本迭代也比较快对新手不算友好。适合快速原型验证但真要上生产你需要对它的内核原理有足够理解否则出了问题很难排查。第二类Spring AI。这是Java生态的答案。如果你现有技术栈是Spring BootSpring AI的吸引力极大——它能把模型调用、Prompt模板、输出解析这些能力以Spring的方式注入你的工程和现有业务代码无缝融合。我的主力项目就是基于Spring Boot构建的所以Spring AI是我最终的主选路线。第三类自研封装。在模型调用层面做一层薄薄的封装自己管理Prompt模板、上下文、工具调用。适合AI能力比较庞杂、业务耦合度高、需要深度定制的场景。缺点是前期开发量大但可控性最强。表格对比一下三类方案的适用场景维度LangChainSpring AI自研封装技术栈PythonJava/Spring任何上手成本中中高生产稳定性依赖选型较高完全可控生态丰富度极高中无适合场景快速原型Java业务系统深度定制我的建议是不要盲目跟风先看你现有系统的技术栈和团队能力。Java团队用Spring AIPython团队用LangChain或自研这是最不折腾的路径。4.2 一个完整的实操案例本地部署 Agent Spring AI接入讲一个我自己实际做过的案例完整走一遍这套链路。场景是内部需要一个“报销单据自动审核助手”读取报销单图片、提取关键字段、比对报销制度、输出审核意见。模型层本地部署一个多模态模型负责OCR识别和字段抽取。选多模态模型是因为要直接吃图片输入纯文本模型解决不了这个问题。Agent层任务拆成三步。第一步抽字段第二步查制度第三步比对审核。第二步不需要模型是一个规则查询函数。这里就体现了“哪些环节该交给模型”的思路抽字段必须用模型查制度用数据库更可靠比对审核则模型规则结合制度明确的部分走规则模糊地带让模型给参考意见。Spring AI接入层在Spring Boot工程里引入Spring AI依赖配置模型端点。这里给一段真实的配置参考// Spring AI接入本地Ollama服务的配置 Configuration public class AiConfig { Bean public ChatClient chatClient() { return ChatClient.builder() .model(qwen2.5-vl:7b) .baseUrl(http://localhost:11434) .defaultOptions(ChatOptions.builder() .temperature(0.2) .build()) .build(); } }这里有个细节值得单独讲temperature参数。很多人不知道这个参数的意义它控制模型输出的随机性。取值0到1之间越接近0输出越确定越接近1越有创造性。工程场景里凡是字段抽取、分类、审核这类任务temperature一律设到0.2以下只有文案生成、头脑风暴这类创造性任务才建议放到0.7以上。这个参数调对很多“模型结果不稳定”的问题就自动消失了。整个流程跑通后处理一张报销单从原来的手工5分钟降到了18秒而且审核意见和人工复核的一致性达到90%以上。这个案例最有价值的结论是AI工程化的关键是“模型规则工作流”的组合设计而不是追求单点模型能力的极致。5. 常见问题与排查实录5.1 那些绕不开的“坑”从零搭AI工程这条路上我踩过的坑足够写一本小册子。这里挑几个最有代表性的按影响程度排序。第一个坑Prompt上下文溢出导致输出质量雪崩。当对话轮次变多输入Token超过上限时模型的注意力会分散在大量老旧信息上导致最新一轮的指令反而得不到有效执行。现象就是“聊着聊着模型就变傻了”。解决方案是做上下文裁剪保留系统指令和最近几轮对话把中间过程压缩成摘要。这也是为什么很多成熟的Agent框架里都有“会话摘要”模块。第二个坑本地部署模型的内存碎片化。Windows环境下运行Ollama时长时间工作后模型服务会越来越卡本质是显存碎片化没有得到释放。我的解决建议是写一个定时任务每天凌晨重启一次模型服务。这招极土但极其有效生产环境的稳定性大幅提升。第三个坑Agent的“死循环”行为。当模型被赋予工具调用能力后偶尔会出现一遍遍调用同一个工具、反复获取相同结果的情况。问题根源是模型不知道“已经尝试过了”。解决办法是给工具调用加一个“记忆机制”——把每次调用的输入输出都记录到上下文中并要求模型在重复调用前先说明“为什么这次会不一样”。加了这个约束之后死循环问题基本销声匿迹。第四个坑结构化输出偶尔出格。即使你在Prompt里严格指定了JSON格式模型偶尔还是会输出多余的解释文本。这时候不要试图靠Prompt彻底解决要在代码层做防御性解析捕获解析异常从输出文本中截取JSON片段再解析。工程里要始终相信“模型是不可靠的同事”所有的关键路径都要有代码兜底。5.2 排查思路速查表把这段实践总结成一张速查表遇到问题直接对照排查故障现象优先排查方向常见根因模型响应太慢显卡利用率、上下文长度GPU层数设置不足、上下文过长输出质量下降Prompt上下文是否被挤占多轮对话后上下文超限结果不稳定temperature参数、随机种子temperature过高Agent卡住不执行工具调用日志、死循环保护缺少重复调用约束服务内存持续增长重启策略、内存释放服务长时间运行未重启结构化输出解析失败输出原始文本模型输出掺杂了额外文本排查的底层方法论只有一条让每个环节都可以被观测。给模型调用、工具执行、Prompt构造分别打日志出了问题先看日志定位到具体环节再针对环节优化。我在项目里养成的习惯是每次模型调用都记录输入Token数、输出Token数、耗时、temperature、模型版本。这些数据攒下来不仅方便排查问题还是后续做效果评估的宝贵素材。写在最后从零开始构建AI工程我最大的感受是这个领域没有“银弹”也没有“一步到位”。真正有效的路径是把大模型当作团队里一个能力很强但需要严格管理的“新同事”——你要给它清晰的岗位说明书Prompt给它好用的工具和工作流程Agent编排给它建立清晰的工作汇报机制结构化输出还要经常盯着它的工作质量效果评估与日志观测。我个人在实际操作中收获最大的一件事是把“模型能力”和“工程能力”彻底分开看待。模型能力是底座决定天花板工程能力是骨架决定能不能落地。大多数项目失败都不是因为模型不够强而是工程骨架撑不住业务需求。这个内容后续还可以这样扩展把整套能力沉淀为内部平台提供统一的模型接入、Prompt管理、Agent编排和效果评估能力让团队里任何人都能快速搭建AI应用而不是每个项目都从零重复一遍。如果你正在走这条路希望这篇文章能帮你少踩几个坑。
返回列表