ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

WorkBuddy企业版套件化:一个Agent底座统管五个产品的架构设计与实践

WorkBuddy企业版套件化:一个Agent底座统管五个产品的架构设计与实践

1. 从五个产品到一套底座:WorkBuddy 企业版套件化的核心命题

第一次看到“WorkBuddy 企业版套件化:一个 Agent 底座统管五个产品”这个标题,我脑子里蹦出来的第一个画面不是架构图,而是一个很具体的运维场景:公司内部同时跑着五套 AI 工具,每套都有自己的账号体系、自己的模型配置、自己的日志格式,运维同事每天在五个后台之间来回切换,改一个超时参数要登录五次。这种“烟囱式”的 AI 工具堆叠,在 2024 年到 2025 年之间几乎成了中大型团队的标配痛点。

WorkBuddy 企业版做的事情,本质上就是把这五套东西的“地基”抽出来,做成一个统一的 Agent 底座,让上层五个产品变成这个底座上的“租户”或者“插件”。这个思路听起来简单,但真正落地的时候,涉及的问题远比“抽个公共库”复杂得多:五个产品的 Agent 能力边界不一样,有的偏代码生成,有的偏工作流编排,有的偏数据分析,怎么用一个底座同时满足?底座的抽象层次定在哪里,才不会既管不住上层、又把自己撑爆?

我先把结论放在前面:套件化的关键不在于“统一”,而在于“分层”。一个 Agent 底座要统管五个产品,它必须把“所有产品都一样的部分”和“每个产品都不一样”的部分切得足够干净。切错了,底座要么变成一坨谁都不敢改的巨石,要么变成一层薄得没有价值的壳。

1.1 为什么是“一个底座”而不是“一套微服务”

很多人第一反应是:五个产品,那就拆成五个微服务,共享一个网关不就行了?这个方案在传统业务系统里没问题,但在 Agent 场景下会踩坑。原因是 Agent 的核心资源不是 CPU 和内存,而是模型调用配额、上下文窗口、工具(Skill)注册表、会话状态。这四样东西如果每个产品各管各的,会出现三个致命问题。

第一,配额打架。五个产品各自持有模型 API Key,各自限流,结果就是 A 产品把配额跑满了,B 产品直接 429。企业版必须有一个统一的配额池和调度器,才能把有限的 token 预算按优先级分配。

第二,Skill 重复注册。热词里反复出现skill、skill插件、agent skill,说明 Skill 机制是这个体系的核心。如果五个产品各自维护一套 Skill 注册表,同一个“查询数据库”的 Skill 会被写五遍,改一次要改五处。底座必须提供统一的 Skill Registry。

第三,会话状态割裂。用户在 A 产品里跟 Agent 聊到一半,切到 B 产品,上下文全丢了。企业级体验要求跨产品的会话连续性,这只能靠底座统一管理 session。

所以“一个底座”不是架构洁癖,而是被 Agent 的资源特性逼出来的必然选择。微服务那套“每个服务自治”的理念,在共享稀缺模型资源的前提下会直接失效。

1.2 五个产品到底共享了什么

我把这套套件化拆解下来,底座真正需要统管的东西其实就五类,我习惯叫它“五件套”:

共享层具体内容不共享会怎样
模型接入层多模型路由、配额、重试、降级配额打架、成本失控
Skill 注册中心Skill 定义、版本、权限、发现Skill 重复开发、版本混乱
会话与上下文Session、Memory、上下文压缩跨产品体验断裂
身份与权限租户、用户、产品级 RBAC权限模型五套、审计困难
可观测性日志、Trace、Token 计量出问题无法定位、成本无法归因

这五类里,模型接入层和 Skill 注册中心是底座的技术核心,身份和可观测性是工程保障,会话与上下文是最容易被低估、但用户感知最强的一层。后面我会逐个展开。

1.3 套件化之后,五个产品变成了什么

这是理解整个架构的关键。套件化不是把五个产品合并成一个,而是让它们从“独立应用”降级为“底座上的配置 + 少量专属逻辑”。用一句话概括:产品 = 底座能力 + 产品专属的 Prompt 策略 + 产品专属的 Skill 组合 + 产品专属的 UI。

