news 2026/9/9 22:26:47

AI系统架构分层指南:Workflow与Inference的边界与协作

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AI系统架构分层指南:Workflow与Inference的边界与协作

我这两年跟不少团队聊过AI系统架构,发现一个很有意思的现象:刚把模型训练跑通的人,几乎都会觉得"分层"是多余的。逻辑很简单——一个脚本里把数据处理、模型调用、结果拼装全写完,调通就能上线,为什么要拆成好几个模块、好几层服务?但等到模型真的上了生产环境,流量一上来,需求一多,问题就接踵而至:一个节点挂了整条链路瘫痪、想替换其中的某个模型结果牵一发动全身、出了故障根本不知道是数据问题还是推理问题。这时候再回头看"为什么必须分层",答案已经不是理论问题,而是血泪教训了。

这个标题里的 Workflow 和 Inference,恰好是AI系统里最容易被混为一谈、却必须分开对待的两层。Workflow 管的是流程和状态,Inference 管的是模型计算本身。很多系统设计的乱象,都是从把这两件事揉在一起开始的。这篇文章我想从原理、实践、坑位三个角度,把分层的逻辑和这两层的边界讲清楚,给正在搭AI系统、尤其是准备把原型改造成生产级系统的同学一个可以直接参考的思路。

1. 为什么AI系统必须分层:从耦合到失控的必然

1.1 不分层会怎样:一个真实到不能再真实的例子

先说一个我见过很多次的场景。某个团队做内容审核系统,最初的MVP版脚本长这样:

def audit_text(text): # 1. 文本清洗 clean_text = remove_noise(text) # 2. 调用模型推理 result = model.predict(clean_text) # 3. 后处理拼接 if result["label"] == "reject": return {"action": "block", "reason": result["detail"]} return {"action": "pass", "reason": None}

单看这段代码,简洁、清晰、能跑。问题出在一个月后:产品说要加一个人工抽检环节,又过了两周,另一个模型上线,要求先过A模型再过B模型,再后来要支持批量异步处理,老板要求所有决策都要留痕可追溯。这个函数开始膨胀,从几十行变成几百行,从单进程变成多线程,从直接调用变成加缓存加队列加回调。每一步改动都像在雷区里走——因为你根本不知道"加一个环节"应该放在哪一层,所有逻辑挤在一起,互相依赖,改了数据处理就影响模型调用,改了模型调用就影响返回结构。

这就是不分层的本质问题:责任边界模糊。当数据处理、业务规则、模型推理、结果输出全部出现在同一个模块里,系统的可维护性和可扩展性会随着需求增长呈指数级恶化,而不是线性恶化。

1.2 分层的本质:把"做什么"和"怎么做"分开

分层不是一种格式化要求,而是一种控制复杂度的策略。每一层只回答一个问题:

  • 接入层:请求从哪来、参数怎么解析、鉴权怎么做。
  • Workflow层:这个任务要经过哪些步骤、步骤之间怎么流转、失败怎么处理。
  • Inference层:模型怎么加载、推理怎么执行、性能怎么优化。

这样拆开之后,每一层的修改都是局部的。想换模型?只动Inference层。想调整处理流程?只动Workflow层。想改API参数格式?只动接入层。改动的波及范围被限制住了,测试范围也自然缩小。

有人会反问:小系统也值得这样拆吗?我的判断是:如果这个系统活不过三个月,怎么简单怎么来;如果它要活过一年以上,分层是必须的。因为一年内需求一定会变,变的频率远超你的想象。做一个"方便修改"的架构,比做一个"当下最优"的架构更重要,而分层恰恰是方便修改的基础。

注意:分层不是越细越好。我看到有人把AI系统拆成十几个微服务,每个服务就干一件极小的事,结果光是服务间通信和部署就耗掉了大半精力。分层的核心是"按变化频率和职责边界划分",而不是"按功能切片"。

1.3 两个关键概念的定位:Workflow 和 Inference 各管什么

在AI系统的分层语境里,Workflow 和 Inference 是两个容易混淆的层级。

