拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

从零搭建AI工程体系:分层架构、评测与可观测性实战

从零搭建AI工程体系:分层架构、评测与可观测性实战

1. 从零搭建AI工程能力:为什么我劝你别一上来就调包

这两年AI应用开发的门槛肉眼可见地降低了,一个刚入门的开发者,装好环境、拿到API Key,半天时间就能跑出一个能对话的Demo。但我带过不少新人,也看过很多团队的项目,发现一个很普遍的现象:Demo跑得飞快,一旦要上线、要迭代、要处理真实业务数据,问题就全冒出来了。模型输出不稳定、成本失控、响应慢、幻觉频发、评测没有标准、改一个Prompt结果另一条链路崩了——这些都不是“调个包”能解决的,它们属于AI工程的范畴。

“ai-engineering-from-scratch”这个标题,我理解的核心不是“从零训练一个大模型”,那既不现实也没必要。它真正指向的是:从零构建一套能支撑AI应用稳定运行的工程体系。这包括数据管线的搭建、Prompt与上下文的管理、模型调用层的抽象、评测与回归机制、成本与延迟的监控、以及上线后的可观测性。说白了,就是让AI应用从“能跑”变成“能扛”。

这套东西适合谁?如果你是把AI当玩具玩玩的爱好者,可能觉得这些太重了;但如果你是要把AI能力真正落到产品里、要对结果负责的开发者或技术负责人,那这些工程能力就是绕不过去的坎。我自己踩过的坑告诉我,越早建立这套体系,后面越省心。下面我就按自己实际搭建的顺序,把每个环节拆开讲清楚,包括为什么这么设计、具体怎么做、以及我踩过的那些坑。

2. 整体架构设计:先想清楚分层,再动手写代码

2.1 为什么不能把所有逻辑塞进一个函数

我见过最典型的“反面教材”,是一个几百行的Python脚本:读用户输入、拼Prompt、调模型、解析结果、写数据库,全在一个函数里。刚开始跑得挺欢,等到要换模型、要加缓存、要做A/B测试的时候,改一处就牵一发而动全身。这就是没有分层的代价。

从零搭建AI工程,第一件事是分层。我的经验是至少分成四层:接入层、编排层、模型层、数据与观测层。接入层负责接收请求、鉴权、限流;编排层负责Prompt组装、上下文管理、工具调用、结果解析;模型层负责统一封装不同厂商的模型调用;数据与观测层负责日志、指标、评测数据的沉淀。这样分层之后,换模型只动模型层,改业务逻辑只动编排层,互不干扰。

提示:分层不是为了“看起来专业”,而是为了在需求变化时把改动范围控制到最小。这一点在AI应用里尤其重要,因为模型和Prompt的迭代频率远高于传统后端。

2.2 技术选型背后的取舍逻辑

选型这块我不推荐盲目追新。语言上,Python生态最成熟,LangChain、LlamaIndex这类编排框架、各种评测库都齐全,适合快速起步;但如果你的主业务是Java或Go,也没必要为了AI单独切语言,用HTTP把AI服务独立出来即可。我的做法是:AI能力做成独立的服务,通过标准接口对外暴露,主业务用什么语言都不影响。

编排框架要不要用?我的建议是:初期可以用,但一定要理解它帮你做了什么。LangChain这类框架封装了大量细节,上手快,但出问题时排查成本高,而且版本迭代快、破坏性变更多。我自己的做法是,核心链路尽量用原生SDK手写,框架只用来做原型验证。这样虽然前期多写点代码,但可控性强得多。

存储方面,向量库选型要看数据规模。几万条以内,用FAISS这种本地库就够了;上百万条再考虑Milvus、Qdrant这类专业向量数据库。别一上来就上重型方案,运维成本会吃掉你大量精力。

2.3 目录结构长什么样

一个清晰的目录结构能省掉很多沟通成本。我常用的结构大致是这样:

ai-service/ api/ # 接入层:路由、鉴权、限流 orchestration/ # 编排层:prompt、上下文、工具调用 models/ # 模型层:各厂商客户端封装 evaluation/ # 评测:数据集、指标、回归脚本 observability/ # 观测:日志、指标、追踪 configs/ # 配置:模型参数、prompt模板 tests/ # 测试

这个结构的好处是,任何人拿到项目,一眼就能知道去哪找什么。尤其是evaluation和observability这两个目录,很多项目一开始没有,等到出问题才补,结果发现历史数据全丢了,非常被动。

3. 核心模块拆解:每个环节的关键细节

3.1 模型调用层:统一封装是刚需

模型调用层最核心的价值是屏蔽差异。不同厂商的API在参数命名、返回结构、错误码、流式输出格式上都不一样。如果业务代码直接调各家SDK,换模型时就是灾难。我的做法是定义一个统一的接口,比如generate(messages, **kwargs),内部再适配各家。