举个具体例子。假设五个产品里有一个偏代码的(类似 CodeBuddy 的定位),一个偏通用办公的(WorkBuddy 本体),一个偏数据分析的,一个偏科研文献的,一个偏工作流自动化的。套件化之后:

  • 代码产品 = 底座 + 代码类 Skill 集 + 代码专用系统提示词 + IDE 插件 UI
  • 办公产品 = 底座 + 文档类 Skill 集 + 办公提示词 + 对话式 UI
  • 数据产品 = 底座 + SQL/图表 Skill 集 + 分析提示词 + 看板 UI

你会发现,产品之间的差异被压缩到了“Skill 组合 + 提示词 + UI”这三样。底座承担了 80% 的复杂度,产品只负责 20% 的差异化。这就是套件化的价值:新增一个产品,从“重写一个 Agent 系统”变成“配置一套 Skill 和提示词”。

但这里有个陷阱我必须提醒:不是所有产品都适合塞进同一个底座。如果两个产品的 Agent 交互范式差异过大(比如一个是纯对话,一个是纯批处理流水线),强行统一底座会导致抽象层被迫做得极其宽泛,最后谁都用得不顺手。判断标准是:它们的“模型调用 + Skill 调用 + 会话管理”这三件事的形态是否一致。一致,就能共享底座;不一致,就该独立。

2. Agent 底座的分层设计与 Skill 机制拆解

底座怎么分层,直接决定了它能撑多久。我见过太多“统一底座”项目死在第二层——抽象做浅了,上层产品各自绕过底座直连模型;抽象做深了,底座变成一个改不动的黑盒。WorkBuddy 这套体系能统管五个产品,说明它的分层是经过实战检验的。我按自己的理解把它拆成四层,并重点讲 Skill 机制,因为热词里skill出现的频率高得离谱,这一定是整个体系的重心。

2.1 四层架构:接入层、编排层、能力层、资源层

接入层负责协议适配。企业里五个产品可能用不同的调用方式:有的走 HTTP OpenAPI,有的走 WebSocket 长连接,有的走 SDK。接入层要把这些协议统一成内部的 Agent 请求格式。热词里OpenAPI反复出现,说明对外暴露标准 OpenAPI 是这套体系的重要能力——第三方系统可以通过 OpenAPI 直接调用底座能力,而不需要理解内部协议。

编排层是 Agent 的大脑,负责决定“这一步该调模型还是调 Skill”“上下文怎么组装”“多轮怎么推进”。这一层是产品差异化的主要战场,但底座要提供的是编排原语,而不是替产品做编排决策。比如底座提供“条件分支”“并行调用”“重试”这些原语,产品用它们拼出自己的流程。

能力层就是 Skill 层。所有可被 Agent 调用的能力——查数据库、调 API、读文件、画图、跑代码——都注册在这里。这一层是底座最核心的资产。

资源层是模型、向量库、存储、计算资源的抽象。这一层要屏蔽具体供应商差异,让上层不关心用的是哪个模型。

这四层里,编排层和能力层的边界最容易画错。我的经验是:编排层只负责“怎么调”,能力层只负责“调什么”。一旦编排层开始关心具体 Skill 的业务逻辑,或者能力层开始关心调用顺序,边界就破了。

2.2 Skill 机制:底座的能力单元

热词里有一堆关于 Skill 的搜索:skill插件、agent skill、workbuddy skill、skill编码193、skill编码247、测试skill、豆包skill、codex skill、codex论文skill、打斗动作提示词skill、gemini反重力skill。这些词说明 Skill 已经形成了一个生态,不同来源、不同用途的 Skill 都在往这个体系里接。

Skill 的本质是给 Agent 用的函数。它和普通函数调用的区别在于三点:第一,Skill 必须能被模型“理解”,所以它需要自然语言描述(description);第二,Skill 的输入输出要能被模型消费,所以通常是结构化的 JSON Schema;第三,Skill 要有权限和配额,因为 Agent 可能被诱导调用危险操作。

一个 Skill 的标准定义大概长这样:

{ "name": "query_sales_data", "description": "查询指定时间范围内的销售数据,返回汇总结果", "version": "1.2.0", "parameters": { "type": "object", "properties": { "start_date": {"type": "string", "description": "开始日期 YYYY-MM-DD"}, "end_date": {"type": "string", "description": "结束日期 YYYY-MM-DD"}, "region": {"type": "string", "description": "区域,可选"} }, "required": ["start_date", "end_date"] }, "permissions": ["sales:read"], "timeout_ms": 10000 }

这里有几个设计要点值得展开。description 的写法直接决定模型能不能正确调用。我踩过的坑是:description 写得太技术化,模型理解不了业务语义;写得太模糊,模型会乱调。好的 description 是“业务语义 + 边界条件”,比如“查询销售数据,仅支持最近两年,超过范围会报错”。