Workflow 解决的是流程编排问题:一个任务从进入到完成,需要经历哪些步骤?步骤是串行还是并行?哪些步骤需要人工确认?哪些步骤可以自动跳过?失败之后是重试还是降级?这些问题的答案构成了一个业务逻辑的拓扑结构。Workflow 不关心单个模型的计算细节,它只关心"流程什么时候走完、走到哪一步了、状态是什么"。

Inference 解决的是模型计算问题:给一段输入,怎么通过模型得到输出。它关注的是模型加载方式、显存管理、批量推理效率、推理延迟、并发处理能力等。Inference 层可以是一个独立的推理服务,也可以是多个模型服务集群。

两者的关系是:Workflow 编排任务流,Inference 执行任务流中的"计算节点"。把这两个概念分开,是AI系统架构的第一步。如果硬把它们混在一个模块里,就会出现我前面提到的那个脚本膨胀的局面——业务逻辑和计算逻辑互相纠缠,谁也无法独立演进。

2. Workflow层:AI系统的流程编排中枢

2.1 Workflow到底在管哪些事

Workflow层在AI系统里承担的角色,可以类比成一个项目里的项目经理。它不亲自写代码,但他知道整个项目要分几个阶段、每个阶段的负责人是谁、什么时候该做什么、出了问题找谁。

落到具体技术上,Workflow层要管的几件事:

任务建模:把一个业务请求拆解成有向无环图(DAG),节点是具体操作步骤,边是步骤之间的依赖关系。比如"用户上传一张图片",图可能是:图片解码 → 基础质量检测 → 主模型识别 → 后处理规则校验 → 输出结果。每一个节点都是可独立执行的单元。

状态管理:任务执行到哪一步了,每个中间态的结果是什么,任务处于等待中、运行中、成功还是失败。状态必须持久化,否则进程一重启,所有任务状态就丢了,这在生产环境是不可接受的。

调度执行:节点如何被触发。串行执行是最简单的模式;但如果做得好,节点之间可以并行。比如一个任务同时调用两个模型,它们互不依赖,Workflow层应该能并行调度这两个Inference请求,而不是一个一个排队。

失败处理与重试:某个节点失败了怎么办?是直接重试?还是跳过?还是把整个任务标记为失败并通知人工介入?这是Workflow层最重要的职责之一,也是跟Inference层最大的区别:Inference层一般只管"算成功或算失败",而Workflow层要管"失败之后的路怎么走"。

2.2 流程描述与代码实现:用状态机思维而不是回调地狱

很多人第一次写Workflow时,容易掉进回调地狱。用简单的Python代码示意一下错误的做法:

def process(request): result1 = step1(request) if result1.success: result2 = step2(result1.data) if result2.success: result3 = step3(result2.data) return result3 else: return fallback_2(result2) else: return fallback_1(result1)

这段代码的问题在于:业务流程被硬编码在函数调用栈里。每增加一个步骤,就要增加一层嵌套;每增加一个失败分支,就要增加一个if。两周之后,这段逻辑会复杂到没人敢改。

更好的思路是用数据驱动的方式描述流程。把流程定义成一张表或一个字典:

workflow = { "steps": [ {"name": "image_decode", "type": "processor"}, {"name": "quality_check", "type": "validator"}, {"name": "main_inference", "type": "inference", "model": "detect_v3"}, {"name": "rule_filter", "type": "rule", "threshold": 0.5}, {"name": "output_format", "type": "serializer"} ], "edges": [ {"from": "image_decode", "to": "quality_check"}, {"from": "quality_check", "to": "main_inference"}, {"from": "main_inference", "to": "rule_filter"}, {"from": "rule_filter", "to": "output_format"} ], "retry_policy": {"max_attempts": 3, "on_failure": "skip"} }

然后由一个通用的Workflow引擎去解释执行这张表。这样做的好处是:流程的变化不再需要修改代码,只需要改配置。产品的同学甚至可以在可视化编辑器里拖拽流程,而不用麻烦开发。

