运行约 12 分钟

多租户与请求上下文

租户信息从哪来、跟着请求走到哪:部署记录带 user_id / space_id,每个请求带统一信封和请求上下文,审计自动带上是谁。

依据 agent-runtime develop@0a47a523(2026-11-12)核实

租户是谁

企业里同一套平台通常要服务多个团队、多个用户。Runtime 用两个字段标识租户:

字段含义
user_id哪个用户
space_id哪个空间(团队、项目、业务线)

部署时把它们写进部署记录,查询时按它们过滤:

await manager.deploy_agent(DeployAgentParams(
    name="promise_agent", version="1.0.0",
    user_id="u-001", space_id="sales",
))
mine = await manager.list_deployments(ListDeploymentsParams(space_id="sales"))
说明

示意代码,参数名取自 DeployAgentParams 和 list_deployments;本站没有运行它。

源码list_deploymentsagent-runtime/management/openjiuwen_runtime/management/manager.py:223@0a47a523
注意

README 提到"租户中间件"在 server/ 目录,本站核实的基线版本里没有这个目录。能核实的隔离是:部署记录带租户字段、查询按租户过滤。谁能用哪个 space_id,需要上层的身份和权限来保证(见第 5 关"管理面与身份中心")。

每个请求都装在一个信封里

部署起来的智能体应用,基于 service/ 的服务框架。框架只认一种入口消息:Envelope。

Envelope
 ├─ type        路由键,同时是 REST 路径段
 ├─ metadata    请求元数据
 │   ├─ request_id   必填:幂等键 + 链路追踪键
 │   ├─ user_id、session_id、chat_id、bot_id、channel
 │   ├─ trace_id、instance_id、timestamp
 │   └─ extra        可扩展字段,不破坏结构
 └─ rawdata     业务数据
源码Metadataagent-runtime/service/openjiuwen_runtime/service/envelope.py:22@0a47a523

字段名和其他消息格式对齐,所以从别的协议转换过来很轻。request_id 必填这件事很关键:重复投递的请求可以靠它去重,一次请求的日志、审计、链路都能靠它串起来。

两级上下文

服务框架把资源分成两级:

层级类型职责
进程级SystemContext持有数据库、Redis、缓存、锁、审计等共享资源,负责启停和就绪检查
请求级RequestContext绑定这次请求的信封、元数据、截止时间、日志字段、鉴权主体和清理回调
源码服务上下文设计agent-runtime/service/openjiuwen_runtime/service/context/DESIGN.md@0a47a523

业务代码只跟 RequestContext 打交道:ctx.db_* 读写数据库、ctx.kv / ctx.idempotency 用 Redis、ctx.lock(...) 拿分布式锁、ctx.audit(...) 写审计。日志自动带上 request_id 和 trace_id。

审计自动知道"是谁"

await ctx.audit("create_order", resource="order", details={"order_id": "SO-001"})
说明

示意代码,方法签名取自 RequestContext.audit;本站没有运行它。

这条审计事件会自动带上:actor(优先取鉴权主体,没有就用 user_id)、request_id、trace_id、session_id、消息类型、实例 ID。业务代码不用自己拼这些字段,也就不容易漏。

源码RequestContext.auditagent-runtime/service/openjiuwen_runtime/service/context/request_context.py:471@0a47a523

小结

  • 租户用 user_id + space_id 标识,部署记录带上、查询按它过滤。
  • 每个请求都是一个 Envelope,request_id 必填,是幂等和追踪的依据。
  • 业务代码通过 RequestContext 使用数据库、缓存、锁和审计,身份和链路字段由框架自动带上。
  • 租户能访问什么,最终要靠身份与权限来约束,不能只靠调用方自报的字段。

源码出处

链接指向固定提交,仓库后续更新不影响这里的行号。

过关测验

  1. 1. Envelope 的 Metadata 里,哪个字段是必填的?

  2. 2. 业务代码调用 ctx.audit("create_order") 时,审计记录里的 actor 从哪来?

  3. 3. list_deployments 传了 space_id,返回什么?

通关条件

  • ○ 测验全部答对