一人交付笔记

一人交付实验

从模型服务、LLM 工具编排到数据与算法,拆解一套私有化 AI 应用真正落地时需要一起设计的三层栈。

很多 AI 项目的失败,不是模型选错了,而是只做了「模型」这一层。

一个能交付的 AI 应用,通常要同时解决三件事:模型怎么稳定地跑起来、LLM 怎么和业务工具接上、数据与算法怎么形成闭环。我把它们叫做 AI 工程落地的三层栈。这篇用我做过的金融级私有化项目拆开讲。

AI 工程落地的三层栈

第一层:模型服务,不是「写个 Flask 调模型」

模型服务层要回答的问题很具体:模型怎么加载、怎么批处理、怎么在 CPU/GPU 之间切换、怎么预热、怎么观测、怎么升级。

在内容识别场景里,我用 YOLOv5 做检测、PaddleOCR 做文字识别(det + rec),模型导出 ONNX 后部署到 Triton Inference Server。Triton 里维护了 5 个模型仓库:检测和识别走 ONNX Runtime backend,前后处理用 Python backend 自己实现;max_batch_size 最高到 1000,其中 2 个模型配置了 model warmup。

为什么用 Triton,而不是直接在 Flask 里加载模型?因为交付环境要考虑的不只是「推理一次」:多个模型要共存、请求要批处理、CPU/GPU 要有不同配置、模型升级要能回滚、进程重启后要能自动预热。Triton 提供的模型仓库和 backend 机制,把这些事收敛到了配置层;业务代码只负责调用,不负责管理模型生命周期。

Triton 模型仓库与 CPU/GPU 双版本

对外接口是 Flask + waitress,部署在 Kubernetes 的 Deployment / Service 上。客户环境不一定有 GPU,所以同一套服务提供 CPU / GPU 双版本;在没有 GPU 的银行客户环境里,CPU 版本稳定吞吐大约 7–10 req/s,具体会随请求内容大小浮动。

这一层最容易被低估的是「前后处理」。检测框怎么裁、OCR 的 det/rec 怎么串、图片怎么归一化、批量请求怎么拼,这些都不在模型文件里,却直接决定吞吐和准确率。把它们放进 Python backend,而不是散落在业务代码里,是我认为最值得的一个取舍。

模型服务还有几个必须提前想清楚的失败模式:图片超大导致显存/内存暴涨;批量请求里混入损坏文件导致整批失败;模型版本升级后输出格式变化;CPU 环境下超时。这些不是「模型准不准」的问题,而是「服务能不能稳定交付」的问题。

模型服务的观测与回滚

模型服务的日志不能只记「成功/失败」。我至少会记录:输入尺寸、批大小、推理耗时、CPU/GPU、模型版本、错误类型。这样线上变慢时,才能判断是流量、模型还是环境的问题。

回滚也要提前设计:模型仓库按版本命名,配置里锁定版本;新版本先在一小部分请求上验证,再全量切换;切换失败时能回到上一版,而不是重新导出模型。对私有化客户来说,「能不能回滚」往往比「新模型准不准」更重要,因为客户环境里没有人能帮你现场调试。

第二层:LLM 应用,重点是工具编排

LLM 应用层不是「接一个聊天接口」就结束了。真正的价值在于:把自然语言变成对内部系统的可靠调用。

我做过两个方向:

AI 智询:用户用自然语言描述需求,系统做意图识别,然后路由到最合适的内部接口或工具,完成多步调用。它把过去需要在菜单里点很多次的流程,收敛成一次对话。难点不在 prompt,而在工具边界的定义:哪些工具可以暴露、参数怎么校验、失败怎么回滚、权限怎么继承。

AI 鉴敏:用语义分析识别用户行为与内容中的敏感信息,相比关键词匹配降低误判。它同样私有化部署在客户环境里,数据不出门。

这两个应用有一个共同约束:私有化部署。模型、向量、日志、工具调用都不能离开客户环境。这个约束会反过来影响架构:你不能依赖一个云端 LLM API 做所有事,要在本地做模型服务、缓存、降级和审计;你也不能把业务数据随便塞进第三方工具。

工具编排最容易犯的错误,是把「模型能调用」当成「模型可以随便调用」。我的做法是:每个工具都有明确的输入 schema、权限要求和失败语义;模型只负责选择工具和填参数,真正的执行、鉴权和审计由后端完成。这样即使模型选错工具,也不会越权。

权限模型也要按「用户身份」而不是「模型身份」设计。模型只是发起调用的一个环节,最终执行时仍然要带当前用户的身份、租户和角色;不能因为「是 AI 发起的」就绕过 RBAC。否则一次 prompt 注入,就可能变成一次越权操作。

第三层:数据与算法,决定系统是不是「越用越准」

第三层最容易被忽略,但它决定 AI 应用是不是只有 demo 价值。

在用户行为分析场景里,系统每天采集千万级的桌面操作元事件。我们用 Python + Pandas / NumPy 按业务配置的异常规则做清洗、转换与特征工程,归纳到约 30 万条样本、4–10 维特征(分类 + 数值),在模型效率与检出效果之间取平衡;日均百万级预测。