这里我补充一个小建议:如果团队规模不大、没有专门的基础设施团队,不建议一开始就上专门的Workflow引擎(比如Airflow、Temporal等),先写一个轻量级的流程解析器,用几十行代码维护一个有序步骤列表,再逐步增加重试、超时、状态持久化能力。等复杂度真的上来了,再迁移到成熟的框架也不迟。过早引入重框架,学习成本和运维成本会淹没业务开发时间。

2.3 轻量Workflow引擎的参考实现

我实际用过的一个轻量方案是这样的:

class WorkflowEngine: def __init__(self, definition, context): self.steps = definition["steps"] self.context = context self.history = [] def run(self): for step in self.steps: executor = get_executor(step["type"]) try: result = executor.execute(self.context, step) self.context[f"{step['name']}_result"] = result self.history.append({"step": step["name"], "status": "ok"}) except Exception as e: # 根据retry policy处理 if self._should_retry(step): self._retry(step) else: self.history.append({"step": step["name"], "status": "failed", "error": str(e)}) # 决定是跳过还是中止整个流程 return self.context

这个引擎很简单,但已经具备了流程执行、结果记录、失败感知的能力。关键在于,业务的增删只体现在definition里,而引擎本身几乎不用改。

2.4 Workflow层的扩展:条件分支与并行

当流程变复杂,单线串行就不够了。常见场景是:先做一次初筛,初筛通过走A路径,不通过走B路径。还有场景是需要同时调用两个独立的模型服务,最后汇总结果。

条件分支的实现可以在step定义里加一个condition字段:

{"name": "route", "type": "router", "condition": "lambda ctx: ctx['quality_check_result']['score'] > 0.8", "next": "high_quality_path"}

并行执行的实现更复杂一点,需要引入线程或异步任务。我的建议是:除非性能瓶颈真的在串行环节,否则第一版不要做并行。并行带来的状态同步和错误恢复复杂度,在早期阶段完全是负担。先把串行流程跑稳,再针对热点路径优化。

3. Inference层:决定AI系统性能的最后一公里

3.1 推理不只是"调用一下模型"

很多从训练转向推理的人有一个误区:模型在训练时能跑,推理时直接加载进来用不就行了?事实远没那么简单。推理是AI系统里最贴近硬件、最敏感于延迟的一层。

一个典型的Inference服务要做的事包括:

  • 模型加载与生命周期管理:模型文件从哪读、加载到GPU显存还是CPU内存、热更新时怎么平滑切换版本。
  • 请求预处理:文本要tokenize,图片要resize到特定尺寸,数值要做归一化。这些预处理虽然看起来"不重要",但占了推理延迟的很大一部分。
  • 批处理优化:单条请求推理效率往往很低,把多条请求拼成一个batch并行算,吞吐量能提升数倍。但batch要等到多大才触发?等待会不会增加延迟?这是经典的吞吐和延迟权衡。
  • 后处理:模型输出的裸张量要转换为业务可读的结构。

3.2 性能优化的核心维度:延迟、吞吐、资源占用

Inference层最核心的三个指标是延迟、吞吐和资源占用。它们之间互相制约,实际取舍取决于业务场景。

如果做的是实时风险拦截,拦截请求必须毫秒级返回,那就不能为了吞吐等太久的batch。如果做的是离线批量处理,比如批量给历史数据打标签,那延迟不敏感,可以把batch开大,把吞吐拉满。

资源占用方面,最重要的是显存管理。一个3B参数的模型FP16精度下大约占用6GB显存,如果并发多个副本,显存翻倍。我见过很多团队在推理层疯狂横向扩展——本质是因为他们没有优化推理路径,只能靠堆机器硬扛。实际上,常见的优化手段至少能把单机吞吐翻一番。

几个性价比很高的推理优化手段:

优化手段原理适用场景收益
动态批处理把并发请求攒成batch一起推理在线服务,有并发但能容忍几十毫秒等待吞吐提升2-5倍
量化(INT8/FP16)降低模型精度换取速度对精度损失不敏感的场景内存减半、速度提升2-3倍
模型缓存高频输入直接走缓存重复查询多、结果可复用延迟降到微秒级
自研算子融合把多个算子合并减少IO模型结构固定、需要极致性能提速30%-60%

