Bridge
推理引擎的 HTTP 门面:加载了什么、谁贡献了多少、以及补全——除此之外什么都没有。
bridge 是结算网关在推理这件事上唯一对话的对象。它在 p4 的术语里是一个 OUTER:它在模型的各个 stage 上装配会话、向头部 stage 提交请求、汇集 token 流,并汇报每个节点贡献了什么。它不拥有放置、不做调度,除了一份"什么已加载"的目录之外不持有任何状态——它刻意做得很小,因为凡是它不决定的事情就不会走样。
契约
四条路由,一个令牌
| 路由 | 它回答什么 |
|---|---|
/api/controllers | 哪些模型已加载,以及每个 stage 的状态 |
/api/runtime | 运营者钱包,以及它背后的机器 |
/api/contributions | 每节点的 rows、units、请求数、吞吐 |
/c/<model>/v1/chat/completions | 推理 |
除 /api/health 之外的每条路由都需要一个共享服务令牌,经 X-Kvasir-Service-Token 发送。那个令牌是横在开放互联网与"免费驱动这个环"之间的唯一屏障,这也是为什么 bridge 绑定 loopback、经隧道访问,而不对外发布。
p4 留给它的
引擎不肯做的两件事
- 对话模板。p4 把不透明的提示词原样交给 stage server,自己不套用任何轮次格式。由 bridge 渲染模型的格式——从 GGUF 中读出,并在目录里以
prompt_format命名。跳过它,instruct 模型就会续写你的文本而不是回答它,永远不发出自己的轮次结束 token,每次都跑到 token 上限。 - 思考块。推理模型开口先思考。bridge 把那部分作为
reasoning_content返回,与content分开,并通过在提示词中把思考块闭合来遵守enable_thinking: false——否则一次漫长的思考就能吃光整个预算,把一份已经付过钱的空答案交给调用方。
放置不归它管
它为什么回 409
要求 bridge 去服务一个模型,得到的是 409。哪些层落在哪张 GPU 上、在哪个 load generation 下,来自运营者写好并加载的放置方案;这里没有可执行的远程重载。网关的环看门狗学会这一点之后就不再问,而不是反复重试一件不可能成功的事。
贡献计数器活在内存里。bridge 重启会丢掉网关尚未轮询到的部分——它每 30 秒轮询一次——而当计数器倒退时,网关会重设基线而不是重复计数。bridge 不知道其所有者的节点会被静默跳过,因此一个未设置的运营者钱包读起来就是"这些机器什么都没赚到"。