feat(sense): T-G1+T-G2 Embedder 与观察埋点
- T-G1 embedder.py:embed() 调 llama-server /v1/embeddings -> 对称 per-vector int8 量化(scale=127/max|v|,1024 维余弦扰动 ~1e-4 << 1e-2 验收); 超时/连接/非200/空形状 -> EmbedderDown(D-G4 fail-closed); /v1/embeddings OpenAI 兼容透传(双路由组:/sense 前缀 + /v1 无前缀, 不可用 503);build_sense_routers 返回列表 - T-G2 observer.py:Observation + 批量缓冲 100ms 刷盘(asyncio.Queue + to_thread,D-P10);三消费方共用;升级阶梯回写 outcome/executed_tier; D-G6 无 query 原文列(int8 BLOB + 特征 JSON) - 测试 +11(量化误差/范围/fail-closed×3/透传/单例/BLOB 持久化/批量刷盘/ 回写/无原文列),全量 381->386->381? 校正:386 passed - 待真机项:llama-server embedder 端点冒烟(需配置 embedder.base_url)
This commit is contained in:
+19
-11
@@ -1,7 +1,4 @@
|
||||
"""Sense 路由(T-G1):/sense 前缀组 + /v1 无前缀组(embeddings 透传)。
|
||||
|
||||
/v1/route(T-G5 grader)后续加入无前缀组;/sense/admin/*(T-G3+)加入前缀组。
|
||||
"""
|
||||
"""Sense 路由(T-G2 补观察初始化):/sense 前缀组 + /v1 无前缀组。"""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List
|
||||
@@ -12,27 +9,37 @@ from fastapi.responses import JSONResponse
|
||||
from gateway.sense.config import SenseConfig
|
||||
from gateway.sense.embedder import embed
|
||||
from gateway.sense.errors import EmbedderDown
|
||||
from gateway.sense.observer import get_observer
|
||||
from gateway.sense.store import SenseStore
|
||||
|
||||
|
||||
def build_sense_routers(cfg: SenseConfig) -> List[APIRouter]:
|
||||
"""组装 sense 路由组:[/sense 前缀组, /v1 无前缀组]。"""
|
||||
main = APIRouter(prefix="/sense")
|
||||
v1 = APIRouter()
|
||||
store = SenseStore.init_db(cfg.db_path)
|
||||
|
||||
@main.on_event("startup")
|
||||
async def _start_observer():
|
||||
get_observer(store)
|
||||
obs = get_observer()
|
||||
await obs.start()
|
||||
|
||||
@main.on_event("shutdown")
|
||||
async def _stop_observer():
|
||||
obs = get_observer()
|
||||
await obs.flush_once()
|
||||
await obs.stop()
|
||||
|
||||
@main.get("/health", tags=["sense"])
|
||||
async def health():
|
||||
"""sense 面健康检查(含灰度状态,供看板/运维)。"""
|
||||
"""sense 面健康检查(含灰度状态)。"""
|
||||
return {"enabled": cfg.enabled, "mode": cfg.mode,
|
||||
"embedder": cfg.embedder.base_url}
|
||||
|
||||
@v1.post("/v1/embeddings", tags=["sense"])
|
||||
async def embeddings(request: Request):
|
||||
"""OpenAI 兼容透传 embedder(客户端/代理共用)。
|
||||
|
||||
请求:{"model"?, "input": str};响应:{"object":"list","data":[{"object":
|
||||
"embedding","index":0,"embedding":[int8...]}],"model":...}。
|
||||
embedder 不可用 -> 503(D-G4 fail-closed,客户端可感知降级)。
|
||||
"""
|
||||
"""OpenAI 兼容透传 embedder(客户端/代理共用)。"""
|
||||
try:
|
||||
body = await request.json()
|
||||
except Exception:
|
||||
@@ -49,4 +56,5 @@ def build_sense_routers(cfg: SenseConfig) -> List[APIRouter]:
|
||||
return {"object": "list", "model": model,
|
||||
"data": [{"object": "embedding", "index": 0, "embedding": vec}]}
|
||||
|
||||
# /v1/route(T-G5 grader)与 /sense/admin/*(T-G3+)后续追加。
|
||||
return [main, v1]
|
||||
|
||||
Reference in New Issue
Block a user