news 2026/9/29 23:55:13

从零搭建AI工程能力:四层架构与实战避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从零搭建AI工程能力:四层架构与实战避坑指南

1. 从零搭建AI工程能力,为什么大多数人卡在第一步就放弃了

如果你最近在技术社区里频繁看到“ai-engineering-from-scratch”这个说法,不用怀疑,它不是什么新出的框架或者工具库,而是一种学习路径的统称——从零开始,把AI工程化落地所需的整套能力一点点搭起来。我身边有不少朋友,有做后端的、做前端的、甚至做产品经理的,都在问同一个问题:我想搞AI应用,但不想只停留在调API的层面,到底该从哪里下手?

这个问题的答案,其实取决于你怎么定义“从零”。很多人以为从零就是打开一个在线教程,跟着敲一遍pip install,然后跑通一个demo就算入门了。但真正做过项目的人都知道,跑通demo和能交付一个稳定可用的AI功能之间,隔着一整条工程化的鸿沟。模型选型、数据管道、推理服务、成本控制、效果评估、版本迭代——这些东西没有任何一个教程会一次性讲清楚,因为它们本身就是交叉的。

我写这篇东西的目的很直接:把“ai-engineering-from-scratch”这个路径拆开,告诉你每一层需要什么、为什么需要、以及我在实际项目中踩过的那些坑。适合的读者是那些有一定编程基础、想系统性地建立AI工程能力、但又不希望被各种营销概念带偏的人。不管你是想转行做AI应用开发,还是想在现有岗位上增加AI相关的交付能力,这套思路都能直接参考。

需要提前说明的是,AI工程不等于模型训练。绝大多数业务场景下,你不需要自己训练模型,你需要的是把已有的模型能力可靠地集成到系统里,并且让它持续稳定地产生价值。这个认知差,是很多人走弯路的根源。

2. 先搞清楚AI工程到底包含哪些层,别一上来就啃论文

2.1 把AI工程拆成四层来看,心里就有地图了

我习惯把AI工程能力分成四层:基础层、模型层、服务层、应用层。这个分法不是教科书上的标准分类,而是从实际交付角度倒推出来的,每一层对应不同的技能栈和关注点。

基础层是地基,包括Python工程能力、数据处理、API调用、基本的系统设计。这一层不过关,后面全是空中楼阁。我见过太多人直接跳到模型层,结果连一个异步请求都写不明白,服务一上量就崩。

模型层不是让你去训练大模型,而是理解模型的能力边界、输入输出格式、推理参数的含义。比如temperature和top_p到底怎么影响输出,token是怎么计算的,上下文窗口超了会怎样。这些东西不需要你懂Transformer的数学推导,但必须懂它的行为特征。

服务层是把模型能力封装成可调用的服务。这里涉及API设计、并发处理、缓存策略、错误重试、限流降级。这一层是AI工程和普通后端开发重叠最多的部分,也是最能体现工程功底的地方。

应用层是最终面向业务的部分,包括Prompt设计、结果后处理、效果评估、用户反馈闭环。这一层看起来简单,实际上最考验对业务的理解。

2.2 为什么我不建议一上来就学模型训练

很多人一提到AI工程,第一反应是“我得先学机器学习”。这个想法在五年前是对的,但现在情况变了。绝大多数业务场景用的是预训练好的模型,通过API或者本地部署的方式调用。你需要的不是梯度下降的推导能力,而是理解模型能做什么、不能做什么、怎么让它稳定输出你想要的结果。

我举个例子。假设你要做一个合同关键信息提取的功能。自己训练一个NER模型,你需要标注数据、选模型架构、调参、部署、维护,周期至少几个月。而用现成的模型能力加上合理的Prompt设计,可能一周就能跑通,效果还更好。这不是说模型训练不重要,而是说对于“从零搭建AI工程能力”这个目标来说,优先级应该放在工程化能力上,而不是算法研究上。

当然,如果你所在团队确实需要微调模型来解决特定问题,那另当别论。但那是进阶话题,不是起点。

2.3 一张表看清四层各自的核心技能和常见误区

层级核心技能常见误区
基础层Python异步编程、HTTP协议、JSON处理、环境管理用同步思维写AI调用,忽略超时和重试
模型层模型能力评估、Token计算、参数调优、上下文管理把模型当黑盒,不测试边界情况
服务层API设计、并发控制、缓存、监控告警没有降级方案,模型挂了整个服务不可用
应用层Prompt工程、结果校验、效果评估、反馈闭环只看单次输出,不做系统性评估

