import anthropic from typing import Optional, List, Dict, Any, Tuple from sqlalchemy.orm import Session from providers.base_provider import LLMProvider from services.api_key_service import ApiKeyService SYSTEM_PROMPT = "你正在参与一场结构化辩论。请按照用户消息中的规则进行辩论,直接给出你的论点,不要重复提示词或历史记录。" class ClaudeProvider(LLMProvider): """ Anthropic Claude API provider implementation """ def __init__(self, db: Session, api_key: Optional[str] = None): if not api_key: api_key = ApiKeyService.get_api_key(db, "claude") if api_key: self.client = anthropic.AsyncAnthropic(api_key=api_key) else: raise ValueError("Claude API key not found in database or provided") def supports_tools(self) -> bool: return True async def generate_response(self, model: str, prompt: str, max_tokens: Optional[int] = None) -> str: try: response = await self.client.messages.create( model=model, max_tokens=max_tokens or 500, temperature=0.7, system=SYSTEM_PROMPT, messages=[ {"role": "user", "content": prompt} ] ) return response.content[0].text except Exception as e: raise Exception(f"Error calling Claude API: {str(e)}") async def generate_response_with_tools( self, model: str, prompt: str, tools: List[Dict[str, Any]], max_tokens: Optional[int] = None ) -> Tuple[str, List[Dict[str, Any]]]: try: # Convert OpenAI-format tools to Anthropic format anthropic_tools = [] for tool in tools: func = tool.get("function", tool) anthropic_tools.append({ "name": func["name"], "description": func.get("description", ""), "input_schema": func.get("parameters", func.get("input_schema", {})) }) response = await self.client.messages.create( model=model, max_tokens=max_tokens or 500, temperature=0.7, system=SYSTEM_PROMPT, messages=[ {"role": "user", "content": prompt} ], tools=anthropic_tools ) text_content = "" tool_calls = [] for block in response.content: if block.type == "text": text_content += block.text elif block.type == "tool_use": tool_calls.append({ "name": block.name, "arguments": block.input }) return text_content.strip(), tool_calls except Exception as e: raise Exception(f"Error calling Claude API with tools: {str(e)}")