llm_adapter.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. """
  2. LLM 适配器 - 基于 HelloAgent 框架
  3. """
  4. import logging
  5. from typing import Dict, Any, Optional
  6. from core.config import get_config
  7. logger = logging.getLogger(__name__)
  8. class LLMAdapter:
  9. """LLM 适配器,基于 HelloAgent 框架"""
  10. def __init__(self):
  11. """初始化 LLM 适配器"""
  12. self.config = get_config()
  13. self.llm = None
  14. self._initialize_llm()
  15. def _initialize_llm(self):
  16. """初始化 HelloAgent LLM"""
  17. try:
  18. from hello_agents import HelloAgentsLLM
  19. # 根据文档,HelloAgentsLLM 的初始化参数
  20. self.llm = HelloAgentsLLM(
  21. model=self.config.llm.model_name,
  22. api_key=self.config.llm.api_key,
  23. base_url=self.config.llm.base_url,
  24. temperature=self.config.llm.temperature,
  25. max_tokens=self.config.llm.max_tokens,
  26. timeout=self.config.llm.timeout
  27. )
  28. logger.info(f"HelloAgent LLM 初始化成功: {self.config.llm.model_name}")
  29. except ImportError as e:
  30. logger.error(f"hello-agents 未安装: {str(e)}")
  31. raise ImportError("请安装 hello-agents: pip install 'hello-agents[all]>=0.2.7'")
  32. except Exception as e:
  33. logger.error(f"HelloAgent LLM 初始化失败: {str(e)}")
  34. raise
  35. def _format_messages(self, prompt: str) -> list:
  36. """
  37. 将提示词格式化为消息列表
  38. Args:
  39. prompt: 提示词字符串
  40. Returns:
  41. 消息列表,格式为 [{"role": "user", "content": "..."}]
  42. """
  43. if isinstance(prompt, str):
  44. return [{"role": "user", "content": prompt}]
  45. elif isinstance(prompt, list):
  46. return prompt
  47. else:
  48. return [{"role": "user", "content": str(prompt)}]
  49. async def ainvoke(self, prompt: str, **kwargs) -> str:
  50. """
  51. 异步调用 LLM
  52. Args:
  53. prompt: 提示词(字符串或消息列表)
  54. **kwargs: 额外参数
  55. Returns:
  56. LLM 响应文本
  57. """
  58. try:
  59. # 格式化消息
  60. messages = self._format_messages(prompt)
  61. # HelloAgent 使用同步 invoke,在异步上下文中调用
  62. import asyncio
  63. response = await asyncio.to_thread(self.llm.invoke, messages, **kwargs)
  64. # 提取文本内容
  65. if isinstance(response, str):
  66. return response
  67. elif hasattr(response, 'content'):
  68. return response.content
  69. elif hasattr(response, 'text'):
  70. return response.text
  71. else:
  72. return str(response)
  73. except Exception as e:
  74. logger.error(f"LLM 异步调用失败: {str(e)}")
  75. raise
  76. def invoke(self, prompt: str, **kwargs) -> str:
  77. """
  78. 同步调用 LLM
  79. Args:
  80. prompt: 提示词(字符串或消息列表)
  81. **kwargs: 额外参数
  82. Returns:
  83. LLM 响应文本
  84. """
  85. try:
  86. # 格式化消息
  87. messages = self._format_messages(prompt)
  88. # HelloAgent 的同步调用
  89. response = self.llm.invoke(messages, **kwargs)
  90. # 提取文本内容
  91. if isinstance(response, str):
  92. return response
  93. elif hasattr(response, 'content'):
  94. return response.content
  95. elif hasattr(response, 'text'):
  96. return response.text
  97. else:
  98. return str(response)
  99. except Exception as e:
  100. logger.error(f"LLM 同步调用失败: {str(e)}")
  101. raise
  102. # 全局 LLM 适配器实例
  103. _llm_adapter = None
  104. def get_llm_adapter() -> LLMAdapter:
  105. """获取全局 LLM 适配器实例"""
  106. global _llm_adapter
  107. if _llm_adapter is None:
  108. _llm_adapter = LLMAdapter()
  109. return _llm_adapter