这张表建议你保存下来,每学一块就对照一下自己是不是真的掌握了。我当初就是吃了亏,服务层没做好,模型一超时整个请求链路全堵死,排查了一整天才找到问题。

3. 基础层怎么打:Python工程能力比算法知识更紧迫

3.1 异步编程是AI应用的第一道门槛

AI应用的典型特征是高延迟、高并发、IO密集。你调用一次模型接口,可能等两三秒才返回。如果用同步的方式写,一个请求占一个线程,并发量稍微上来线程池就满了。所以异步编程是必须掌握的。

Python的asyncio和aiohttp是基础中的基础。我建议你从写一个简单的异步请求封装开始,把超时、重试、错误处理都加进去。下面是我常用的一个模板,你可以直接参考:

import asyncio import aiohttp from typing import Optional async def call_model_api( session: aiohttp.ClientSession, payload: dict, timeout: int = 30, max_retries: int = 3 ) -> Optional[dict]: for attempt in range(max_retries): try: async with session.post( "https://api.example.com/v1/chat", json=payload, timeout=aiohttp.ClientTimeout(total=timeout) ) as resp: if resp.status == 200: return await resp.json() elif resp.status == 429: await asyncio.sleep(2 ** attempt) continue else: resp.raise_for_status() except asyncio.TimeoutError: if attempt == max_retries - 1: raise await asyncio.sleep(1) return None

这段代码看起来简单,但包含了几个关键设计:指数退避重试、超时控制、状态码分类处理。我见过很多项目直接用requests同步调用,上线后并发一高就各种超时,排查半天发现是线程池不够用。

3.2 环境管理和依赖隔离,别等到冲突了才后悔

Python的依赖管理是个老生常谈的问题,但在AI项目里尤其突出。因为AI相关的库更新快、依赖多、版本兼容性差。我强烈建议用poetry或者uv来管理依赖,不要用全局的pip install。

另外,模型相关的依赖和业务依赖最好分开。比如你把torch和fastapi装在一个环境里,镜像体积会大到离谱,部署的时候拉镜像都要等半天。我的做法是:模型推理单独一个服务,业务逻辑单独一个服务,通过HTTP或者消息队列通信。这样不仅依赖清晰,扩缩容也灵活。

3.3 日志和可观测性,从第一天就要做

AI应用有个特点:出问题的时候很难复现。同样的输入,模型可能返回不同的结果。所以日志必须记录完整的请求和响应,包括Prompt、参数、返回内容、耗时。我一般会在日志里记录这几个字段:

  • request_id:全链路追踪
  • prompt_hash:方便去重和统计
  • model_name和params:定位模型版本和参数
  • latency_ms:监控性能
  • token_usage:成本核算

这些字段看起来多,但真出问题的时候,少一个你就要花几倍的时间去排查。我吃过这个亏,有一次线上返回异常,但日志里只记了结果没记Prompt,完全不知道用户输入了什么,最后只能靠猜。

4. 模型层的关键认知:把模型当组件,不是当魔法

4.1 理解Token机制,才能控制成本和延迟

Token是模型处理文本的基本单位。英文大概一个单词对应一个多Token,中文一个字可能对应一到两个Token。这个机制直接影响两件事:成本和延迟。

成本方面,API调用通常按Token计费,输入和输出分别计价。如果你不注意控制Prompt长度,成本会迅速膨胀。我做过一个统计,把系统Prompt从500 Token压缩到200 Token,每月成本直接降了三分之一。

延迟方面,输出Token数越多,生成时间越长。如果你只需要一个分类结果,不要让模型输出一整段解释。用max_tokens参数限制输出长度,同时在Prompt里明确要求简短回答。

提示:不同模型对Token的计算方式略有差异,建议在项目初期就用实际数据测一下,建立自己的Token估算表。

4.2 参数调优不是玄学,有明确的取舍逻辑

模型推理参数里最常调的是temperature、top_p、max_tokens、presence_penalty和frequency_penalty。很多人调参数靠感觉,其实每个参数都有明确的作用方向。

temperature控制随机性。值越低输出越确定,适合分类、提取这类需要稳定结果的任务。值越高输出越多样,适合创意生成。我一般做信息提取时用0到0.3,做文案生成时用0.7到1.0。

