Commit Graph
8 Commits
Author SHA1 Message Date
tzt e41471c39c feat(proxy): T-P6 语义缓存(L1/L2 倒排+singleflight+SSE 回放,M2 核心)
- semcache.py:SemanticCache——L1 精确(LRU max_entries=30万)+ L2 字符 2/3-gram
  倒排索引(启动自 sqlite q_norm 重建)+ 加权 Jaccard(3-gram 权 2)+
  共享 gram>=3 候选门限 + 阈值 0.92 + TTL 滑动过期 + L2 命中 5 次晋升 L1
  (别名键写回表);SingleFlight(dict[hash->Future] 上限 256/60s 超时降级);
  synth_sse_chunks 命中回放(分块 delta+finish+[DONE] 合法 SSE)
- ledger:semcache_rows/put_semcache/promote_semcache/purge_expired
- 测试 +10:gram/精确/语义上下阈值/TTL 假时钟/LRU/重建/晋升/singleflight/SSE 合法性,
  全量 422 passed
- 待接线:routes 缓存分支(T-P7 顺带接入,M2 完整闭环在压测前完成)
2026-09-05 15:39:48 +08:00
tzt a636b989e5 feat(sense): T-G7 审计+前端(live 分流接线 + tier 指标卡 + Settings 灰度区块)
- proxy/routes:sense.mode=live 时转发前调 Grader 分流,档位 -> 池条目
  (tier_pool_hint 映射),响应头 X-Campus-Tier 透出(可解释性);
  T1 决策按 review.sample_rate 抽样入 ReviewQueue(sense_t1 标签,
  人工核"判 T1 实为更高档");分级故障不影响代理可用性(D-G4)
- /api/metrics:sense 段(enabled/mode/观察数/已标签/档位分布/shadow 一致率)
- 前端:MetricsView「语义分级」卡片(观察/标签进度/一致率/晋升门提示);
  SettingsView「Sense 灰度控制」区块(总开关 + collect/shadow/live 切换 +
  标签进度),npm run build 产物更新
- 全量 410 passed
2026-09-05 15:06:27 +08:00
tzt 3250e4e099 feat(proxy): T-P5 规范化+桶(canonical_hash 五规则/整形顺序/doc_version 失效)
- normalizer.py:resolve_bucket(X-Campus-Bucket 头 > 映射 > default,D-P2);
  normalize_messages(role\u0001content\u0002 串接,剔易变字段与时间戳行,
  多模态 content 取 text);is_cacheable(system 外 >1 条 = 多轮不缓存,D-P5);
  canonical_hash(bucket|doc_version|sha256(norm)——模板/资料不参与哈希,
  资料更新 = 版本+1 旧键失效);shape([canonical_system(无才注入)] ->
  [课程资料前缀(文件读取,不入git)] -> [原 messages],易变顶层字段剔除)
- 测试 +8:同义同哈希/易变剔除/模板不入哈希/doc_version 失效/多轮判定/
  整形顺序+资料注入/桶解析回落/序列化形态,全量 370 passed
2026-09-05 09:40:05 +08:00
tzt 5b04276fc8 feat(proxy): T-P4 路由端到端(M1:计费代理跑通)
- routes.py 主时序:auth(热缓存) -> 限流/并发槽 -> 413 -> 池条目解析 ->
  try_hold 预扣(字符/3 + min(max_tokens,4096) 宁可高估)-> 上游流式 tee
  -> usage 归一 -> compute -> settle(actual 回补) -> 流水;异常路径:
  UpstreamError 全额 void / UpstreamAborted 按已收 usage 结算 status=aborted
- install_error_handlers:ProxyError 家族 -> §5.3 错误码
  (401/402/403/413/429/502,401 带 WWW-Authenticate)
- 管理面:students/topup/keys 签发/keys-revoke(X-Admin-Key 或 loopback)
- SSE 同构:chunk 补齐 object/created/id/model(OpenAI SDK 兼容形状),
  usage chunk 按客户端要求过滤
- 修复:补回 T-P4 重写时丢失的 /proxy/v1/models
- 测试 +8(非流式全程含 2550/1491 黄金账目/流式/402/401/413/502 void/
  httpx 手写 OpenAI SDK 合规断言含 chunk 形状+usage 过滤+[DONE]),全量 362 passed
