理解 Downcity City
Federation、Bureau 与 City
分清全局服务、产品身份、产品后端和 Agent 终端的边界。
在 @downcity/city 里,服务端和客户端是两个不同的类,名字也不同。最容易踩的坑,就是把它们都当成“City”。
- 全局服务与信任根是
Federation - 稳定产品身份与授权域是
Bureau - Agent 终端客户端是
City
这一页只解决一件事:让你看代码时立刻知道自己在写哪一端。
一句话区分
Federation:共享后端运行时、账户事实源和信任根,维护 Bureau 注册表与 Organization 关系。Bureau:稳定的产品身份和授权域;每个机器凭证绑定一个bureau_id。City:Agent 终端客户端,连接预配置的 Bureau 产品域,不在 Federation 注册。FederationAdmin:由 Admin Session 授权的旧版管理员客户端,不属于任何 Bureau。
换句话说:Federation 信任 Bureau;City 只是连接某个 Bureau 产品域的终端。
服务端:Federation
服务端永远从 new Federation({ database }) 开始。它负责把数据库、service、模型目录和统一路由组装成一个能跑的后端:
import { Federation, Service } from "@downcity/federation";
const base = new Federation({ database });
base.use(new Service({ id: "translate" }));
await base.health();
serve({ fetch: (request) => base.fetch(request), port: 3001 });Federation 负责:
- 注册
Service、官方服务和AIService - 校验
user_token和管理员会话 Token - 暴露统一的
/v1/*路由 - 协调 runtime env、hooks、usage 和数据库
文档里出现的“Federation”指的就是这个
Federation实例,不是客户端City。
控制面与终端
可信控制面和 Agent 终端使用两个独立客户端:
import { City, FederationAdmin } from "@downcity/federation/legacy";
// 旧版管理员客户端:请求 Federation 管理 Bureau、env,并签发 User Token
const admin = new FederationAdmin({
base_url: "https://base.example.com",
credential: administrator_session_token,
});
// 产品前端:只拿 user_token (which contains bureau_id),调用 service
const city = new City({
federation_url: "https://base.example.com",
user_token,
});FederationAdmin:运行在可信后端,请求 Federation 管理 Bureau 身份与 env,并签发user_token。City:运行在 Agent 终端,只持有user_token(其中包含bureau_id),调用 AI 与 Service action。
客户端永远拿不到 provider key,User City 也永远拿不到管理员凭证或会话 Token。
一张图记住边界
Agent 终端 City连接预配置的 Bureau 产品域,不拥有服务端身份。
new City({ federation_url })服务端 Federation共享后端运行时,承载模型目录、service 路由、token 校验、usage 和 hooks。
new Federation({ database })和 CLI 的对应关系
CLI 也是按这条边界拆的:
downfed:管理Federation、Bureau 身份、机器凭证、服务资源和 env。downcity:本机 Agent 宿主与管理入口。
接下来读什么
- 想看完整调用链,读 架构总览
- 想分清两类密钥,读 token 模型
- 想直接上手部署,读 创建 Federation