top_p是另一种控制随机性的方式,通常和temperature二选一调。它的逻辑是只从累积概率前p的Token里采样。值越小输出越保守。

presence_penalty和frequency_penalty用来抑制重复。前者惩罚已经出现过的Token,后者按出现频率惩罚。做长文本生成时适当加一点,能有效减少车轱辘话。

我的经验是:先固定一组默认参数,然后在实际数据上做A/B测试,用效果指标说话,不要凭感觉调。

4.3 上下文窗口管理,超长输入的处理策略

每个模型都有上下文窗口限制,比如4K、8K、32K、128K Token。超过限制会直接报错。处理长文本有几种常见策略:

  • 截断:只取前N个Token,简单但会丢信息
  • 分段处理:把长文本切成多段分别处理,再合并结果
  • 摘要压缩:先用模型把长文本压缩成摘要,再基于摘要做后续处理
  • 检索增强:把长文本存到向量库,按需检索相关片段

这几种策略没有绝对优劣,取决于你的场景。做合同审查适合分段加合并,做知识问答适合检索增强。我一般会先评估信息密度,如果关键信息集中在局部,检索增强最划算;如果全文都重要,分段处理更稳妥。

5. 服务层才是分水岭:让AI能力稳定可用的工程手段

5.1 API设计的几个关键决策

把模型能力封装成API的时候,有几个设计决策会直接影响后续的维护成本。

第一个是同步还是异步。如果模型推理时间在几秒内,同步接口可以接受。但如果可能超过10秒,建议用异步任务模式:提交任务返回task_id,客户端轮询或者通过Webhook获取结果。这样避免连接超时,也方便做任务队列和优先级控制。

第二个是批量还是单条。有些场景适合批量处理,比如离线数据标注。批量接口能显著提高吞吐量,但要注意单次批量不要太大,否则容易超时。我一般控制在10到20条一批。

第三个是版本管理。模型会更新,Prompt会迭代,接口要能兼容不同版本。我的做法是在请求里加一个version字段,服务端根据版本路由到不同的处理逻辑。这样新老版本可以并行运行,逐步迁移。

5.2 缓存策略:省钱和提速的双刃剑

AI调用的成本不低,缓存是最直接的优化手段。但缓存有个关键问题:同样的输入,模型可能返回不同结果。所以缓存策略要分场景。

对于确定性任务,比如信息提取、分类,如果参数固定,结果基本稳定,可以放心缓存。缓存键用输入文本的哈希加上参数组合。

对于生成式任务,比如文案创作,每次结果都应该不同,缓存意义不大。但可以考虑缓存中间结果,比如检索到的文档片段。

我一般会用两级缓存:本地内存缓存热点请求,Redis缓存全量结果。本地缓存用LRU策略,设置合理的过期时间。这里有个坑:如果模型版本更新了,缓存必须失效,否则会返回旧结果。所以缓存键里一定要包含模型版本号。

5.3 限流、降级和熔断,别等故障了才想起来

AI服务依赖外部API,网络抖动、服务限流、额度耗尽都是可能发生的。如果没有降级方案,整个功能就不可用了。

限流方面,我一般会在客户端和服务端都做。客户端控制并发数,服务端按用户或按接口限流。用令牌桶或者滑动窗口算法都可以,Python里slowapi或者自己实现都不复杂。

降级方面,准备一个兜底逻辑。比如模型调用失败时,返回缓存结果或者默认值,而不是直接报错。对于非核心功能,甚至可以暂时关闭,保证主流程可用。

熔断方面,当错误率超过阈值时,自动切断对模型服务的调用,过一段时间再试探性恢复。这个用pybreaker之类的库就能实现。

注意:降级逻辑一定要在测试环境验证过,否则真出故障的时候,降级代码本身可能有bug,那就雪上加霜了。

5.4 监控告警:没有度量就没有改进

AI服务的监控和传统服务略有不同,除了QPS、延迟、错误率这些常规指标,还要关注模型特有的指标:

  • Token消耗速率:突然飙升可能是被刷了或者Prompt有bug
  • 输出长度分布:异常变长或变短都可能是模型行为变化
  • 拒绝率:模型拒绝回答的比例,过高说明Prompt需要调整
  • 缓存命中率:太低说明缓存策略有问题

