网关与转向引擎
AiHummer 的核心是 单一网关服务. 它同时也是 控制平面 (管理 API、设置、频道连接、市场) 和 启动发动机 (生成答案的函数调用循环)。因此,一个典型的部署只是那一个服务加上 PostgreSQL——你不需要运行单独的工作者层。
一项服务,两个角色
网关监听于 公共的 港口 :8780 默认,由……控制 AIHUMMER_GATEWAY_ADDR ——此端口承载所有外部流量(API、配对、WS/SSE、入站 Webhook、应用/口袋代理以及健康检查)。管理员 Web 界面运行在 分开的,私人的 监听器(默认) :8781, AIHUMMER_WEBUI_ADDR),在根路径提供 / 并且理想情况下绑定到仅内部使用的接口。无论哪种情况,该过程始终是相同的单一服务。
# gateway.env — the only required setting
AIHUMMER_DATABASE_URL=postgres://user:pass@localhost:5432/aihummer?sslmode=disable
# Admin Web UI after start at http://localhost:8781/ (the private Web UI listener)
这 唯一的硬依赖是 PostgreSQLPostgres 是代理、设置、对话、记忆、交付状态和审计的唯一真实来源。其他所有内容——可选服务、向量存储和模型提供者——仅在你配置时才会接入。
[!NOTE] 没有数据库时网关启动于 仅健康模式: 它回答
GET /healthz所以协调器或负载均衡器可以看到该进程是 活着,但它不会派上用场。GET /readyz检查 PostgreSQL 和 返回503当数据库无法访问时。
启动时会发生什么
在启动时,网关会按照严格的顺序执行几个步骤:
- 打开数据库连接池,
- 在 Postgres 顾问锁下应用任何待处理的迁移,
- 解析配置(数据库值 → 环境变量 → 内置值) 默认),以及
- 连接服务——路由器、编排器、通道、工具、内存, 传送——进入一个运行中的网关。
重要的结果是 大多数功能需要通过设置键选择启用未配置的功能只是未激活,这可以保持默认运行时的小巧和可预测性。您可以通过网页管理界面或使用…来开启这些功能。 AIHUMMER_* 变量,网关将在下一次启动时(或对于支持的旋钮,在热启动时)解析它们。
转向引擎
当消息到达网关时,转换引擎接管。它运行一个 函数调用循环:模型接收到系统提示和对话内容后,可能会调用工具(或生成子代理),每个工具的结果都会被反馈回去,循环继续,直到模型生成最终答案。然后,该答案会被交给交付层。
inbound message
└─▶ turn engine
├─ assemble layered system prompt
├─ call model ──▶ tool calls / sub-agents ──▶ tool results ─┐
│ ▲ │
│ └────────────────────────────────────────────────-─┘
└─ final answer ─▶ reliable delivery ─▶ originating channel
因为循环在每个输入来自哪里的方面是确定性的,答案是从对话历史和工具结果中解析出来的——从不通过将不受信任的文本注入指令来生成。这个特性也是下面提示分层既安全又高效的原因。
分层的、缓存友好的系统提示
系统提示不是一个整体。它是分层组装的,顺序是刻意安排的,以便 稳定的部分先出现,不稳定的部分最后出现. 这很重要,因为模型提供商会按前缀缓存提示:只要提示的开头逐字节完全相同,缓存的前缀就会被重复使用,只有尾部会被重新处理。
| 区域 | 图层(顺序) | 变化… |
|---|---|---|
| 稳定前缀 (可缓存) | 基础身份 + 工具/记忆指南 → 租户 → 人物角色 → 技能 | 很少 — 每个代理/租户 |
| 不稳定的尾部 (最后附上) | 入职状态 → 内存补充 → 上线日期 | 每一次转弯 |
稳定前缀包含定义代理是谁的一切内容:内置身份以及工具和记忆工作方式的指导,然后是租户层、代理的人设以及呈现的技能块。在同一代理的两个连续回合之间,这些内容都不会改变,因此它形成了一个可重用的缓存前缀。
易失尾已附加 之后 稳定的前缀正是如此,它永远不会使缓存失效:入职状态、为这个特定对话准备的内存以及当前日期都会随着每一轮变化,但因为它们位于末尾,所以只消耗它们所增加的部分。
[!TIP] 这种排序是实时数据(例如今天的日期)可以存在的原因 每次转弯时无需支付费用来重新编码整个身份。保持 在稳定层(个性、技能)中为每个代理定制内容,并让 发动机拥有易变的尾部。