# -*- coding: utf-8 -*- """ 智能体模块 """ # 列举导入模块 from pathlib import Path import sys from typing import List, Optional from uuid import uuid4 from starlette.applications import Starlette from pydantic_ai import Agent, AgentRunResult from pydantic_ai.models.openai import OpenAIChatModel from pydantic_ai.output import OutputSpec from pydantic_ai.providers.openai import OpenAIProvider from pydantic_ai_skills import SkillsToolset sys.path.append(Path(__file__).parent.as_posix()) from memory import Memory class BaseAgent: """ 通用智能体基类,支持: 1)实例智能体 2)异步运行 """ def __init__( self, instructions: str, output_type: OutputSpec = str, skill_name: Optional[str] = None, ): """ 初始化智能体 :param instructions: 指令 :param output_type: 输出类型 :param skill_name: 技能名称,默认不使用技能 :return: 智能体实例 """ # 生成会话唯一标识 self.session_id = uuid4().hex.lower() # 实例智能体 self.agent = self._instantiate_agent( skill_name=skill_name, instructions=instructions, output_type=output_type, ) # 实例记忆体 self.memory = Memory() def _instantiate_agent( self, skill_name: Optional[str], instructions: str, output_type: OutputSpec ) -> Agent: """ 实例智能体 :param skill_name: 技能名称 :param instructions: 指令 :param output_type: 输出类型 :return: 智能体实例 """ # 若技能名称为空则技能集合为 None,若技能名称非空则构建技能路径 if not skill_name: toolsets = None else: toolsets = [ SkillsToolset( directories=[Path(__file__).parent.parent / "skills" / skill_name] ) ] agent = Agent( toolsets=toolsets, model=OpenAIChatModel( model_name="deepseek-v4-flash", provider=OpenAIProvider( base_url="https://tokenhub.tencentmaas.com/v1", api_key="sk-D9Y1mCe8VlvNqLuSC4mAjqEwxJ2nW4C0h8a7EPn8kg9RLsHq", ), ), instructions=instructions, output_type=output_type, ) return agent async def run(self, user_prompt: str | List[str]) -> AgentRunResult: """ 异步运行 :param user_prompt: 用户提示词 :return: 智能体回复 """ # 查询会话历史消息 message_history = self.memory.read(session_id=self.session_id) result = await self.agent.run( user_prompt=user_prompt, message_history=message_history ) # 记录会话历史消息 self.memory.create( session_id=self.session_id, dialogue_message=result.new_messages(), ) return result def to_web(self) -> Starlette: """ 实例 Starlette 应用 :return: Starlette 应用实例 """ return self.agent.to_web()