Administrator
发布于 2025-05-22 / 5954 阅读
28

企业级 AI 中台的建设思路

三个团队写了三套几乎一样的东西

今年三月做季度复盘时,我们数了一下公司的 AI 建设:客服知识库、智能质检、合同审核,三个项目分属三个团队,各自实现了一遍模型调用封装、限流、审计日志、向量库接入、prompt 管理。代码重复度我粗略估了一下有 40% 以上。

更现实的问题是:三个项目都踩了同样的坑(流式输出的 nginx 缓冲、token 统计不准、模型超时导致线程池打满),但因为是三个团队,每个坑都踩了一次,没人知道别人已经踩过。

于是公司决定建 AI 中台,我负责架构。这篇记录建设过程中的思考和取舍,包括我觉得不该做的部分。

先说清楚什么是"不该做"的中台

中台这个词在 2020 年前后被用烂了,很多中台项目最后变成了"一个没人愿意用的、文档不全的、拖慢业务的平台"。我在启动前跟团队明确了三条红线:

  • 不做强制接入。业务团队可以只用中台的一部分,也可以完全不用(如果他们能说明确理由)。强制接入的结果是阳奉阴违;
  • 不追求接口统一。三个场景的差异是真实的,硬套一层统一抽象只会让每个场景都别扭;
  • 不集中做业务 prompt。prompt 是业务逻辑,不是基础设施。中台提供管理能力,但内容是业务团队自己的。

这三条本质上是一件事:中台提供的是"能力"而不是"规范"。它的价值应该来自"用了能省事",而不是"规定必须用"。

中台的四层结构

最后定下来的中台分四层,每层解决不同的复用问题:

┌─────────────────────────────────────────────────┐
│  L4 治理层:权限穿透 / 审计 / 成本核算 / 内容安全 │
├─────────────────────────────────────────────────┤
│  L3 知识资产层:文档接入 / 切片 / 向量 / 版本管理 │
├─────────────────────────────────────────────────┤
│  L2 能力组件层:RAG 引擎 / Agent 编排 / 评测     │
├─────────────────────────────────────────────────┤
│  L1 基础设施层:模型网关 / 模型注册 / 配额管理   │
└─────────────────────────────────────────────────┘

四层的复用价值是不一样的。我按"业务团队的接入意愿"排了个序:L1 最容易推(没人想自己管 API Key 和限流),L4 次之(合规要求是硬约束),L2 和 L3 最难(业务觉得"我的场景特殊")。所以推进顺序也是 L1 → L4 → L2 → L3。

L1:模型管理与注册

这块是 AI 网关的升级版(我之前写过网关那篇),多了模型注册和灰度能力。核心是一个模型注册表:

public record ModelRegistration(
    String modelId,              // 业务侧使用的逻辑名,如 "main-chat"
    String provider,             // dashscope / openai / local-vllm
    String actualModel,          // qwen-plus / gpt-4o-mini
    ModelCapability capability,  // 支持工具调用? 支持视觉? 上下文长度?
    Pricing pricing,             // 输入/输出单价
    RateLimit limit,
    ModelStatus status           // ACTIVE / DEPRECATED / DISABLED
) {}

业务侧只看到 main-chat 这种逻辑名,实际背后的模型可以换,也可以做灰度。这一点非常重要——模型迭代太快了,如果业务代码里写死了 qwen-plus,换模型就要改代码发版。

灰度我们做得比较简单,按流量百分比 + 白名单:

routes:
  main-chat:
    - model: qwen-plus
      weight: 90
    - model: qwen-max          # 灰度中
      weight: 10
    whitelist:                  # 内部测试账号强制走新模型
      - u_1001
      - u_1002

灰度不只是换模型,还要能对比效果。我们接了评测系统,灰度期间自动对同一批请求用两个模型跑,对比用户点踩率和耗时。上个月的一次模型升级,就是靠这个发现新模型虽然各项离线指标更好,但用户点踩率反而涨了 0.8 个点,最后回滚了。

