refactor: migrate workflow to v2 core and archive legacy modules
This commit is contained in:
91
core/pydantic_ai_agent_v2.py
Normal file
91
core/pydantic_ai_agent_v2.py
Normal file
@@ -0,0 +1,91 @@
|
||||
import os
|
||||
import logging
|
||||
from typing import List, Optional, Any, Dict
|
||||
from pydantic_ai import Agent, RunContext
|
||||
from pydantic_ai.models.openai import OpenAIChatModel
|
||||
from pydantic_ai.providers.openai import OpenAIProvider
|
||||
from core.schema import StandardMessage, StandardResponse
|
||||
from core.agent_tools import register_agent_tools
|
||||
|
||||
logger = logging.getLogger("cs_agent")
|
||||
|
||||
from core.skill_manager import skill_manager
|
||||
|
||||
class CustomerServiceBrain:
|
||||
"""
|
||||
重构后的单一 Agent 大脑:
|
||||
【全能终极版】统一称呼为“设计师”,支持下线安抚。
|
||||
"""
|
||||
|
||||
def __init__(self, model_name: str = None):
|
||||
self.api_key = os.getenv("OPENAI_API_KEY")
|
||||
self.base_url = os.getenv("OPENAI_BASE_URL")
|
||||
self.model_name = model_name or os.getenv("OPENAI_MODEL", "gpt-4o-mini")
|
||||
|
||||
model = OpenAIChatModel(
|
||||
model_name=self.model_name,
|
||||
provider=OpenAIProvider(api_key=self.api_key, base_url=self.base_url)
|
||||
)
|
||||
|
||||
all_skills = skill_manager.get_all_skills_text()
|
||||
|
||||
# --- 统一口径后的 System Prompt ---
|
||||
system_prompt = (
|
||||
"你是一位专注【高清修复】和【找原图】的专业店主。性格干脆,说话高端、专业。\n\n"
|
||||
|
||||
"【统一称呼规范】\n"
|
||||
"1. 严禁使用'师傅'、'客服'、'专员'等词汇!\n"
|
||||
"2. 必须统一称呼为【设计师】。比如:'找设计师看下'、'设计师马上来'、'等设计师核价'。\n\n"
|
||||
|
||||
"【核心逻辑】\n"
|
||||
"1. 业务:只聊高清修复和找原图。引导发图 -> 问需求 -> 找设计师。\n"
|
||||
"2. 下线安抚:如果工具返回 'ERROR_NO_DESIGNER_ONLINE',说明设计师们【下班/下线】了。回:'亲亲,设计师现在下班啦,需求我先记下,明天第一时间回您哈!'。\n"
|
||||
"3. 正在转接中:如果看到系统提示已在转接,回:'设计师正在赶来,我再帮你催下哈!'。\n"
|
||||
"4. 没转接时:引导发图 -> 问需求 -> 调工具转人工。\n\n"
|
||||
"5. 语气:淘宝亲切风,多用'亲亲'、'铁子'。每句回复【严禁超过15字】!\n\n"
|
||||
|
||||
"【必杀令】\n"
|
||||
"1. 每句回复严禁超过15个字!\n"
|
||||
"2. 严禁报价,严禁复读图片已收到的情况。\n"
|
||||
"3. 必须原样输出工具返回的'正在为您转接|'指令。\n\n"
|
||||
|
||||
f"业务参考:\n{all_skills}"
|
||||
)
|
||||
|
||||
self.agent = Agent(model=model, system_prompt=system_prompt)
|
||||
register_agent_tools(self.agent)
|
||||
|
||||
async def think_and_reply(self, msg: StandardMessage, history: List[dict] = []) -> StandardResponse:
|
||||
try:
|
||||
# 构造增强上下文(强灌输)
|
||||
user_content = msg.content
|
||||
if msg.image_urls:
|
||||
user_content = f"【系统通知:收到客户 {len(msg.image_urls)} 张图】\n{user_content}"
|
||||
|
||||
recent_context = ""
|
||||
if history:
|
||||
lines = [f"{('客户' if h['role']=='user' else '我')}:{h['content']}" for h in history[-6:]]
|
||||
recent_context = "【近期对话回顾】\n" + "\n".join(lines) + "\n----------------\n"
|
||||
|
||||
full_input = f"{recent_context}现在的对话:{user_content}"
|
||||
|
||||
result = await self.agent.run(full_input, message_history=history)
|
||||
|
||||
if hasattr(result, 'data') and isinstance(result.data, str):
|
||||
reply_text = result.data
|
||||
elif hasattr(result, 'output') and isinstance(result.output, str):
|
||||
reply_text = result.output
|
||||
else:
|
||||
reply_text = str(result.data) if hasattr(result, 'data') else "在呢铁子。"
|
||||
|
||||
need_transfer = "[转移会话]" in reply_text
|
||||
|
||||
return StandardResponse(
|
||||
reply_content=reply_text,
|
||||
need_transfer=need_transfer,
|
||||
metadata={"acc_id": msg.acc_id, "acc_type": msg.acc_type}
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"[Brain Error]: {e}")
|
||||
return StandardResponse(reply_content="好哒,设计师正在看图,稍等回你。", metadata={"acc_id": msg.acc_id})
|
||||
Reference in New Issue
Block a user