version 字段是必须的。Skill 会迭代,如果没版本管理,某个产品依赖旧行为、另一个产品依赖新行为,就会互相打架。底座要支持多版本共存,产品按需锁定版本。

permissions 是安全底线。热词里有agent安全,这不是空话。Agent 被 prompt injection 攻击时,最危险的就是它调用了不该调的 Skill。底座必须在 Skill 调用前做权限校验,而不是信任模型的判断。

2.3 Skill 的注册、发现与隔离

五个产品共享一个 Skill 注册中心,但不是所有 Skill 对所有产品可见。这里需要三层隔离:

  • 全局 Skill:所有产品都能用,比如“获取当前时间”“通用搜索”。
  • 产品级 Skill:只有特定产品能用,比如代码产品的“执行单元测试”。
  • 租户级 Skill:企业客户自己上传的私有 Skill,只对该租户可见。

隔离靠的是 Skill 的 namespace 和权限标签。产品在初始化时声明自己需要哪些 namespace,底座只返回可见的 Skill 列表。这样既保证了共享,又避免了污染。

Skill 的发现机制有两种:静态注册和动态发现。静态注册是启动时加载配置文件,适合稳定的核心 Skill;动态发现是运行时从注册中心拉取,适合频繁更新的 Skill。企业版通常两者结合:核心 Skill 静态加载保证启动速度,扩展 Skill 动态拉取保证灵活性。

注意:动态发现 Skill 时一定要做签名校验。我见过有团队为了图方便,允许从任意 URL 加载 Skill 定义,结果被注入了一个“读取环境变量”的恶意 Skill。Skill 的来源必须可信,加载前必须验签。

2.4 上下文管理:最容易被低估的一层

会话与上下文管理,是套件化里最不显眼但用户感知最强的一层。五个产品共享会话,意味着用户在代码产品里说“帮我看看昨天那个 bug”,切到办公产品时 Agent 还能记得“昨天那个 bug”指的是什么。这需要底座维护一个跨产品的 Memory 层。

Memory 的设计有两个流派:全量保留和摘要压缩。全量保留简单,但 token 成本爆炸;摘要压缩省钱,但会丢信息。我的实践是分层 Memory:最近 N 轮对话全量保留,更早的对话做摘要,关键实体(人名、项目名、文件路径)单独抽取成结构化记忆。这样既控制了 token,又保住了关键信息。

上下文组装的时候还有个细节:不同产品的系统提示词要注入到同一个上下文里。如果处理不好,会出现“代码产品的提示词污染了办公产品的对话”。解决办法是给每段上下文打上来源标签,组装时按产品过滤。

3. 从零搭建:底座核心模块的实操过程

前面讲的是设计思路,这一节我讲具体怎么落地。我会按“模型接入层 → Skill 注册中心 → 会话管理 → OpenAPI 暴露”的顺序,给出可参考的实现方案。这些方案是我基于常见企业级 Agent 平台的实践总结,具体参数需要根据你的模型供应商和团队规模调整。

3.1 模型接入层:多模型路由与配额池

模型接入层的核心是统一接口 + 智能路由 + 配额管理。统一接口让上层不关心具体模型;智能路由根据任务类型、成本、延迟选择模型;配额管理防止某个产品把预算跑光。

先看统一接口的设计。我建议定义一个内部模型调用协议,所有模型都适配到这个协议:

class ModelRequest: def __init__(self, messages, model_hint=None, max_tokens=4096, temperature=0.7, tools=None, tenant_id=None, product_id=None): self.messages = messages self.model_hint = model_hint # 上层可以给建议,但路由层有最终决定权 self.max_tokens = max_tokens self.temperature = temperature self.tools = tools # Skill 列表,转成模型的 function calling 格式 self.tenant_id = tenant_id self.product_id = product_id

路由逻辑我通常分三级:任务类型匹配 → 成本约束 → 可用性降级。任务类型匹配是看这个请求是代码生成、长文本理解还是简单问答,不同任务用不同模型;成本约束是看当前租户的预算余额,余额低就切便宜模型;可用性降级是主模型超时或报错时自动切备用模型。

配额池的实现要点是按租户 + 产品双维度计量。只按租户计量,无法知道哪个产品在烧钱;只按产品计量,无法做租户级预算。两个维度都要有,才能既做成本归因又做预算控制。

