六池归池记账 + /cost 花费查询 #89
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feature/81-cost-accounting"
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?
Closes #81
六池(reply / proactive / reflection / multimodal / embedding / delegate)归池记账,按池 + 本地日累计,
/cost查今日/本月,经is_admin校验。AC 的一个前提不成立
AC 说「路径信息在调用点已知(
RuntimeContext及各调度入口已经区分得很清楚)」——RuntimeContext分不出 reply 与 proactive:反应式 / 即刻追问 / Callback / 环境信号四条路径都传"reactive",只有 Drive Tick 不同。各调度入口确实知道,但那个枚举不知道。所以归池键用 issue #79 为决策快照建的
TriggerPath(五条路径各有取值),经纯函数cost.pool_of()推导。额外收益:同一条触发的决策快照标签与成本池从此由同一个取值推导,不可能各说各话;新增一条触发路径却忘了归池会被测试当场抓到。四个 grill 决策
/diagnose两个探针分别归 reply 与 embedding(#80 明确留给本片的口子)。embed()进 embedding 池、所有兜底多模态旁路进 multimodal 池,与发生在哪条路径无关(ADR 原话「按能力分池」;这两项通常独立 provider、独立计价,混进路径池会让「该关掉哪个功能省钱」失去答案)。complete()里好几处在共享 helper 里(漂移守卫、子智能体),同一处代码被不同池的调用方复用;包装器把归池绑在「调用方拿到的那个 client」上,新增调用点天然被覆盖。两条架构逼出来的口径
LLMClient只有complete(),provider/model 由 host 私有持有),能挂定价的最细粒度就是池。一个池里混用多价位模型时数字是估算,文档如实这么说。issue #78 刻意留空的「累加时怎么对待
None」在这里定了:provider 没回传用量照样算一次调用、单独计入calls_without_usage,/cost把它显示出来 —— 静默丢弃会让金额偏低而且没有任何迹象。两轴 review 后修掉的(第二个 commit)
/cost原本零测试 —— AC「经is_admin校验」没有守卫。accumulate的「单个字段缺失」那支到不了(TokenUsage两字段都是int,两条边界都是全有或全无),而我那两条测试是靠违反声明类型构造输入才通过的。record_pool_usage原本是无锁 read-modify-write,而(pool, day)全局只有六个热行、每次 provider 调用都撞 —— 丢更新且无迹可循。改成数据库侧原子自增。PricingEntry裸元组 → 具名 frozen dataclass;两套存储的求和收敛进cost.merge;delegate_llm_client改必填;drive_tick 断言从<=收紧成精确等于{"proactive"}(那条路本就不做 embedding)。验证
1297 测试全绿。8 处变异逐条验过(主循环不记账 / 委托复用主池 / 反应式记错池 / 丢弃未回传用量 / embedding 不记账 / 未配定价显示 0 元 / 定价打错静默忽略 / 求和开区间),各自只挂对应测试。
其中两处第一次没杀掉测试:
delegate池零覆盖、embedding摘掉记账也没被抓到(断言写的是<=,"压根没记账"同样满足)。两条都已补强后重验。