embedding.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. """火山方舟 Doubao-embedding-vision 文本向量化客户端(scope-link 用)。
  2. 契约见《数据接口与来源/embedding接口.md》:
  3. - Endpoint: POST .../api/v3/embeddings/multimodal(vision 版必须走 multimodal)
  4. - model = 预置推理接入点 ep-id
  5. - 输入 input=[{"type":"text","text":...}],输出 data.embedding = 2048 维
  6. - 单条调用(一次请求一个向量),批量靠并发多次请求。
  7. 密钥/ep 全部从 .env 读,不硬编码。
  8. """
  9. from __future__ import annotations
  10. import time
  11. from dataclasses import dataclass
  12. from pathlib import Path
  13. import httpx
  14. from core.config import env_value, load_env_file
  15. _DEFAULT_URL = "https://ark.cn-beijing.volces.com/api/v3/embeddings/multimodal"
  16. @dataclass
  17. class ArkEmbedConfig:
  18. api_key: str
  19. endpoint: str # ep-id,作为 model 字段传入
  20. url: str = _DEFAULT_URL
  21. dim: int = 2048
  22. timeout: int = 30
  23. @classmethod
  24. def from_env(cls, env_file: str | Path = ".env") -> "ArkEmbedConfig":
  25. fe = load_env_file(env_file)
  26. return cls(
  27. api_key=env_value("ARK_API_KEY", fe, required=True),
  28. endpoint=env_value("ARK_EMBEDDING_EP", fe, required=True),
  29. url=env_value("ARK_EMBEDDING_URL", fe, _DEFAULT_URL),
  30. dim=int(env_value("ARK_EMBEDDING_DIM", fe, "2048")),
  31. )
  32. def embed_text(text: str, cfg: ArkEmbedConfig, retries: int = 4) -> list[float]:
  33. """文本 → 2048 维向量。失败指数退避重试,最终仍失败则抛出。"""
  34. payload = {"model": cfg.endpoint, "input": [{"type": "text", "text": text}]}
  35. headers = {
  36. "Authorization": f"Bearer {cfg.api_key}",
  37. "Content-Type": "application/json",
  38. }
  39. last_err: Exception | None = None
  40. for attempt in range(retries):
  41. try:
  42. resp = httpx.post(cfg.url, json=payload, headers=headers, timeout=cfg.timeout)
  43. resp.raise_for_status()
  44. return resp.json()["data"]["embedding"]
  45. except Exception as err: # noqa: BLE001 — 网络/限流统一退避重试
  46. last_err = err
  47. time.sleep(1.0 * (attempt + 1))
  48. raise RuntimeError(f"ark embed failed for {text!r}: {last_err}")