L2:RAG 引擎要不要统一

这是争议最大的一层。三个业务的 RAG 实现差异确实大:

维度客服知识库智能质检合同审核
文档类型FAQ、Markdown工单记录PDF 扫描件
切片策略按段落整条记录按条款 + 版面
检索方式向量 + BM25纯向量向量 + 关键词强匹配
是否需要 Rerank
更新频率每天几十次实时每周

硬要抽象成一个"统一 RAG 引擎",结果就是配置一大堆开关,谁都觉得难用。我们最后的做法是把 RAG 拆成可组合的算子,而不是一个黑盒引擎

public interface Retriever {
    List<Document> retrieve(RetrieveContext ctx);
}

// 业务自己组合
Retriever pipeline = RetrieverPipeline.builder()
        .add(new VectorRetriever(vectorStore, topK = 20))
        .add(new KeywordRetriever(esClient, topK = 20))
        .add(new Merger(MergeStrategy.RRF))        // 倒数排名融合
        .add(new Reranker(rerankModel, topK = 6))
        .add(new PermissionFilter(permissionService))
        .build();

这套东西上线后,客服团队接入用了两天,合同审核团队用了四天(他们的版面解析是额外的定制部分)。相比从零写,还是省了至少两周。

这里的关键是提供零件而不是成品。中台团队没能力理解每个业务的检索细节,那就别假装能,把能力拆到足够小的粒度让业务自己拼。

L3:知识资产沉淀是最难的一层

技术反而是这层最简单的部分,难的是组织问题。

我们一开始的想法是"建一个统一的知识库,所有文档都进来"。推行了两个月只收上来 30% 的文档,而且质量参差不齐。后来才想明白:知识资产的所有权在业务团队手里,中台不能抢,只能服务。

调整后的定位是:中台提供"文档接入 → 解析 → 切片 → 向量化 → 版本管理"的流水线,业务团队保留对内容的所有权和治理责任。具体能力:

  • 多格式解析:PDF(含扫描件的 OCR + 版面分析)、Word、Markdown、HTML、Excel。这块我们封装了内部服务,业务不用各自接;
  • 切片策略库:内置几种常见策略(固定长度 + 重叠、按标题层级、按语义、按条款),业务可自定义;
  • 版本管理:文档更新后自动重新切片,旧版本可回溯。这一点很重要——出问题时你需要知道"当时模型看到的是哪一版文档";
  • 质量反馈闭环:记录每个切片被召回的次数和用户的点踩,长期没人用的切片标记为"低价值",提示业务清理。

最后一条的效果出乎意料。上线三个月,系统标记出 23% 的文档从未被召回过,业务团队清理掉了一批过期内容,检索准确率反而提升了 6 个点(噪声少了)。

L4:权限穿透是 AI 特有的难题

这层是传统中台没有的,也是我觉得最有价值的一层。

传统系统的权限控制在接口层面:你能不能调这个接口、能不能看这条记录。AI 系统里多了一个难题:检索是按语义相似度做的,模型可能在回答里引用用户无权访问的文档内容

具体场景:客服知识库里有一份"VIP 客户特殊处理流程",普通客服无权查看。但他问"遇到情绪激动的客户怎么办"时,向量检索可能把那份文档召回,模型看了之后把里面的特殊流程写进了回答。接口权限完全没被突破,但信息泄露了。

我们的解法是把权限标签下推到切片级别,在检索阶段就过滤

-- 切片表结构
CREATE TABLE kb_chunk (
    id           BIGINT PRIMARY KEY,
    doc_id       BIGINT NOT NULL,
    content      TEXT NOT NULL,
    embedding    VECTOR(768),
    acl_tags     JSON NOT NULL,      -- 权限标签,如 ["dept:cs", "level:senior"]
    version      INT NOT NULL,
    INDEX idx_doc (doc_id)
);

