Python/产品需求文档AI生成/utils/agent.py

112 lines
3.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- 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()