2026-09-05 09:35:12 +08:00
tzt a0afeec5cb feat(proxy): T-P3 计价(峰谷窗口/毫元整数/差异化售价/黄金用例)
- pricing.py:is_offpeak(含跨午夜窗口、非法回落、±1min 边界语义);
  compute 全整数毫元——上游成本叠加 offpeak_factor(空闲半价),
  学生售价按差异化折扣(in 0.5 / out 0.8,不叠加热闲系数,全天一口价),
  margin = charged - cost 恒等式
- 未配置价格模型三值零(调用方可拦截);配置换算加载期唯一
- 测试 +9(窗口边界/跨午夜/回落/黄金手算 #1#2/恒等式 10 组扫/零用量/
  稳定性/未知模型/换算不漂移),全量 354 passed
2026-09-05 09:18:51 +08:00
tzt f24f016e95 feat(proxy): T-P2 上游客户端(流式派发/usage 注入过滤/三家归一化/首 token 前 failover)
- upstream.py:httpx.AsyncClient 模块级单例(keepalive,limits=100,
  超时 connect10/read120/write10/pool30);stream() 始终注入
  stream_options.include_usage(计量不依赖客户端)+ filter_usage_chunk
  (客户端未要求 usage 时剥除该 chunk);D-P4 首 token 前 failover 链、
  流中失败抛 UpstreamAborted(不可切换);ttfb_ms 记录
- normalize_usage 三家归一:deepseek prompt_cache_hit_tokens /
  openai prompt_tokens_details.cached_tokens / anthropic cache_read_input_tokens
  (命中数>总数时钳制)
- model_pool:+provider(枚举校验 deepseek/openai/anthropic)+in_hit_price
  (缺省 = price_in×1/30,D-P3)
- 测试 +6:透传+sink/failover/流中 aborted/全挂 502/三家归一/过滤,全量 345 passed
2026-09-05 09:14:31 +08:00
tzt a9f3405970 feat(proxy): T-P1 鉴权+账本(原子预扣/热路径缓存/令牌桶/管理鉴权原语)
- ledger.py:students/keys CRUD + 日限额 check_and_count(跨日重置,注入时钟)+
  流水分页;计费两阶段拆分至 billing.py(BillingMixin,评审聚焦):
  try_hold 锁内读现状->日上限判定->余额原子防线->holding 流水(request_id 幂等)、
  settle 按真实值回补(预扣-实际)差额、void 全额退款(上游失败)
- auth.py:issue_key(sk-campus- 前缀,明文只返回一次,库存 sha256+前缀)、
  authenticate 校验链(形态/注销/停用/日额/rpm,热路径 LRU TTL30s D-P10)、
  RateLimiter(令牌桶 rpm + per-key 并发信号量,D-P9 单进程)、
  verify_admin(hmac.compare_digest;未配置仅 loopback)
- 测试 +17:签发/错key/注销/停用/403/rpm 429/日额 429/并发槽/admin 策略 +
  预扣-结算-回补一致/双向差额/余额不足/日上限/幂等/跨日重置/void/并发10路不超扣
- 全量 339 passed
2026-09-05 09:05:59 +08:00
tzt b109576707 feat(proxy): T-P0 代理层骨架(包结构/DDL/门控挂载/单进程校验)
- gateway/proxy/ 十文件:config(ProxyConfig:元->毫元加载期换算 D-P1、差异化售价、
  桶/峰谷/限流/semcache 配置)/ errors(8 类 HTTP 语义异常)/ ledger(四表两索引 DDL,
  WAL,ReviewQueue 连接纪律)/ auth·pricing·normalizer·semcache·upstream(§6 签名占位)
  / routes(/proxy/v1/models OpenAI 形状)/ __init__(build_proxy_router 组装点)
- settings DEFAULTS 增 proxy 段(enabled 默认 False,D-P7)
- api.py 首次 include_router(enabled 门控 + 装配失败不拖垮主应用)
- serve.py workers>1 拒绝启动(D-P9:WEB_CONCURRENCY/UVICORN_WORKERS 校验)
- 测试 +4(门控 404/DDL 幂等/毫元换算/池模型列表),全量 322 passed
2026-09-05 08:35:31 +08:00