"""Ollama 客户端 通过 Ollama HTTP API 调用本地模型进行文本生成。 """ import httpx import structlog from app.config import settings logger = structlog.get_logger() class OllamaClient: """Ollama HTTP API 客户端""" def __init__( self, base_url: str | None = None, model: str | None = None, timeout: float = 120.0, ) -> None: self.base_url = (base_url or settings.ollama_base_url).rstrip("/") self.model = model or settings.ollama_model self.timeout = timeout async def generate(self, prompt: str, json_mode: bool = False) -> str: """调用 Ollama 生成文本 Args: prompt: 输入提示词 json_mode: 为 True 时启用 Ollama 原生 JSON 约束输出(payload 加 format: json) Returns: 生成的文本内容 """ url = f"{self.base_url}/api/generate" payload = { "model": self.model, "prompt": prompt, "stream": False, } if json_mode: payload["format"] = "json" async with httpx.AsyncClient(timeout=self.timeout) as client: resp = await client.post(url, json=payload) resp.raise_for_status() data = resp.json() result = data.get("response", "") logger.debug("Ollama 生成完成", model=self.model, output_length=len(result)) return result async def is_available(self) -> bool: """检查 Ollama 服务是否可用""" try: async with httpx.AsyncClient(timeout=5.0) as client: resp = await client.get(f"{self.base_url}/api/tags") return resp.status_code == 200 except httpx.HTTPError: return False