"""Qwen Provider (兼容 OpenAI SDK)""" from openai import AsyncOpenAI from app.providers.base import BaseLLMProvider, LLMMessage, LLMResponse class QwenProvider(BaseLLMProvider): """通义千问 Provider,使用 OpenAI SDK 兼容模式""" def __init__( self, api_key: str, model: str = "qwen-turbo", base_url: str = "https://dashscope.aliyuncs.com/compatible-mode/v1", ): self.api_key = api_key self.model = model self.client = AsyncOpenAI(api_key=api_key, base_url=base_url) async def chat(self, messages: list[LLMMessage]) -> LLMResponse: response = await self.client.chat.completions.create( model=self.model, messages=[{"role": m.role, "content": m.content} for m in messages], ) return LLMResponse( content=response.choices[0].message.content or "", model=response.model, usage={ "total_tokens": response.usage.total_tokens, "prompt_tokens": response.usage.prompt_tokens, "completion_tokens": response.usage.completion_tokens, }, ) async def chat_stream(self, messages: list[LLMMessage]) -> str: stream = await self.client.chat.completions.create( model=self.model, messages=[{"role": m.role, "content": m.content} for m in messages], stream=True, ) async for chunk in stream: if chunk.choices[0].delta.content: yield chunk.choices[0].delta.content async def embed(self, texts: list[str]) -> list[list[float]]: # Qwen embedding 使用不同接口 response = await self.client.embeddings.create( model="text-embedding-v3", input=texts, ) return [item.embedding for item in response.data]