检索时在向量库查询条件里带上 ACL 过滤:

Filter.Expression acl = permissionService.buildFilter(currentUser);
SearchRequest request = SearchRequest.builder()
        .query(question)
        .topK(20)
        .filterExpression(acl)      // 在向量检索阶段就过滤
        .build();

这里有个必须强调的点:过滤必须在检索阶段做,不能在模型生成之前做。如果在召回之后过滤,模型已经在 prompt 里看到了不该看的内容(虽然不会输出,但风险仍在)。有些团队是在 LLM 输出后再做敏感信息过滤,那是第二道防线,不能替代第一道。

审计方面我们做了完整的记录:谁在什么时候问了什么、召回了哪些切片、模型输出了什么、用户是否点踩。一条审计记录包含完整的 trace,事后可以完整还原。这套东西在第一次接受合规审查时帮了大忙。

成本核算:中台最容易做出价值的地方

统一之后最大的直接收益是成本可见和可控。我们把所有模型调用的成本按"业务线 / 功能 / 用户"三个维度拆开,每天出报表。

{
  "date": "2025-05-20",
  "total": 8412.36,
  "byBiz": {
    "customer-service": 3120.44,
    "quality-check": 1790.12,
    "contract-review": 2401.80,
    "other": 1100.00
  },
  "byModel": { "qwen-plus": 5210.9, "qwen-max": 2201.3, "text-embedding-v3": 1000.16 },
  "cacheHitRate": 0.41,
  "degradedRate": 0.008
}

数据一出,问题就暴露了:合同审核功能日均用量只有 800 次,却占了 28% 的成本,因为它每次都要处理几十页的合同。我们做了针对性优化(改成分页处理 + 缓存中间结果),成本降了 52%。

没有这个视角,这些钱花在哪儿根本没人知道。这是中台最容易量化的一块价值,建议优先做。

组织上的两个坑

技术上说得差不多了,说两个非技术问题,我觉得比技术更难。

坑一:中台团队不懂业务,容易做出没人用的东西。我们 L2 的第一版就是闭门造车做的,业务团队看了一眼说"这玩意儿限制太多"就拒绝接入。后来改成"派两个人到业务团队蹲一个月",重新设计后才推下去。中台团队必须有驻场机制。

坑二:成本归属不清导致扯皮。中台把成本拆细之后,业务团队开始质疑"为什么我们用了 3000 块,我觉得应该用不了这么多"。后来我们改成分账模型:中台只做计量,账单直接落到业务团队头上,中台的运维成本单独算。权责清楚了,扯皮就少了。

当前进展

中台从三月启动,到现在(五月中旬)的状态:

层级状态接入情况
L1 模型网关已完成3/3 业务 + 2 个新业务
L2 能力组件完成 70%3/3 部分接入
L3 知识资产完成 50%2/3 接入
L4 治理已完成3/3 强制接入

量化收益:新业务接入 AI 能力的平均时间从 6 周降到 2 周;重复代码减少约 35%;因为统一了限流和降级,AI 相关的线上故障从月均 2.3 次降到 0.7 次;模型成本通过统一缓存和分级,整体下降 31%。

小结

AI 中台的价值不在"统一",在"复用"和"治理"。我建议的优先级是:

  1. 先做成本计量和限流(L1 + 成本核算),投入小、见效快、没人反对;
  2. 再做权限和审计(L4),这是合规硬需求,业务不得不接;
  3. 能力组件慢慢来(L2),提供零件而不是成品,允许业务不接入;
  4. 知识资产最后做(L3),技术问题只占三成,主要精力会花在跟业务团队的协作上。

最后一句提醒:如果你们公司只有一两个 AI 应用,别急着建中台,先把应用做好。中台的收益跟接入方数量是超线性关系,两个应用建中台,大概率是亏的。

参考