这一层的关键不是「用哪个模型」,而是「数据怎么变成可解释的特征」。异常规则来自业务,特征工程要能回答「为什么这个用户被判定为异常」;如果模型只给一个分数,客户环境里没人敢用。

另一块是事件序列关联分析。我独立设计并实现了一个轻量的事件序列正则引擎:

  • 词法 / 语法分析 → AST → 后缀 IR → Thompson ε-NFA 构造与匹配;
  • 支持并、连接、分组、有界重复 {n} 与无序组 <...>;
  • 带 mustMatchPos 位置约束的反向匹配,保证刚到达的事件必须参与;
  • 用字符集、长度 100、编译规模 3000、无序单元 5 四层约束规避灾难性回溯;
  • 核心 pass 都有单元测试。

事件序列正则引擎

为什么不用现成的规则引擎?因为需求要的是「事件之间的顺序关系」:先打开某个页面,再复制,再外发,才算一条风险序列;中间允许无关事件,但关键事件必须按顺序出现。现成引擎要么表达不了无序组,要么在长序列上回溯失控。自己实现一个小而可控的引擎,反而更容易测试和解释。

这段经历给我的最大提醒是:AI 工程不是只有模型。 数据怎么采、特征怎么造、规则怎么表达、失败怎么解释,往往比换一个更大的模型更能决定系统能不能上线。

工程取舍:为什么没有做 RAG 和微调

这套系统没有做 RAG,也没有做微调。不是这些技术不好,而是场景不匹配:

  • 客户环境要求私有化,数据不能出门;
  • 业务问题更多是「识别 + 路由 + 规则」,不是开放域问答;
  • 微调需要稳定的标注数据和持续评估,项目周期内不成立;
  • 先把模型服务、工具编排、数据闭环做稳,收益比追新更大。

同理,Triton 也不是唯一选择。如果只是低频调用,一个 Flask 服务就够了;但当你要批处理、要多模型仓库、要在 CPU/GPU 之间切换、要做 warmup 和观测,Triton 的价值才会显现。技术选型应该由交付约束驱动,而不是由技术名词驱动。

这也是为什么我先把模型服务做稳,再做 LLM 应用。模型服务是底座:它不稳定,上面的工具编排再优雅也没有意义。反过来,底座稳定之后,LLM 层可以快速试错,因为每次失败都能定位到是工具、提示词还是模型服务。对一人项目来说,顺序比速度重要:先做能复用的底座,再做能讲故事的场景。

还有一个取舍是观测。模型服务的日志不能只记「请求成功/失败」,还要记输入尺寸、批大小、推理耗时、CPU/GPU、模型版本。否则线上变慢时,你无法判断是流量、模型还是环境的问题。

常见失败模式

  • OCR 质量不稳定:图片模糊、倾斜、遮挡会显著影响识别;需要在前后处理里加入质量判断和降级策略。
  • CPU 吞吐不够:没有 GPU 的客户环境,批处理和超时策略要重新设计,不能照搬 GPU 参数。
  • 工具越权:模型选错工具或填错参数,必须在后端做权限校验和参数校验。
  • 数据漂移:业务规则变化后,特征分布会变;需要定期回看样本和误判。
  • 模型升级破坏契约:输出格式、类别、阈值变化要有版本和回滚。

这些失败模式有一个共同点:它们都不是模型能力问题,而是工程问题。模型服务层要把它们当成一等公民,提前设计检测、降级和回滚,而不是等上线后再补。

可复用清单

  1. 先把模型服务做成独立层,不要让业务代码直接加载模型。
  2. 前后处理也属于模型服务,不要散落在业务里。
  3. 私有化场景先设计降级路径:没有 GPU、没有外网、模型升级失败时怎么办。
  4. LLM 应用先定义工具边界和权限,再谈 prompt。
  5. 数据与算法层要能解释「为什么命中」,否则无法在客户环境里维护。
  6. 不要为了追新引入 RAG/微调;先确认场景真的需要。
  7. 吞吐数字要写清测试条件,不要把实验室数字当成生产承诺。

回到「一人交付」

这三层栈看起来是技术问题,其实也是交付问题:一个人要同时扮演模型工程师、后端工程师、数据工程师和运维,唯一的办法是把边界切清楚,让每一层都能独立验证。

这也是一人交付实验的核心:不是让一个人变成四个人,而是让一个人用流水线把四类工作组织起来。上一篇讲的是一个人如何交付一套多租户 SaaS,这一篇讲的是 AI 应用的三层栈;如果你还没看开篇,可以从我为什么开始「一人交付笔记」开始。

想继续聊模型服务、工具编排或事件序列引擎,欢迎通过 RSS、知乎或公众号找到我;也可以先看看关于我。

评论

评论由 Giscus 提供,内容保存在 GitHub Discussions,需要 GitHub 账号参与。本站不建立评论数据库,也不保存评论副本。

也可以直接前往 GitHub Discussions 查看或参与讨论。

© 2026 袁海粟(Yuan Haisu)

一人交付实验 · 中文 canonical

除非另有说明,本站内容采用 CC BY 4.0 授权

隐私说明