llm_adapter.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. """
  2. LLM 适配器 - 基于 HelloAgent 框架
  3. """
  4. import asyncio
  5. import logging
  6. from typing import Any, List, Union
  7. from core.config import get_config
  8. from core.exceptions import LLMException
  9. logger = logging.getLogger(__name__)
  10. class LLMAdapter:
  11. def __init__(self):
  12. self.config = get_config()
  13. self.llm = None
  14. self._init_llm()
  15. def _init_llm(self):
  16. """初始化 HelloAgent LLM"""
  17. try:
  18. from hello_agents import HelloAgentsLLM
  19. self.llm = HelloAgentsLLM(
  20. model=self.config.llm.model_name,
  21. api_key=self.config.llm.api_key,
  22. base_url=self.config.llm.base_url,
  23. temperature=self.config.llm.temperature,
  24. max_tokens=self.config.llm.max_tokens,
  25. timeout=self.config.llm.timeout
  26. )
  27. logger.info(f"HelloAgent LLM 初始化成功: {self.config.llm.model_name}")
  28. except ImportError as e:
  29. logger.error(f"hello-agents 未安装: {str(e)}")
  30. raise ImportError("请安装 hello-agents: pip install 'hello-agents[all]>=0.2.7'")
  31. except Exception as e:
  32. logger.error(f"HelloAgent LLM 初始化失败: {str(e)}")
  33. raise
  34. def _format_messages(self, prompt: Union[str, List[dict]]) -> List[dict]:
  35. if isinstance(prompt, str):
  36. return [{"role": "user", "content": prompt}]
  37. if isinstance(prompt, list):
  38. return prompt
  39. return [{"role": "user", "content": str(prompt)}]
  40. async def ainvoke(self, prompt: Union[str, List[dict]], **kwargs) -> str:
  41. try:
  42. messages = self._format_messages(prompt)
  43. response = await asyncio.to_thread(self.llm.invoke, messages, **kwargs)
  44. return self._extract_text(response)
  45. except Exception as e:
  46. raise LLMException(f"LLM 调用失败: {e}")
  47. def invoke(self, prompt: Union[str, List[dict]], **kwargs) -> str:
  48. try:
  49. messages = self._format_messages(prompt)
  50. response = self.llm.invoke(messages, **kwargs)
  51. return self._extract_text(response)
  52. except Exception as e:
  53. raise LLMException(f"LLM 调用失败: {e}")
  54. def _extract_text(self, response: Any) -> str:
  55. if isinstance(response, str):
  56. return response
  57. if hasattr(response, "content"):
  58. return response.content
  59. if hasattr(response, "text"):
  60. return response.text
  61. return str(response)
  62. # 全局实例
  63. _llm_adapter: LLMAdapter | None = None
  64. def get_llm_adapter() -> LLMAdapter:
  65. global _llm_adapter
  66. if _llm_adapter is None:
  67. _llm_adapter = LLMAdapter()
  68. return _llm_adapter