# 配额检查的简化逻辑 def check_quota(tenant_id, product_id, estimated_tokens): tenant_quota = get_tenant_quota(tenant_id) product_quota = get_product_quota(tenant_id, product_id) if tenant_quota.remaining < estimated_tokens: raise QuotaExceeded("租户配额不足") if product_quota.remaining < estimated_tokens: raise QuotaExceeded("产品配额不足") return True

实操心得:配额检查一定要在调用模型之前做,而且要预留 buffer。我见过有团队在调用后才扣减配额,结果并发请求同时通过了检查,实际消耗远超预算。正确做法是调用前预扣、调用后按实际用量结算。

3.2 Skill 注册中心:从定义到执行

Skill 注册中心要解决四个问题:定义、存储、发现、执行。定义用 JSON Schema,存储用数据库或配置中心,发现靠 namespace 过滤,执行靠沙箱隔离。

执行环节是最需要小心的。Skill 本质上是执行任意代码或调用外部系统,如果不隔离,一个恶意 Skill 就能拿到整个底座的权限。我的方案是进程级隔离 + 能力白名单:每个 Skill 在独立进程或容器里跑,只能访问白名单里的资源(比如指定的数据库连接、指定的 API 域名)。

# Skill 执行的沙箱包装 class SkillExecutor: def execute(self, skill_name, params, context): skill = self.registry.get(skill_name, context.product_id) if not self.check_permission(skill, context.user): raise PermissionDenied() # 在隔离环境中执行 with self.sandbox(skill.timeout_ms, skill.resource_limits): result = skill.handler(params) # 记录审计日志 self.audit_log(skill_name, params, context) return result

审计日志这块我要多说一句。热词里有agent安全,企业级 Agent 的安全审计不是可选项。每次 Skill 调用都要记录:谁调的、调了什么、参数是什么、结果是什么、耗时多少。出安全事件时,这份日志是唯一的追溯依据。

3.3 会话管理:跨产品的上下文连续性

会话管理的核心数据结构是 Session。一个 Session 包含:会话 ID、租户 ID、参与的产品列表、消息历史、结构化记忆、创建和更新时间。

跨产品连续性的实现关键是Session 与 Product 解耦。Session 属于用户,不属于产品。用户在产品 A 创建的 Session,切到产品 B 时可以通过 Session ID 继续。产品 B 拿到 Session 后,按自己的系统提示词重新组装上下文。

class Session: def __init__(self, session_id, tenant_id, user_id): self.session_id = session_id self.tenant_id = tenant_id self.user_id = user_id self.messages = [] # 全量消息 self.summary = "" # 历史摘要 self.entities = {} # 结构化记忆 self.products = set() # 参与过的产品 def add_message(self, role, content, product_id): self.messages.append({ "role": role, "content": content, "product_id": product_id, "ts": now() }) # 超过阈值触发摘要 if len(self.messages) > 50: self.compress()

上下文压缩的触发阈值需要调。太小,频繁压缩丢信息;太大,token 成本高。我的经验值是保留最近 20 到 30 轮全量,更早的做摘要。摘要用便宜的小模型做,成本可控。

3.4 OpenAPI 暴露:让第三方接入底座

热词里OpenAPI出现多次,说明对外暴露标准接口是刚需。底座的能力要通过 OpenAPI 暴露给第三方系统,让它们能像调用普通 API 一样调用 Agent。

OpenAPI 设计有三个要点。第一,认证用标准方案,比如 OAuth2 或 API Key,不要自创。第二,接口要幂等,Agent 调用可能重试,非幂等接口会出问题。第三,流式响应要支持,Agent 的输出是逐字生成的,用 SSE 或 WebSocket 推送体验最好。

# OpenAPI 片段示例 paths: /v1/agent/chat: post: summary: 发起一次 Agent 对话 security: - ApiKeyAuth: [] requestBody: content: application/json: schema: type: object properties: session_id: {type: string} message: {type: string} product_id: {type: string} stream: {type: boolean, default: true} responses: '200': description: 流式返回 Agent 响应

注意:OpenAPI 暴露的接口一定要做速率限制和配额绑定。第三方系统可能写出死循环调用,没有限流会把底座打垮。每个 API Key 绑定一个配额池,超限直接拒绝。

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

套件化落地过程中,问题往往不在设计阶段,而在联调和运维阶段。我把踩过的坑整理成速查表,覆盖模型、Skill、会话、性能四类问题。