告警阈值要根据历史数据来定,不要拍脑袋。我一般会观察一周的基线,然后设置3倍标准差作为告警线。告警通道用邮件加即时消息,确保能及时响应。

6. 应用层的实战细节:Prompt设计、结果校验和效果评估

6.1 Prompt设计的核心原则:清晰、具体、有约束

Prompt设计不是写作文,不需要华丽的辞藻。核心原则就三条:指令清晰、格式具体、边界明确。

指令清晰是指告诉模型做什么,而不是让它猜。比如“提取合同中的甲方名称”比“分析这个合同”要清晰得多。

格式具体是指明确输出格式。用JSON就用JSON Schema描述清楚,用列表就说明每项包含什么。我一般会在Prompt里给一个输出示例,模型模仿能力很强,有示例的情况下格式准确率会高很多。

边界明确是指告诉模型遇到不确定的情况怎么处理。比如“如果找不到相关信息,返回null,不要编造”。这一条能大幅减少幻觉。

我常用的Prompt结构是这样的:

角色:你是一个合同信息提取助手。 任务:从以下合同文本中提取甲方名称、乙方名称、合同金额、签署日期。 输出格式:JSON,包含字段 party_a, party_b, amount, sign_date。 约束: - 如果某个字段无法确定,值设为 null - 金额只保留数字,单位元 - 日期格式为 YYYY-MM-DD 合同文本: {contract_text}

这个结构看起来简单,但比随便写一句“帮我提取合同信息”的效果要好得多。

6.2 结果校验:模型输出不可全信

模型输出必须经过校验才能进入业务流程。校验分两层:格式校验和内容校验。

格式校验用JSON Schema或者Pydantic做,确保字段齐全、类型正确。这一步能拦截大部分低级错误。

内容校验更复杂一些。比如提取的金额是否在合理范围内,日期是否合法,名称是否在已知列表里。这些规则需要结合业务来定。我一般会写一个校验函数,对每个字段做规则检查,不通过的标记出来人工复核。

还有一个实用技巧:让模型自己给出置信度。在Prompt里要求模型对每个提取结果标注高、中、低置信度,低置信度的结果优先人工检查。这样能大幅提高人工复核的效率。

6.3 效果评估:建立可量化的评估体系

没有评估就没有优化。AI应用的效果评估需要一套指标体系,不能只看“感觉准不准”。

我一般会从三个维度评估:

  • 准确率:提取类任务看字段级准确率,生成类任务看人工评分
  • 一致性:同样输入多次调用,结果是否稳定
  • 覆盖率:能自动处理的比例,需要人工介入的比例

评估数据集要提前准备,覆盖各种边界情况。我一般会准备至少100条测试数据,包含正常案例、边界案例和异常案例。每次Prompt调整或者模型切换,都跑一遍评估集,对比指标变化。

这里有个经验:评估集要持续更新。线上发现的新case要补充进去,否则评估集和实际分布会越来越脱节。

6.4 反馈闭环:让系统越用越好

AI应用上线不是终点,而是起点。用户反馈是优化的重要来源。我一般会在产品里加一个简单的反馈入口,让用户标记结果是否正确。这些标记数据积累起来,就是宝贵的优化素材。

反馈数据可以用来做几件事:一是补充评估集,二是分析错误模式,三是作为微调的种子数据。即使不做微调,分析错误模式也能帮你发现Prompt的盲区。

我做过一个项目,上线初期准确率只有70%左右,通过分析用户反馈发现主要是日期格式和金额单位的问题。调整Prompt后准确率提升到90%以上。这个过程没有改模型,纯粹是工程优化。

7. 我踩过的几个典型坑和对应的解法

7.1 超时设置不合理导致雪崩

项目初期,我把模型调用的超时设成了60秒,觉得留足时间更稳妥。结果有一次模型服务响应变慢,大量请求堆积,线程池被占满,整个服务不可用。

后来我把超时改成动态的:根据历史P99延迟设置,一般比P99多50%的余量。同时加了熔断机制,错误率超过阈值直接快速失败,不再等待。这样即使模型服务出问题,也不会拖垮整个系统。

7.2 Prompt里放了太多示例导致Token爆炸

为了让模型输出更准确,我在Prompt里放了大量示例。结果Token消耗飙升,成本翻了好几倍,而且延迟也增加了。

后来我做了精简:只保留最典型的两个示例,其他用规则约束代替。效果没有明显下降,但Token消耗降了60%。这个经验告诉我,Prompt优化要在效果和成本之间找平衡,不是越多越好。