这里有个细节值得说:重试与超时策略。模型调用失败是常态,网络抖动、限流、服务端偶发错误都会导致失败。我一般设置指数退避重试,最多3次,超时按模型类型区分——对话类给30秒,长文本生成给120秒。但要注意,不是所有错误都该重试,比如参数错误、内容审核拦截,重试多少次都没用,反而浪费配额。所以错误分类很重要。

def call_with_retry(fn, max_retries=3, base_delay=1.0): for attempt in range(max_retries): try: return fn() except RetryableError as e: if attempt == max_retries - 1: raise time.sleep(base_delay * (2 ** attempt)) except FatalError: raise

另一个容易被忽略的点是Token计数。很多厂商的返回里带usage字段,但流式输出时往往拿不到。我的做法是在调用前用tokenizer预估,调用后再用实际值校正,两者都记录下来,用于成本核算。

3.2 Prompt与上下文管理:别把Prompt写死在代码里

Prompt写死在代码里,是我见过最常见的坏习惯。一旦要调整,就得改代码、走发布流程,效率极低。正确做法是Prompt模板化、配置化,放在独立的配置文件或配置中心里,支持热更新。

模板化还有个好处是版本管理。每次Prompt变更都应该有版本号,配合评测数据,能清楚知道这次改动是变好了还是变差了。我一般用类似prompt_v3_20240501这样的命名,配合Git管理,回滚非常方便。

上下文管理是另一个重灾区。多轮对话时,历史消息无限增长,Token很快爆掉。常见策略有几种:滑动窗口(只保留最近N轮)、摘要压缩(把早期对话总结成一段话)、关键信息抽取(只保留实体和意图)。我的经验是,摘要压缩+关键信息抽取组合使用效果最好,既保留了长期记忆,又控制了Token量。但摘要本身也要调模型,有额外成本,所以要权衡。

注意:上下文裁剪一定要保留系统Prompt和最近一轮用户输入,这两部分丢了,模型基本就“失忆”了。

3.3 评测体系:没有评测就没有迭代

这是我认为从零搭建AI工程里最重要、也最容易被跳过的一环。很多人改Prompt、换模型,全凭“感觉好像好了一点”,这是非常危险的。没有量化评测,你根本不知道改动是优化还是劣化。

评测体系至少包含三部分:评测数据集、评测指标、回归流程。数据集要覆盖典型场景和边界情况,我一般会攒几百条真实业务问题,人工标注期望输出或评分标准。指标方面,分类任务看准确率、召回率,生成任务可以用BLEU、ROUGE这类自动指标,但更靠谱的是用模型评模型(LLM-as-Judge),让一个强模型给输出打分,配合人工抽检校准。

回归流程是关键:每次Prompt或模型变更,自动跑一遍评测集,对比新旧版本的指标。如果指标下降超过阈值,就阻断发布。这套流程搭起来要花点时间,但一旦跑通,迭代效率会提升一个量级。

评测维度常用方法适用场景
准确性人工标注+准确率分类、抽取
相关性LLM评分问答、对话
安全性规则+模型审核所有生成场景
一致性多次采样对比需要稳定输出的场景
延迟端到端计时所有线上场景

3.4 可观测性:上线只是开始

AI应用上线后,最怕的就是“黑盒”——用户反馈不好,但你不知道是哪一步出了问题。可观测性要解决的就是这个。我一般记录三类数据:请求日志(输入、输出、模型、参数、耗时)、指标(QPS、延迟分布、错误率、Token消耗)、追踪(一次请求经过哪些环节,每步耗时多少)。

日志里有个细节:用户输入和模型输出要脱敏。真实业务数据里可能有手机号、身份证号,直接落库有合规风险。我一般用正则做基础脱敏,敏感场景再加一层专门的脱敏服务。

指标监控要设告警。比如错误率超过5%、P99延迟超过阈值、单日Token消耗超过预算,都要及时通知。我踩过的坑是:有次模型厂商悄悄调整了默认参数,导致输出变短、质量下降,但因为没监控输出长度分布,过了好几天才发现。从那以后,我把输出长度、拒绝率、异常格式率都加进了监控。

4. 实操落地:从零到跑通的完整流程

4.1 环境准备与依赖管理

第一步是把环境搭起来。Python项目我强烈建议用uv或poetry做依赖管理,别用裸pip。原因很简单:AI项目依赖多、版本冲突频繁,没有锁文件,换台机器就装不起来。uv速度快,poetry生态成熟,选哪个都行。

# 用uv初始化项目 uv init ai-service cd ai-service uv add openai faiss-cpu pydantic fastapi

配置文件用.env管理密钥,但千万别把.env提交到Git。我一般提供.env.example,里面写清楚需要哪些变量,新人照着填就行。密钥读取统一走一个config模块,方便后续换成密钥管理服务。

4.2 最小可用链路:先跑通再优化

别一上来就追求完美架构。我的做法是先搭一条最小可用链路:接收请求→组装Prompt→调模型→返回结果。这条链路跑通后,再逐步加缓存、加重试、加评测。