4.1 模型接入类问题

问题现象可能原因排查方法解决
某产品突然大量 429配额被其他产品抢占查配额池实时用量按产品设独立配额上限
响应变慢但无报错路由到了慢模型查路由日志的模型选择调整路由权重或加超时
成本突然飙升上下文没压缩查平均 token 数调低压缩阈值
模型返回格式错乱提示词与模型不匹配对比不同模型的输出按模型定制提示词模板

这里重点说 429 问题。多产品共享配额池,最容易出现的就是“一个产品把配额跑满,其他产品饿死”。解决办法不是简单加配额,而是分级配额:给每个产品设保底配额(保证基本可用)和弹性配额(空闲时可用)。保底配额之和不超过总配额,弹性配额按优先级分配。

4.2 Skill 调用类问题

Skill 相关的问题最隐蔽,因为模型可能“静默失败”——它调用了 Skill 但没告诉用户。常见问题包括:

  • Skill 不被调用:description 写得太差,模型没理解。解决是把 description 改成业务语言,并加 few-shot 示例。
  • Skill 被错误调用:多个 Skill 的 description 太相似,模型分不清。解决是明确每个 Skill 的边界,在 description 里写“仅用于 X,不用于 Y”。
  • Skill 超时:外部依赖慢。解决是设合理超时,超时后返回降级结果而不是报错。
  • Skill 权限报错:产品没声明对应 namespace。解决是检查产品的 Skill 声明配置。

实操心得:调试 Skill 调用时,一定要打开模型的 function calling 日志。很多时候模型“看起来没调 Skill”,其实是调了但参数错了。日志里能看到模型生成的原始参数,这是定位问题的关键。

4.3 会话与上下文类问题

跨产品会话最容易出的问题是上下文污染。产品 A 的系统提示词被带到了产品 B 的对话里,导致 Agent 行为异常。根因是上下文组装时没做来源过滤。

解决办法是给每条消息打 product_id 标签,组装时只保留当前产品的系统提示词,历史消息按需保留。另外,结构化记忆要做租户隔离,不同租户的实体不能混。

还有一个坑是会话过期策略。会话不能永久保留,否则存储爆炸。我的方案是:活跃会话保留 30 天,过期会话归档到冷存储,只保留摘要。用户主动删除的会话立即清除。

4.4 性能与稳定性问题

套件化之后,底座成了单点。底座挂了,五个产品全挂。所以高可用是硬要求。

关键措施有三个。第一,无状态化:底座的服务实例不保存状态,状态全放 Redis 或数据库,这样实例可以随意扩缩容。第二,熔断降级:某个模型供应商挂了,自动切备用;某个 Skill 超时率高,自动熔断。第三,限流保护:入口做全局限流,防止突发流量打垮底座。

# 熔断器简化实现 class CircuitBreaker: def __init__(self, failure_threshold=5, recovery_time=60): self.failures = 0 self.threshold = failure_threshold self.recovery_time = recovery_time self.opened_at = None def call(self, func, *args, **kwargs): if self.is_open(): raise CircuitOpen("熔断中,请稍后重试") try: result = func(*args, **kwargs) self.failures = 0 return result except Exception as e: self.failures += 1 if self.failures >= self.threshold: self.opened_at = now() raise

注意:熔断阈值不要设得太敏感。Agent 调用本身就有一定失败率(模型超时、Skill 抖动),阈值太低会导致频繁熔断,反而影响可用性。我的经验是连续 5 次失败才熔断,恢复时间 60 秒起步。

5. 套件化的边界与扩展:什么时候该拆,什么时候该合

写到这儿,我想聊聊套件化的边界问题。因为“一个底座统管五个产品”听起来很美好,但不是所有团队都适合。我见过强行套件化最后失败的案例,也见过该合没合、维护成本爆炸的案例。判断标准其实就一条:产品之间的共享收益是否大于耦合成本。

5.1 适合套件化的三个信号

信号一:产品间共享大量 Skill。如果五个产品里有 60% 以上的 Skill 是重叠的,套件化收益巨大。反之,如果每个产品的 Skill 都是独有的,共享底座的价值就只剩模型接入和会话管理,收益有限。

信号二:有统一的租户和权限体系。企业客户买的是“一套 WorkBuddy”,而不是“五个独立工具”。如果产品各自有独立的账号体系,客户要管理五套权限,体验很差。套件化能统一身份,这是企业版的刚需。