3.3 推理服务的部署形态:独立服务还是嵌入进程

Inference层应该独立部署还是跟业务代码合在一起?我的答案是:只要资源允许,一定独立部署。

独立推理服务(例如用Triton、TorchServe,或者简单的FastAPI加模型加载)有几个明显优势:

  1. 独立扩缩容。业务流量大了扩Web服务,推理流量大了扩推理服务,互不干扰。
  2. 独立版本管理。模型升级不需要重新发布整个应用。
  3. 独立故障隔离。推理服务崩溃了,Workflow层可以感知并做降级处理,而不是整个系统一起挂。

不过独立部署也带来一个新问题——网络开销。原本同一个进程里函数调用只要微秒级,拆成两个服务后变成一次HTTP调用,可能要几毫秒到几十毫秒。这就要在"架构清晰"和"网络开销"之间找一个平衡。

我的经验是:同机房内网调用延迟通常在1-5ms以内,对大多数AI场景完全可接受。如果真有极低延迟要求(比如实时推荐要求P99小于10ms),可以用gRPC + 长连接 + 连接池来压缩开销,但不要因此否定独立部署的价值。

3.4 Inference层的关键接口设计

Inference服务对外暴露的接口应当尽量通用化,不要绑定具体业务。一个比较推荐的接口设计:

service Inference { rpc Predict(PredictRequest) returns (PredictResponse); } message PredictRequest { string model_name = 1; string model_version = 2; bytes payload = 3; // 原始输入数据 map<string, string> params = 4; // 推理参数 } message PredictResponse { bool success = 1; bytes result = 2; int64 latency_ms = 3; string error_message = 4; }

为什么payload用bytes而不是结构化字段?因为不同模型的输入差异巨大——有的是文本,有的是图片,有的是多模态拼接。把接口定义成通用字节流,Inference服务内部再做具体的反序列化,这样上层Workflow调用时就不用关心每个模型的具体输入格式。这也是分层思想在接口层面的一个体现。

4. Workflow vs Inference:这不是二选一,而是两件不同的事

4.1 关注点差异:业务正确性 vs 计算效率

Workflow层的核心关注点是业务正确性:流程是否按照预期走到终点、中间状态是否一致、失败路径是否符合预期。你不太需要关心某个具体模型是怎么算的,你关心的是整个任务的状态机是否正确。

Inference层的核心关注点是计算效率:如何压GPU利用率、如何降低P99延迟、如何让显存不爆炸。你不太需要关心上层业务为什么发起这个请求、结果用在哪里,你只需要把模型推理做好。

这两者的思维方式是完全不同的。Workflow层通常是CPU密集、IO密集、业务逻辑密集;Inference层是计算密集、显存敏感、模型生命周期敏感。放在同一个系统里、同一个进程里,很容易互相拖累——业务日志刷屏把推理日志淹没,业务频繁变动的代码导致推理服务频繁重启,推理的GPU显存波动又影响业务进程稳定性。分开是自然而然的。

4.2 失败语义差异:可重试 vs 不可盲目重试

这是一个很重要但常被忽略的差异。

Workflow层处理失败时可以重试:如果第2步失败了,可以重新执行第2步,甚至整个任务重新跑一遍。因为Workflow操作的往往是"业务逻辑",重试的代价是可控的。

Inference层则不同。推理失败通常意味着:模型输入非法、显存不足、模型文件损坏、推理服务过载。这些情况下盲目重试没有意义——重试还是会失败,甚至加重过载。正确的做法是:Inference服务对失败进行快速归类,返回明确错误码(是"输入不合法"还是"服务过载"还是"模型不可用"),Workflow层再根据错误码决定是跳过、重试、还是走降级策略。

我见过一个事故:某团队在Inference层做了无脑重试,推理服务已经过载了,重试请求还在不断涌入,最后服务彻底雪崩。加了熔断和退避之后才恢复。

注意:重试不是万能的,尤其在推理服务这种对资源敏感的节点上。重试要有最大次数、退避策略和熔断机制。

4.3 性能指标差异:耗时构成不同

Workflow层的耗时可大可小,取决于流程中有多少步骤、步骤之间是否串行、是否有等待人工处理的环节。有些任务可能几秒完成,有些要几分钟、几小时(比如大量数据的批量处理)。Workflow的性能指标是吞吐率和流程准确率。

Inference层的耗时通常是毫秒到秒级,单次推理的延迟是核心指标。它的性能指标是P50、P95、P99延迟,以及吞吐量(每秒请求数)、GPU利用率。

这两者在监控上也要分开。你不能用Workflow的流程耗时去衡量推理快不快,也不能用推理的单次延迟去推断流程整体需要多久。分开监控、分开告警、分开优化,是分层之后的自然要求。

4.4 演进方式差异:各自独立变化

分层的最大收益其实是"演进自由"。

Workflow层会随业务需求频繁变化——新增步骤、调整顺序、修改失败策略,这些变化可能一周发生好几次。而Inference层相对稳定——模型版本可能一两个月迭代一版,模型结构可能更久才变一次。

如果这两层耦合在一起,业务的频繁变化会逼着推理代码跟着改,模型服务的稳定性就得不到保障。分开之后,Workflow可以快速迭代,Inference可以稳定运行,彼此通过明确的接口协议通信,互不阻塞。这就是我一开始说的:"方便修改的架构"的价值所在。

5. 一个真实的系统演进:从单脚本到三层架构

5.1 原始状态的"能跑就行"

我帮一个团队做过类似的改造。他们的应用场景是智能客服工单分类:用户提交工单,系统自动判断类别并路由给对应的处理组。

最初的实现是这样的单函数:

def classify_ticket(ticket_text): # 清理 cleaned = clean(ticket_text) # 推理 label, score = model_v1.predict(cleaned) # 业务规则 if "退款" in ticket_text: label = "after_sales" if score < 0.5: label = "manual_review" return label

这个函数跑原型没问题,但生产环境的需求是:

  • 工单量大了以后,需要批量异步处理,不能每次同步等待模型返回。
  • 新模型上线要灰度,先让10%的流量走新模型,看效果再全量。
  • 分类结果需要审计日志,整个决策路径要可追溯。
  • 不同的工单类型要路由到不同的Workflow(有的走自动分类,有的先走模型再走人工复核)。

这些需求在原函数里硬塞,代码结构会越来越臃肿。于是我们做了重构。

5.2 重构后的分层架构

重构后,系统被清晰地分成了三层:

[API Gateway] → [Workflow Service] → [Inference Service] → [Model v1 / Model v2] (Python + State Machine) (FastAPI + Model Server)

接入层(API Gateway):接收工单请求,做鉴权、参数校验、限流,然后把标准化后的任务丢进消息队列。

Workflow层(核心业务逻辑):从队列取出任务,构造任务的状态机。初始状态是"pending",依次经过"text_cleaning"→"inference"→"rule_apply"→"route"→完成。每一步的状态和结果都写入数据库。失败重试也在这层做——如果推理调用超时,会重新发起调用,最多重试3次,仍失败则置为"manual_review"状态。

# workflow 定义 ticket_flow = { "name": "ticket_classify_flow", "steps": [ {"name": "validate", "type": "validator", "required": ["ticket_id", "text"]}, {"name": "clean", "type": "processor", "handler": "text_cleaner"}, {"name": "infer", "type": "inference_call", "model": "classify_v2", "timeout_ms": 2000}, {"name": "apply_rules", "type": "rule_engine", "rules": ["refund_check", "score_threshold"]}, {"name": "route", "type": "router", "targets": ["auto_classify", "manual_review", "after_sales"]} ] }

Inference层(模型服务):加载实际分类模型,提供/predict接口。接口内部做tokenize、推理、后处理。不同模型版本通过模型名称区分,新版本上线先在服务里部署,只让一部分流量通过Workflow层路由过来,实现灰度。

5.3 重构之后的效果

这个改造花了两周时间。带来的直接变化:

  1. 新增模型只需要在Inference层加一个部署,然后在Workflow层配一个节点,不用改任何流程代码。
  2. 模型灰度上线变成了配置项,不需要走代码发版流程。
  3. 出问题排查方便了——Workflow日志和Inference日志分开,直接看是哪个环节挂了。
  4. 人工复核只需要把任务状态改成"manual_review",其他层不用感知。

这个案例说明一个道理:不是"系统大了才需要分层",而是"想让它变大而不崩塌,就要先分层"。分层是给系统留出的扩展空间。

5.4 如果一开始就用成熟框架会不会更好

这个团队的同事当时问过:我们为什么不直接上Airflow或者Kubeflow?我的回答是:不是所有系统都需要那么重的框架。Airflow更适合周期性批处理任务调度,而这里需要的是在线请求处理加简单的状态流转。用一个轻量的状态机库就够了。

选型的逻辑应该是:根据任务特征选工具。在线长任务、需要状态持久化和重试的,可以用Temporal这类工作流引擎;周期性的ETL和批处理,用Airflow;只是一个简单的在线请求处理,自己写个几十行的状态机完全够用。工具是为场景服务的,不要反过来让场景迁就工具。

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

6.1 分层引入的过度设计

分层的反面是过度分层。我见过一个团队把一个简单的文本分类系统拆成了:API层、应用层、调度层、模型代理层、模型服务层、缓存层、消息队列层,一共七层。结果每处理一个请求要经过四五次网络跳转,延迟从10ms变成了60ms,部署一个功能要改四个仓库。

分层的粒度把握有一个判断标准:每一层是否有独立的演进需求。如果某一层永远不变,没必要单独拆出去。如果某一层的变化频率和相邻层完全一致,合并也许更好。分层是手段,不是目的。分层带来代码结构清晰,但代价是网络开销和管理复杂度。在性能和可维护性之间找一个自己能接受的平衡点,这本身就体现架构水平。

6.2 状态不一致问题:Workflow层和Inference层各自维护状态

Workflow层记录任务状态,Inference层记录模型调用状态。两者都可能出问题,最大的坑是状态不一致:Workflow认为任务成功了,但Inference的实际结果没有正确返回;或者Inference执行成功了,但Workflow因为网络超时错误地把它标记为失败。

解决这个问题的思路是:以Workflow层的持久化状态为最终依据,Inference层的成功不是任务的最终成功,写库成功才是。也就是说,Inference返回结果后,Workflow层要把结果持久化到自己的存储中,再更新任务状态。如果持久化失败,整个任务仍然按失败处理,可以重新发起执行。这本质上是分布式系统里经典的"两阶段提交"思想的简化版,虽然不完美,但在大多数场景下可以有效避免状态错乱。

6.3 性能瓶颈定位经验

系统上线之后,性能问题是最常见的。我常用的排查路径是:先看Workflow层的耗时分布,找到耗时最高的步骤;再看这个步骤是调用了推理服务还是做了大量CPU计算;如果是前者,用链路追踪看Inference层的推理时间。

一个实例:某次排查发现工单分类任务P95延迟从200ms涨到了800ms,外部看是变慢了很多,内部看Workflow层的日志,发现"infer"步骤耗时700ms。再往下查,Inference服务的P95推理时间其实只有120ms,但网络传输和排队花了500多ms——原因是推理服务只有一个副本,请求排队严重。解决办法是扩容推理服务到三个副本,并把Workflow层的并发调用做成连接复用,P95立刻降回300ms以内。

这个案例的教训是:别只看一层的数据,瓶颈可能在链路任何位置。分层之后,每层的日志和监控都要有,才能快速定位问题在哪一层。

6.4 多版本模型的灰度与回滚

模型上线最怕出问题。分层架构下,灰度其实是很好做的:Inference服务里同时部署v1和v2两个版本,Workflow层在调用时读配置中心,决定当前流量走v1还是v2。想灰度10%,就在配置中心把v2的权重设为10%。

如果v2效果不好,回滚只需要把配置改回去,不用重新发版,不用重启服务。这种能力在单脚本架构里几乎不可能实现——你只能整体回滚到上一版代码,那会影响所有其他逻辑。

我的一个建议是:从第一天起就为每个推理请求记录model_version字段,作为审计日志的一部分。这样出了问题,你可以回溯任何一个结果是由哪个版本的模型产生的,这对原因定位和争议处理很重要。这个字段成本极低,价值极高。

6.5 重试风暴与熔断

最后分享一个我踩过的坑。某次大促,流量突然暴涨,推理服务开始响应变慢,有个别请求超时。Workflow层发现超时后自动重试,结果重试的请求把推理服务打得更慢,形成恶性循环。当时最要命的是,重试逻辑和正常逻辑完全一样,重试请求同样需要排队,进一步加剧了过载。

后来我们加了三个机制:

  1. 最大重试次数限制,默认2次,最多5次。
  2. 指数退避,第一次重试等200ms,第二次等400ms,第三次等800ms。
  3. 熔断器,如果推理服务的错误率在10秒内超过50%,直接打开熔断,不再发起新的推理调用,而是让Workflow层进入降级路径(比如先转人工)。

这套机制上线之后,即使推理服务彻底不可用,整个系统的入口也不会被打爆。分层架构给了我们一个很好的熔断位置:在Workflow层熔断,而不是在业务入口熔断。这也是分层的价值之一——你有了一个可以集中管控故障策略的位置。


回到"为什么必须分层"这个话题。我的体会是:分层不是某种教科书的教条,而是在AI系统从小变大、从原型到生产的过程中,最靠谱的一条路。它的核心价值不是让代码好看,而是让每一次业务变化都能被限制在局部,让每一次故障都能被快速定位,让模型和业务可以各自独立演进。如果你正在搭一个AI系统,我建议你先别急着写代码,先用一张纸把Workflow流程和Inference服务边界画出来。画清楚的那一刻,很多架构问题其实已经解决了一半。

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

从零搭建LeNet风格CNN:PyTorch实现MNIST图像分类

前两篇我们把卷积的计算方式、卷积核的含义、特征图是怎么来的这些基础概念过了一遍&#xff0c;可能你已经有点感觉了&#xff1a;卷积本身不复杂&#xff0c;复杂的是怎么组织成一整套能解决实际问题的网络。这一篇就干一件事——把前面那些零散概念组装起来&#xff0c;搭出…

作者头像 李华
网站建设 2026/9/9 22:22:33

Seelen-UI:如何把 Windows 桌面改造成 5 分钟上手的高效率工具

Seelen-UI&#xff1a;如何把 Windows 桌面改造成 5 分钟上手的高效率工具 【免费下载链接】Seelen-UI The Fully Customizable Desktop Environment for Windows 10/11. 项目地址: https://gitcode.com/GitHub_Trending/se/Seelen-UI Seelen-UI 是一套跑在 Windows 10/…

作者头像 李华
网站建设 2026/9/9 22:21:29

DeepSeek接入QQ机器人:多段回复逻辑实现拟人化聊天体验

把 DeepSeek 接进 QQ 群&#xff0c;很多人的第一版做法都差不多&#xff1a;写个脚本&#xff0c;群里发一句话&#xff0c;脚本调一次 API&#xff0c;再把返回结果发回群里。跑通不难&#xff0c;但用两天你就会发现&#xff0c;这个机器人非常“AI”——回复动辄几百字&…

作者头像 李华
网站建设 2026/9/9 22:21:20

栈与队列深度解析:从底层实现到工程实战

1. 先说结论&#xff1a;为什么栈和队列永远值得再聊一遍栈和队列这两个词&#xff0c;刷过题的人闭着眼都能写出几个操作&#xff0c;背八股的人张口就是"后进先出、先进先出"。但真到项目落地的时候&#xff0c;能把它们用得漂亮的人其实没那么多。我看了一圈最近的…

作者头像 李华