7.3 忽略模型版本更新导致效果波动

有一次模型服务商悄悄更新了模型版本,输出风格发生了变化,导致下游的解析逻辑大量报错。因为没有版本锁定机制,排查了很久才发现是模型变了。

从那以后,我在请求里固定模型版本号,服务商更新时先在小流量上测试,确认兼容后再全量切换。同时解析逻辑也做了兼容处理,对格式变化有一定的容错能力。

7.4 没有做输入长度检查导致报错

用户输入超长文本时,直接调用模型会报上下文超限错误。早期没有做检查,错误直接抛给用户,体验很差。

后来在入口处加了长度检查,超长文本自动走分段处理流程。同时在Prompt里也加了说明,让模型知道输入可能被截断,尽量基于已有信息回答。

8. 从能跑到好用,中间隔着持续迭代

“ai-engineering-from-scratch”这个路径,说到底是一个从理解基本概念到建立完整工程能力的过程。基础层让你能写出可靠的代码,模型层让你理解模型的行为特征,服务层让你能交付稳定的服务,应用层让你能持续优化效果。这四层缺一不可,但优先级应该是从下往上的。

我在实际项目中的体会是,大部分问题不是模型能力不够,而是工程没做到位。超时没设好、缓存没做对、降级没准备、评估没体系——这些看起来不酷的东西,恰恰决定了AI功能能不能真正用起来。

如果你正在走这条路,我的建议是:不要追求一步到位,先跑通一个最小闭环,然后针对每个环节逐步优化。每优化一个点,就记录下前后的指标变化。积累下来,你不仅有了一个可用的系统,还有了一套自己的工程方法论。这比任何教程都值钱。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/29 23:55:01

YOLO石油泄露数据集实战:三种标签格式转换与训练全流程

简介:面向目标检测学习者与石油泄漏监测应用开发者,这份YOLO石油泄露目标检测数据集提供了真实场景下的高质量图像与人工标注,可支撑从YOLO环境搭建、数据格式转换到模型训练与验证的完整流程。压缩包共2000个文件,容量约117MB&am…

作者头像 李华
网站建设 2026/9/29 23:54:53

Model-Optimizer实战:量化剪枝与算子融合优化全流程

1. 模型优化器到底在解决什么问题第一次接触 Model-Optimizer 这个概念,是在一个推荐系统的排序模型上。当时线上推理延迟死活压不下去,单次请求要跑 180ms,业务方要求降到 80ms 以内。我一开始的想法很朴素——加机器、换更强的 GPU&#xf…

作者头像 李华
网站建设 2026/9/29 23:54:33

p2pDemo拆解:NAT穿透、UDP打洞与信令服务器实战

简介:点对点(P2P)技术绕开传统客户端-服务器模型,让每个节点同时充当服务端与客户端,直接进行资源共享和通信。这份p2pDemo示例正是围绕该技术打造的实操演示,适合网络编程学习者和分布式系统开发者&#x…

作者头像 李华
网站建设 2026/9/29 23:52:48

VS Code搭建Microchip PIC32开发环境实战指南

1. 为什么放弃MPLAB X IDE,转而用VS Code搭Microchip MCU开发环境?我第一次在客户现场调试PIC32MZ EF系列时,连续三天卡在同一个问题上:烧录后程序不运行,串口无任何输出。MPLAB X IDE的调试器窗口里堆着几十行“Targe…

作者头像 李华
网站建设 2026/9/29 23:52:34

XDMA驱动DLL封装实战:PCIe上位机高速DMA读写接口设计

简介:面向PCIE开发人员的Xilinx xdma驱动底层读写DLL封装资源,基于xdma IP核实现高性能PCIe通信,将繁琐的硬件访问接口封装成动态链接库,便于C或C#应用直接调用,省去底层驱动操作门槛。压缩包共45个文件,约…

作者头像 李华
网站建设 2026/9/29 23:52:05

从802.11ax到Wi-Fi 6:协议原理、路由器选购与实战优化

1. ax是什么:从802.11ax到Wi-Fi 6的命名纠葛 路由器型号里那个"AX"后缀,近几年的出镜率实在太高了。AX1800、AX3000、AX5400,从一两百的入门款到两三千的旗舰款,几乎每个品牌都在用这个词。我第一次看到"AX3000&qu…

作者头像 李华