信号三:团队有能力维护底座。底座是一个长期投入的基础设施,需要专门的团队维护。如果团队规模小,五个产品都靠同一批人开发,套件化反而增加协调成本。这种情况下,先做“共享库”而不是“共享底座”更务实。

5.2 底座不该管的三件事

套件化最容易犯的错是底座管太多。有三件事底座不该管:

第一,产品的业务逻辑。底座提供 Skill 和编排原语,但“这个产品的 Agent 该怎么回复用户”是产品的事。底座一旦开始关心业务语义,就会变成改不动的巨石。

第二,产品的 UI 和交互。底座只提供 API,不提供界面。界面是产品差异化的核心,底座不该碰。

第三,产品的专属数据。底座管会话和记忆,但产品自己的业务数据(比如代码产品的代码库索引)应该产品自己管。底座只提供存储抽象,不提供具体存储。

5.3 扩展新产品的标准流程

套件化的最大价值是降低新增产品的成本。我总结了一个标准流程,新增一个产品大概分四步:

  1. 定义产品画像:这个产品面向什么场景、用什么模型、需要哪些 Skill。
  2. 配置 Skill 组合:从 Skill 注册中心挑选需要的 Skill,声明 namespace。
  3. 编写系统提示词:这是产品差异化的核心,决定 Agent 的行为风格。
  4. 接入 OpenAPI:用底座的 OpenAPI 实现产品后端,前端自己开发。

这四步里,系统提示词是最花时间的。我见过有团队以为套件化之后新产品一周就能上线,结果提示词调了两周。提示词不是写一次就完,要反复测试、迭代。建议给每个产品建一个提示词测试集,每次改动都跑一遍回归。

5.4 一个真实的扩展案例

假设要新增一个“科研文献助手”产品(热词里有workbuddy 科研)。按套件化流程:

  • 产品画像:面向科研人员,需要文献检索、摘要生成、引用格式化能力。
  • Skill 组合:复用底座的“通用搜索”Skill,新增“文献库检索”“引用格式化”两个专属 Skill。
  • 系统提示词:强调学术严谨性,要求引用必须标注来源,不确定的内容要明确说明。
  • OpenAPI 接入:用底座的 chat 接口,前端做一个文献管理界面。

整个过程,底座代码零改动,只新增了两个 Skill 和一套提示词。这就是套件化的威力——新增产品从“造轮子”变成“拼积木”。

6. 我在这套体系里踩过的坑和总结的经验

最后这部分,我想抛开架构,聊点更实在的东西。套件化这件事,技术方案可以抄,但经验抄不来。我把自己踩过的坑列出来,希望能帮你少走弯路。

第一个坑:过早抽象。项目刚开始就想着“要统管五个产品”,把底座抽象做得极其宽泛,结果每个产品接入时都要写一堆适配代码。正确做法是先让两个产品跑通,再抽象。两个产品的共性才是真共性,五个产品的共性往往是想象出来的。

第二个坑:Skill 没有版本管理。早期觉得 Skill 改了就改了,结果一个产品依赖旧行为,另一个依赖新行为,互相打架。后来加了版本字段,产品锁定版本,问题才解决。Skill 一旦发布,就不能改行为,只能发新版本。

第三个坑:忽略可观测性。上线初期没做 Trace,出问题只能靠猜。后来补了全链路 Trace,才发现很多问题出在上下文组装而不是模型本身。可观测性不是上线后补的,是设计时就要留的。

第四个坑:配额没做预扣。并发请求同时通过配额检查,实际消耗超预算。改成预扣 + 结算后解决。这个坑很隐蔽,因为单请求测试永远发现不了。

第五个坑:会话没做租户隔离。测试时用同一个租户,没发现问题。上线后多租户,发现结构化记忆串了。所有涉及数据的地方,都要先问一句“租户隔离了吗”。

这套体系跑下来,我最大的体会是:套件化的难点不在技术,而在边界。技术方案网上都能搜到,但“什么该共享、什么该独立”这个判断,只能靠对业务的深刻理解。底座做得太厚,产品失去灵活性;做得太薄,共享价值不足。这个平衡点,每个团队都不一样,只能自己摸索。

如果让我给正在考虑套件化的团队一个建议,那就是:先从共享模型接入和 Skill 注册中心开始,这两块收益最明确、风险最低。会话管理和身份体系可以第二步做。至于产品专属逻辑,永远不要往底座里塞。守住这条线,底座就能活得久。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进