AGC 官方 LLM Router 账号链路与流式联网输出 #242
Reference in New Issue
Block a user
Delete Branch "feat/agc-llm-router-official-chain"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
变更概述
将 AGC 客户端 LLM 使用方式收敛到官方 LLM Router 账号链路:客户端不再配置任意 Provider 凭据,由 api-server 通过 New API 管理员流程创建并管理 Router 账号与 API Key,AGC 正式模式统一走官方代理;同时补充生成过程中间态输出,默认启用流式输出与联网搜索,并在成功后执行幂等后置泥点扣费。
主要内容
llm_router_account表、读写/吊销 procedures、migration 与生成绑定。关联 Issue
当前状态
WIP / Draft:提交已推送,用于继续评审与联调;尚未声明可合并。
验证说明
Genarrative PR review for head
9a06945e44c6219beff7a01f592e4bbad7a220ac:请求修改。高风险:provisioning secret 被硬编码并随仓库发布,导致所有 Router 用户密码可被离线推导。
server-rs/crates/api-server/src/external_api_keys.rs:63将LLM_ROUTER_PROVISIONING_SECRET_V1固定写入源代码,而generate_router_account_password使用该 secret 和owner_user_id稳定派生密码。任何能读取仓库的人都能为任意已知 owner ID 计算密码,并登录对应router.genarrative.world账号,使用其无限额度的agc_auto_generateToken/API Key,造成跨用户账号接管和额度滥用。后续迁移密钥也无法撤销已暴露的派生密码。请移除源码中的固定 secret,改为从部署密钥管理/受保护 secret file 强制读取(缺失时拒绝 provisioning),并轮换已受影响账号的密码/Token;密码派生应包含真正的部署密钥且保留可迁移的 credential version。
Head
9a06945e44c6219beff7a01f592e4bbad7a220accontains a high-risk hard-coded Router provisioning secret; see the PR comment for details.Genarrative PR review for head c12d744d91142fcb8bedd8affe928ecd97f7fe56:已检查完整 diff,并运行 cargo check -p api-server 及 LLM Router 相关测试(10 passed)。此前硬编码 provisioning secret 问题在当前 head 已修复,未发现明确成立且需要阻塞合并的问题。
不要去修改ExternalApiKey表,这都不是为了你这个需求建的
Genarrative PR review for head
cbc73f111c8114b26c0816e959d77b5284d76a49:已检查 base4cd53688e9944a4a24c11833721968f128a45e2a到当前 head 的完整 diff(108 个文件),并运行cargo test -p api-server --bins(993 passed,6 ignored,0 failed)。未发现明确问题。
审查结论:REQUEST_CHANGES
@@ -124,0 +1039,4 @@format!("{LLM_ROUTER_RECONCILIATION_ERROR_PREFIX}active Router Key 密文缺失")})?;let api_key = decrypt_router_api_key(ciphertext, encryption_secret.as_str())?;llm_router_credential_cache().lock().await.insert(这里命中缓存后直接返回解密后的 Router key,但账户轮换、吊销和状态更新没有统一的缓存失效或版本校验。多实例下其他进程可能在 600 秒 TTL 内继续使用旧凭据,并存在旧请求在吊销后重新写回缓存的竞态。请引入共享版本/失效机制,确保不会返回 stale key。
@@ -0,0 +184,4 @@ctx.db.llm_router_account().account_key().delete(&account_key);当前 delete+insert 不是安全的并发 upsert。多实例并发更新时可能互相覆盖,读请求也可能观察到短暂缺口。请基于 owner+route 唯一约束使用原子 upsert,或增加版本/CAS 冲突检测并补并发测试。
服务器启动未检查相关配置
最近更新与请求处理说明
已根据最近评审意见和关联 Issue 完成一轮更新,当前分支已合并最新
master并推送。已完成的请求
ExternalApiKey表职责不变:llm_router_account。ExternalApiKey表。模型选择与白名单
gpt-6-astragpt-5.6-luna客户端 UI
启动链路修复
spacetimedb-standalone版本一致性校验,避免 CLI/standalone 版本错配导致 procedure 调用超时。验证
已完成:
git diff --check当前 PR 分支已包含以上修改,并已合并最新
master。LLM Router 累计额度结算逻辑
当前计费以 Router 用户账号的累计
used_quota为权威数据,不再根据单次请求的 token 数量估算成本,也不依赖响应中的 cost 字段。Router 当前配置为:
结算时不使用美元汇率。
数据库通过
llm_router_billing_checkpoint表,为每个 Router 账号记录已经实际扣费到的累计额度settled_quota。计算公式如下:
除法采用整数除法,不足 50000 的额度不会丢失,而是继续留在 Router 累计额度中,等待后续消费达到一个完整泥点后再结算。
例如:
如果用户当前只能消费 1 泥点,则本次只扣 1 点,
settled_quota只推进到 150000,剩余 73456 额度继续留待后续结算。对于没有 checkpoint 的账号,首次同步直接将当前
used_quota记录为初始基线,不追扣上线前的历史消费。首次基线可以不是 50000 的整数倍。模型调用前会先同步一次累计额度并检查余额;模型成功返回后再同步一次。失败、断流或进程退出导致后置同步未完成时,不会把已经成功的模型响应改成失败,尚未结算的消费会在下一次模型调用前补结算。
扣除泥点、写入
llm_router_consume钱包流水和推进settled_quota在同一个数据库事务中完成。任一步失败都会整体回滚,避免重复扣费、只扣余额但不推进游标,或者推进游标却没有实际扣费。重复快照和较旧快照不会使
settled_quota倒退;Router 账号 ID 与数据库记录不一致时拒绝结算,需要人工核对或迁移。