Files
projectAIpopular/gateway/sense/routes.py
T
tzt 51f1de2154 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)
2026-09-05 13:37:59 +08:00

61 lines
2.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Sense 路由(T-G2 补观察初始化):/sense 前缀组 + /v1 无前缀组。"""
from __future__ import annotations
from typing import List
from fastapi import APIRouter, Request
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 面健康检查(含灰度状态)。"""
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(客户端/代理共用)。"""
try:
body = await request.json()
except Exception:
body = {}
text = str((body or {}).get("input") or "").strip()
if not text:
return JSONResponse({"error": {"message": "input 必填"}}, status_code=400)
model = str((body or {}).get("model") or cfg.embedder.model)
try:
vec = await embed(text, cfg.embedder)
except EmbedderDown as e:
return JSONResponse(
{"error": {"message": str(e), "type": "embedder_down"}}, status_code=503)
return {"object": "list", "model": model,
"data": [{"object": "embedding", "index": 0, "embedding": vec}]}
# /v1/routeT-G5 grader)与 /sense/admin/*T-G3+)后续追加。
return [main, v1]