Integration Patterns
Agent 与 Federation AIService
理解 Agent、Downcity、City 和 AIService 在模型管理上的职责边界,以及集成时应该怎么用
Agent 与 Federation AIService
如果你在正常的 Downcity 项目里使用 Agent,模型通常不应该由 Agent 项目自己持有。
这时要把职责拆成四层:
Federation AIService:拥有模型目录、provider、API key、模型路由Downcity:连接 City,读取模型目录,校验和解析modelIdAgent 项目:只声明execution.modelId@downcity/agentsession:真正执行 prompt
最重要的结论
在 Downcity 集成模式里:
- CLI 全局数据库保存的是
modelId - 不是 provider 配置
- 不是 API key
- 也不是本地模型实例
也就是说,下面这种心智模型才是对的:
global downcity.db: agent.execution.modelId
-> Downcity 读取并校验
-> Federation AIService 解析出目标模型
-> Agent runtime 使用这个模型执行为什么要这样分层
这样做的好处是:
- 多个 Agent 可以复用同一套模型目录
- provider key 不进入项目目录
- provider 切换、模型增删、默认模型策略都可以在 City 侧统一管理
这也是 Downcity 当前真实实现的边界:
- Downcity 不拥有模型池
- Downcity 不解析 provider / apiKey / baseURL
- 模型目录唯一来源是 Federation AIService
Agent 项目里实际写什么
项目里真正的绑定点是:
{
"execution": {
"type": "api",
"modelId": "quality"
}
}也就是:
execution.type = "api"execution.modelId = "<some-id>"
City 侧如何提供模型
City 侧通常会这样注册模型:
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
import { Federation, AIService, Provider, type OpenAICompatibleClientConfig } from "@downcity/city";
const base = new Federation({ db });
class DeepSeekProvider extends Provider {
constructor() {
super({
id: "deepseek",
baseURL: "https://api.deepseek.com/v1",
envKey: "DEEPSEEK_API_KEY",
passthroughModel: "deepseek-chat",
});
}
protected createClient({ apiKey, baseURL }: OpenAICompatibleClientConfig) {
return createOpenAICompatible({ apiKey, baseURL, name: "deepseek" });
}
}
const deepseek = new DeepSeekProvider();
const ai = new AIService();
ai.use(
deepseek.model({
id: "quality",
name: "DeepSeek Quality",
}),
);
base.use(ai);注册后,Federation AIService 就拥有了:
- 模型目录
- SDK 通路
- OpenAI 兼容通路
Downcity 如何读取和校验模型
Downcity 启动 Agent 项目前,会去 Federation AIService 读取模型目录并校验 modelId。
当前真实实现大致是:
- 读取 City 连接配置
- 通过 User City 调
city.ai.listModels() - 检查
execution.modelId是否存在 - 用它构造 Agent 可执行的模型绑定
这也是为什么:
execution.modelId写错时,问题通常会在启动或首次执行阶段暴露- 而不是拖到对话跑了很多轮才发现
什么时候该用 session.set({ model })
应该用
适用于纯 SDK 嵌入模式:
- 你自己在 Node 应用里
new Agent(...) - 你自己持有模型实例
- 你不是通过 Downcity 去绑定 City 模型
不应该作为默认路径
在正常的 Downcity Agent 项目里,不应该把 session.set({ model }) 当默认用法。
这时应优先:
- 在 Federation AIService 注册模型
- 在项目里写
execution.modelId
一个完整的最短链路
1. City 注册模型
const ai = new AIService();
ai.use(provider.model({ id: "quality", name: "Quality" }));
base.use(ai);2. Downcity 连接 City
downcity federation use
downcity federation status3. Agent 项目绑定 modelId
{
"execution": {
"type": "api",
"modelId": "quality"
}
}4. 启动或重启 Agent
downcity agent restart .如果要远程访问 Agent
要区分两层:
- 模型能力:来自 Federation AIService
- session 能力:由本地 Agent 对外暴露
所以 RemoteAgent 连到的是:
- 本地 Agent 暴露出的 session API
不是直接去连 Federation AIService 模型本身。
常见误区
误区 1:Agent 项目里应该保存 provider 配置
不是。项目里只保存 modelId。
误区 2:RemoteAgent 可以远程传 session.set({ model })
不是。远程 session 当前不支持客户端直接传本地模型实例。
误区 3:Downcity 自己维护模型目录
不是。Downcity 只读取和校验 Federation AIService 暴露出的模型目录。