from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class Query(BaseModel): text: str @app.post("/generate") def generate(q: Query): prompt = build_prompt(q.text) result = model_client.generate(prompt) return {"result": result}

这条链路虽然简单,但已经能验证核心流程。接下来每加一个能力,都确保它不破坏已有功能,这就是工程化的思路。

4.3 参数调优:温度、Top-p到底怎么设

模型参数不是随便填的。温度(temperature)控制随机性,0接近确定性输出,1以上发散。做事实问答、数据抽取,温度设0到0.3;做创意写作,可以设0.7到1.0。Top-p是另一种采样策略,一般和温度二选一调,不要同时大改。

我一般会针对每个场景做小规模实验:固定其他参数,只调一个,看评测指标变化。比如抽取任务,温度从0.7降到0.2,准确率可能提升十几个点。这些都要靠评测数据说话,不能拍脑袋。

提示:有些模型对参数不敏感,有些非常敏感。换模型后,原来的参数不一定适用,一定要重新跑评测。

4.4 成本控制:别让账单吓到你

Token成本是AI应用绕不开的话题。控制成本有几个实用手段:缓存(相同或相似请求直接返回缓存结果)、模型分级(简单任务用小模型,复杂任务用大模型)、Prompt精简(去掉冗余示例和说明)、输出长度限制(设置max_tokens)。

缓存这块要注意,语义缓存比精确匹配缓存命中率高得多。用向量相似度判断两个请求是否等价,相似度超过阈值就复用结果。但阈值不能太低,否则会返回不相关的结果,我一般设在0.95以上。

模型分级我一般用路由实现:先用规则或小模型判断任务复杂度,简单任务走便宜模型,复杂任务走强模型。实测下来,成本能降一半以上,质量损失很小。

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

5.1 模型输出格式不稳定怎么办

这是最高频的问题。你要求输出JSON,它偏要加一段解释文字。解决办法有几个层次:Prompt里明确格式要求(给出示例)、用结构化输出功能(很多厂商支持JSON mode)、加解析容错(正则提取JSON部分)、解析失败时重试。我的经验是,Prompt示例+JSON mode组合,能把格式错误率降到1%以下。

5.2 响应太慢怎么优化

延迟优化要分环节看。如果是模型本身慢,考虑换更快的模型或开启流式输出;如果是网络慢,考虑就近部署;如果是编排逻辑慢,检查有没有串行的多余调用。流式输出对用户体验提升巨大,首Token时间能从几秒降到几百毫秒,强烈建议对话类场景都开。

5.3 幻觉问题怎么缓解

幻觉没法根除,只能缓解。常用手段:提供参考资料(RAG)、要求引用来源、降低温度、加事实校验环节。RAG是最有效的,把相关知识检索出来塞进上下文,模型有据可依,幻觉会大幅减少。但检索质量本身也是个大坑,召回不准,反而会误导模型。

5.4 常见问题速查表

问题现象可能原因排查方向
输出格式错乱Prompt不明确/模型不支持加示例、开JSON mode
响应超时模型慢/网络差/逻辑阻塞查耗时分布、开流式
成本飙升上下文过长/缓存失效查Token分布、查缓存命中
质量下降模型变更/Prompt改动跑评测对比、查版本
偶发失败限流/网络抖动加重试、查错误码分布

5.5 我踩过的几个坑

第一个坑是忽略Token预估,有次上线一个长文本总结功能,没限制输入长度,用户传了篇几万字的文章,直接超限报错,还扣了钱。后来加了输入长度校验和截断逻辑。

第二个坑是评测集和线上分布不一致。评测集里都是标准问题,线上用户问得五花八门,导致评测指标很好看,线上体验却很差。后来我定期从线上日志里采样,补充进评测集,才慢慢对齐。

第三个坑是没做灰度发布。有次改Prompt直接全量上线,结果某类问题回答质量暴跌,被用户投诉。后来改成先放10%流量,观察指标没问题再全量。

6. 后续扩展方向:这套体系还能怎么用

这套从零搭建的AI工程体系,跑通之后扩展性很强。往深了做,可以接入多模型路由,根据任务类型自动选模型;可以加Agent能力,让模型调用工具完成复杂任务;可以做微调,用积累的业务数据训练专属模型。往广了做,可以把评测、观测能力沉淀成平台,供多个AI应用复用。

我个人觉得,最有价值的扩展方向是数据飞轮:把线上请求、用户反馈、评测结果串起来,形成持续优化的闭环。用户点踩的回答自动进评测集,模型迭代后自动回归验证,好的结果反哺Prompt和微调数据。这个飞轮转起来,AI应用才会越用越聪明。

最后分享一个小技巧:把每次线上问题都当成评测集的补充。用户报的每一个bad case,脱敏后加进评测集,下次迭代就能自动验证是否修复。坚持几个月,你的评测集就是最贴合业务的资产,比任何公开数据集都值钱。

返回列表