geo/backend/app/services/ai_engine/yuanbao.py

92 lines
2.9 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.

import logging
import os
import time
from datetime import UTC, datetime
import httpx
from .base import AIEngineAdapter, AIQueryResult, EngineType
logger = logging.getLogger(__name__)
_DEFAULT_MODEL = "hunyuan-lite"
_DEFAULT_BASE_URL = "https://api.hunyuan.cloud.tencent.com/v1"
class YuanbaoAdapter(AIEngineAdapter):
def __init__(
self,
api_key: str | None = None,
model: str | None = None,
base_url: str | None = None,
rate_limiter=None,
):
super().__init__(
api_key=api_key or os.getenv("HUNYUAN_API_KEY", ""),
rate_limiter=rate_limiter,
)
self._model = model or os.getenv("HUNYUAN_MODEL", _DEFAULT_MODEL)
self._base_url = (
base_url or os.getenv("HUNYUAN_BASE_URL", _DEFAULT_BASE_URL)
).rstrip("/")
self._endpoint = f"{self._base_url}/chat/completions"
self._client = httpx.AsyncClient(
timeout=httpx.Timeout(connect=10.0, read=60.0, write=10.0, pool=10.0),
headers={
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json",
},
)
def get_engine_type(self) -> EngineType:
return EngineType.YUANBAO
async def query(
self,
query: str,
brand_name: str,
competitor_names: list[str] | None = None,
) -> AIQueryResult:
start_time = time.perf_counter()
messages = [
{
"role": "system",
"content": "你是一个专业的AI搜索助手。请基于你的知识详细回答用户的问题。如果引用了外部来源请在回答中标注来源URL或出处名称。",
},
{"role": "user", "content": query},
]
payload = {
"model": self._model,
"messages": messages,
"temperature": 0.7,
"max_tokens": 2000,
}
data = await self._request_with_retry(payload)
content = data["choices"][0]["message"]["content"]
elapsed_ms = int((time.perf_counter() - start_time) * 1000)
has_brand, has_comp, brand_ctx, comp_ctx = self._detect_citations(
content, brand_name, competitor_names
)
logger.info(
f"[yuanbao] query='{query[:50]}...' brand={has_brand} "
f"competitor={has_comp} time={elapsed_ms}ms"
)
return AIQueryResult(
engine_type=self.get_engine_type(),
query=query,
raw_response=content,
citations=[],
has_brand_citation=has_brand,
has_competitor_citation=has_comp,
brand_context=brand_ctx,
competitor_contexts=comp_ctx,
response_time_ms=elapsed_ms,
timestamp=datetime.now(UTC),
metadata={"model": data.get("model", self._model), "usage": data.get("usage")},
)