
从“调接口”到“真正做工程”这一路我踩过的坑都在这个开源项目里如果你看过不少AI项目代码大概率有过这种感受网上教程里三行代码调用大模型接口感觉AI工程也就那么回事。可一到自己动手要处理文档解析、上下文管理、模型输出不稳定、接口限流、部署时显存不够……全套流程走下来才知道“会调接口”和“能上生产的AI工程”之间隔着一整条河。我最近把从零搭建AI工程的全过程整理成了一个开源项目叫“ai-engineering-from-scratch”核心就是把一个完整AI应用从无到有落地所涉及的所有环节——模型选型、提示词工程、检索增强、Agent设计、评估部署——按可复现的顺序串起来。这篇文章不聊PPT就讲我在这个项目里实际做的那些选择、踩过的那些坑以及每一步为什么非这么做不可。适合刚入门想往工程方向走的开发者也适合已经在做业务AI化、想补一补系统性知识的人。1. 先搞懂“AI工程”到底在拼什么1.1 从“调接口”到“工程化”的认知升级很多人以为AI工程就是“API调得多、模型用得好”实则以我做了几个落地项目之后的感受真正的AI工程更像是在不确定性里搭一套确定性系统。模型回答本身是概率性的你今天问它“你好”它回得挺好明天同样的问题它可能换了种说法甚至偶尔会胡说。工程化要做的事就是把这些概率输出包裹进一套结构化流程里用提示词规范行为用检索约束事实用Agent拆解任务用评估兜住质量底限。这个概念想通了后面所有设计才有方向。我见过不少团队卡在“模型不听话”上让模型输出JSON它偶尔给你解释一段让模型从长文档提取信息它把原文抄了一大半。这不是模型不行是工程化没跟上。从零开始做AI工程第一步是接纳这三个现实模型会犯错、延迟会波动、上下文有上限。基于这些现实设计系统而不是用“换个更强的模型”去掩盖问题才是工程化的起点。1.2 开源项目“ai-engineering-from-scratch”的路线图拆解这个项目名里的“from scratch”强调的是不依赖现成低代码平台自己把每个模块搭一遍。我给它设计的主线是先跑通最小链路再逐层添加复杂度。完整路线分四段。第一段是基础链路选定一个开源模型或商用API写出一个能跑通“提问-回答”的最小程序第二段是增强能力把提示词工程、RAG检索、结构化输出这些模块逐个加入让模型行为变得可预期第三段是Agent化让模型不只是回答问题还能拆分任务、调用工具、执行动作第四段是工程兜底加入评估、监控、部署和性能优化让系统能稳定在线上跑。每一段我都会配套一个实战主题比如“用RAG做企业知识库问答”“用Agent做自动化信息整理”“用评估集压测模型稳定性”。这样做的好处是每阶段都有可验证的里程碑不至于学了一堆概念最终却拼不出一个能用的东西。如果你跟着做下来最终会得到一个分层清晰的AI应用骨架替换业务场景后就能变成自己的产品。2. 从零搭建AI工程的技术底座模型、提示词、RAG2.1 模型选型与API调用先跑通一条端到端链路动手第一步选模型。这里没有“最好”只有“最合适”。我的建议是除非业务对数据隐私极其敏感否则初期直接用商用大模型API比如OpenAI、Anthropic或国产的DeepSeek、通义千问都行先把链路跑通别在自部署上浪费半天。如果确实要本地部署后面第4章会专门讲。选模型时重点看三个指标上下文长度、工具调用能力、输出格式稳定性。上下文长度决定你单次能喂多少资料工具调用能力决定能否走Agent路线输出格式稳定性决定你后处理要花多少力气。我最初用的是一个参数量较小的开源模型想着省成本结果它经常把JSON输出在前面加一段“好的下面是我生成的结果”后处理脚本不堪重负最后还是换了能力更强的模型数据处理成本反而降了一半。API调用这块别急着上复杂框架先用最朴素的HTTP请求调用一次亲手看系统提示词、用户消息、工具定义这三部分是怎么组装的。等理解了协议再根据需要引入OpenAI SDK或LangChain这类上层封装。我项目里的示例代码就用OpenAI兼容接口做了一个最简单的循环组装消息、调用模型、拿到回复。这一步虽然基础却是后续所有复杂系统的地基。2.2 提示词工程Prompt Engineering的三个关键细节很多人觉得写提示词就是“把问题说清楚”实际做完这个项目我发现专业提示词设计要考虑的细节远比想象多。这里有三个我踩出经验的关键点。第一系统提示词不要只写“你是一个助手”要写清角色、目标、约束和输出格式。比如做知识库问答系统提示词至少要有这几层你是企业知识库助手你的任务是根据给定资料回答问题如果资料中没有答案必须明确说明“资料中未查询到”回答用简体中文分点列出引用依据。这四层缺一不可。我见过无数例子只写“你是助手”结果模型自由发挥到姥姥家。第二给模型“安全网”和“退路”。模型在有明确规则时会更守规矩。比如你要求模型从文档提取关键词它可以输出空数组但绝不能瞎编一个。在提示词里显式留出“当无结果时输出空值”的选项能大幅减少幻觉。我自己做信息抽取时加上这句之后无效输出比例从18%降到了3%以下。第三少用抽象形容词多用具体示例。提示词里说“回答要专业”模型不知道什么叫专业但你在用户消息里给出一个小例子说明期望的回答结构模型马上能模仿得像模像样。Few-shot示例是性价比最高的调优手段。我甚至会专门为复杂任务维护一个“示例库”把测试中表现最好的几条输入输出对放进去作为提示词的固定组件。2.3 检索增强生成RAG实战让模型回答你的业务数据RAG是目前把私有知识接入大模型最主流的方式架构不复杂但细节里的坑一个接一个。基础流程是把文档切成小块做向量化存入向量数据库用户提问时把问题向量化检索出最相关的几个文本块连同问题一起塞进提示词。听起来简单可切分方式、检索策略直接决定回答质量。我最初图省事按照固定长度比如每500字切文档结果很多段落被拦腰截断语义破碎检索出来的内容前言不搭后语。后来改用“结构化切分”优先按Markdown标题、段落等自然边界切实在不行再按字数兜底检索命中率明显提升。另一个容易翻车的点是“检索到相关不等于回答正确”。模型会把检索到的内容当真理哪怕片段本身有误导信息。所以我在提示词里明确加了“仅根据以下资料回答不要推测”的约束并且要求模型在回答末尾标注引用来源序号。这样即便答案不完美用户也能追溯到原始文档工程上叫“可溯源”这对做企业知识库几乎是硬指标。向量数据库我试过Chroma和Qdrant最终在项目里选的是Qdrant因为它在过滤元数据比如限定某个文档范围检索时更灵活。检索策略上除了纯向量相似度我还会额外加一层BM25关键词召回再把两路结果合并重排。这种“混合检索”在专业术语繁多的场景下特别有用——向量模型对生僻词理解弱但关键词匹配能精准捞回来。3. 迈向AI Agent从“对话”到“做事”3.1 Agent架构拆解规划、工具、执行、反思如果说RAG让模型“知道得更多”Agent就是让模型“做得更多”。一个完整的Agent需要具备四大能力规划、工具使用、执行、反思。规划是模型理解用户目标后决定分几步完成工具使用是模型在需要时调用外部函数比如搜索、查数据库、发通知执行是实际运行这些工具并拿到结果反思是根据结果判断是否已经完成任务要不要调整计划重新来一次。听起来很玄但底层逻辑就是“把一个大任务拆成几步循环”。我用日常备课做个类比你准备一节课首先拆解目标讲透一个知识点然后搜集资料调用工具资料不够再补充检索反思并修正直到能形成教学方案。Agent本质就是把这个思维过程程序化。设计Agent时最怕的是让模型“自由发挥”太多。我建议一开始把所有工具定义写得极其严格每个工具注明功能、参数、返回格式。并且给Agent设计一个固定循环思考-行动-观察-再思考最多迭代N次超过次数就停止。这个“最大迭代次数”就是安全闸门缺了它Agent可能陷入死循环烧掉大量Token。3.2 用代码实现一个最小可用Agent附关键代码项目里我实现了一个最简Agent不依赖LangChain这类重量级框架只用原生函数就能看透核心机制。这里贴一段核心循环的简化版用伪代码说明思路def run_agent(user_goal, tools, max_steps5): messages [{role: system, content: SYSTEM_PROMPT}] messages.append({role: user, content: user_goal}) for step in range(max_steps): response call_llm(messages, toolstools) # 如果模型决定调用工具 if response.get(tool_calls): messages.append(response) # 保存模型回复 for call in response[tool_calls]: result execute_tool(call[name], call[arguments]) messages.append({ role: tool, tool_call_id: call[id], content: result }) else: # 没有工具调用视为最终回复 return response[content] return 已达最大步数停止迭代这段代码的核心是“把模型的每次回复以及工具返回结果都能放回上下文”这样模型才能推理下一步。实际项目中execute_tool背后可能是调用一个天气API、查询数据库或者执行一段Python脚本。为了让模型能正确调用每个工具定义需要写成JSON Schema告诉模型工具叫什么、需要哪些参数。我踩过的坑就在这工具定义示例写得太少模型调用时参数名对不上后来我把每个参数都加了“示例值”调用准确率立刻提上来了。代码封装好后你自然会面临两个工程问题怎么并发跑多个Agent任务怎么让Agent在任务中间失败后自动重试我现在的做法是用消息队列把任务提交给Worker每个Worker跑一次run_agent结果写入数据库。重试逻辑则放在调用方检测到超时或返回错误就重新入队最多重试两次。这套实现大概二百行但已经足够支撑一个自动化处理上百个文档的并发任务。3.3 多Agent协作与工作流编排的工程化思路单Agent解决独立任务已经很好用了但真实业务里很多需求要多个角色配合。比如做一个“需求分析Agent”可能需要“调研Agent”先去搜资料再有“撰写Agent”整理成文档最后“评审Agent”挑毛病。这就涉及多Agent协作和工作流编排。我的实践建议是不要把多个Agent塞进一个循环里让他们自由对话——那样成本高、不可控且极难调试。更稳的做法是“工作流子Agent”外部用代码定义好每一步第一步调用调研Agent第二步调用撰写Agent每一步之间通过结构化的JSON传递结果。这就像工厂流水线每个工位固定干一件事产品按顺序流转。在这个项目里我用的是一个很轻的编排方式写一个pipeline函数接收任务描述依次调用不同的Agent模块每个Agent只是单独的函数内部再用之前run_agent的逻辑。关键接口保持一致都接收字符串任务返回结构化结果。这样随时可以把某个子Agent替换成普通函数方便单元测试。多Agent协作的核心不是“让模型自己商量”而是“让工程代码掌控节奏让模型专注每一步的执行”。4. 部署、评估与运维AI工程化的真正分水岭4.1 模型部署与推理优化GPU资源怎么花在刀刃上前面的一切在本地跑通只是起点一旦要给别人用部署优化就成了头等难题。如果选的是API服务你只需要关注延迟和费用均衡偶尔切换到更便宜的模型即可。但若要私有化部署开源模型这章就是我整理的经验库。首先切勿一上来就上最大参数量模型。7B和13B之间的效果差距在多数业务场景里远比部署成本差距小得多。先跑通效果分析瓶颈再考虑升级模型。部署时我推荐用vLLM或SGLang这类推理框架相比原生Transformers代码同样的硬件吞吐量能提升数倍。核心原理是连续批处理、PagedAttention这些技术它们让GPU显存被更高效利用。一次实测里用vLLM部署7B模型吞吐量从每秒5次请求跳到了30次差别非常直观。显存不够时还有两个成熟方案量化把模型权重压缩到4bit或8bit和切片。4bit量化后的7B模型显存占用能降到6GB左右普通消费级显卡都能跑。代价是生成质量轻微下降但作为内部工具完全能接受。我的建议是优先尝试AWQ或GPTQ量化这俩在效果和速度上最大平衡。部署之后必须监控两个核心指标首Token延迟用户发出请求到看到第一个字的时间和Token吞吐量每秒生成的字数。这两个指标决定了用户体验也决定了成本。我写过一个极简监控脚本每分钟采集一次推理服务的性能和GPU显存占用超过阈值就告警。别小看这一步没有监控的AI服务就跟没有仪表盘的车一样开着心惊胆战。4.2 评估体系没有评测指标AI工程就是盲人摸象做AI工程最担心的不是模型不够聪明而是“不知道现在好不好”。很多人调了几个小时提示词感觉有改善但说不清改善在哪。所以我在项目里专门写了评估模块。评估的关键是先做“评测集”。挑出100条具有代表性的业务问题为每条写好标准答案或答案要点。然后定义指标比如准确率、完整率、格式合规率、不必要的召回率模型是否输出了页面没有的信息。每次改动提示词、更新模型或者调整检索策略都把评测集跑一遍用脚本计算指标对比。这个过程会逼着你把“我觉得好像变好了”变成“准确率从71%提升到79%”。我在开发RAG知识库时就靠评测集发现了一个意外问题增加检索召回数量从3到5虽然召回完整性变高了但错误信息也变多了准确率反而下滑。这个结论如果靠人肉判断得看几十条回答才能偶然发现评测集五分钟就暴露了。评测集本身也要定期更新。线上用户真实问题里会不断出现新表达可以每周抽一定比例真实请求人工标注后加进评测集。这属于数据飞轮做得越久系统越好把控。4.3 可观测性与上线后的持续迭代模型上线只是开始真正的工程化在运维中才见真章。我踩过最典型的坑就是线上用户提出了一个知识库没有覆盖的问题模型胡编了一个答案用户投诉后才追查原因。这背后缺的是日志系统。做AI应用至少要记录四层日志每一轮请求的原始输入输出、模型生成用了多少Token、检索出的文档ID和相关性分数、整个请求链路耗时。这些日志不仅要存还要能方便回溯。比如用户说“答案不对”你能立刻查到他当时的问题、检索到的资料片段、模型输出的原文问题定位效率翻倍。除了日志还要关注成本。每个请求的Token占用直接就是费用。上线后我发现有相当比例的请求把大量上下文传给了模型但真正有用的就一小段。优化方式是把历史对话做压缩只保留最近两轮完整对话更早的用摘要替代。这么调整后单次成本降了近30%回答质量基本没受影响。持续迭代方面我给你一个具体的节奏每周收敛一个指标。要么提高评测集准确率要么降低单位请求成本要么减少极端失败案例。以周为周期每次只改一个变量不要同时换模型又改提示词否则出了问题根本不知道是谁引发的。用这种方式跑了三个月后我对系统的掌控力远超以前“随机调参”的状态。我个人做完“ai-engineering-from-scratch”一个很深的体会是AI工程领域最稀缺的不是模型知识而是工程素养。用评测集说话用日志定位问题用架构控制不确定性——这些能力在任何技术栈里都成立。如果你准备从零开始做自己的AI应用别迷恋“换个更强模型”的捷径先把RAG、Agent、评估这三板斧练扎实。之后你会发现真正难的不是让模型“听懂话”而是让系统“靠得住”。