feat: 增强 Agent 系统和完善项目结构

主要改进:
- Agent 增强: 订单查询、售后支持、客服路由等功能优化
- 新增语言检测和 Token 管理模块
- 改进 Chatwoot webhook 处理和用户标识
- MCP 服务器增强: 订单 MCP 和 Strapi MCP 功能扩展
- 新增商城客户端、知识库、缓存和同步模块
- 添加多语言提示词系统 (YAML)
- 完善项目结构: 整理文档、脚本和测试文件
- 新增调试和测试工具脚本

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
wangliang
2026-01-16 16:28:47 +08:00
parent 0e59f3067e
commit e093995368
48 changed files with 5263 additions and 395 deletions

110
agent/prompts/base.py Normal file
View File

@@ -0,0 +1,110 @@
"""
Multi-language Prompt Loader
Loads system prompts for different agents in different languages.
"""
import yaml
from pathlib import Path
from typing import Optional
from utils.logger import get_logger
logger = get_logger(__name__)
# Base directory for prompt templates
PROMPTS_DIR = Path(__file__).parent
# Supported locales
SUPPORTED_LOCALES = ["en", "nl", "de", "es", "fr", "it", "tr"]
# Default locale
DEFAULT_LOCALE = "en"
class PromptLoader:
"""Load and cache prompt templates for different languages"""
def __init__(self):
self._cache = {}
def get_prompt(self, agent_type: str, locale: str) -> str:
"""Get system prompt for agent type and locale
Args:
agent_type: Type of agent (customer_service, aftersale, order, product, router)
locale: Language locale (en, nl, de, etc.)
Returns:
System prompt string
"""
# Validate locale
if locale not in SUPPORTED_LOCALES:
logger.warning(
"Unsupported locale, using default",
requested_locale=locale,
default_locale=DEFAULT_LOCALE
)
locale = DEFAULT_LOCALE
# Check cache
cache_key = f"{agent_type}:{locale}"
if cache_key in self._cache:
return self._cache[cache_key]
# Load prompt file
prompt_file = PROMPTS_DIR / agent_type / f"{locale}.yaml"
if not prompt_file.exists():
logger.warning(
"Prompt file not found, using default",
agent_type=agent_type,
locale=locale,
file=str(prompt_file)
)
# Fallback to English
prompt_file = PROMPTS_DIR / agent_type / f"{DEFAULT_LOCALE}.yaml"
if not prompt_file.exists():
# Fallback to hardcoded English prompt
logger.error("No prompt file found, using fallback", agent_type=agent_type)
return self._get_fallback_prompt(agent_type)
# Load and parse YAML
try:
with open(prompt_file, 'r', encoding='utf-8') as f:
data = yaml.safe_load(f)
prompt = data.get('system_prompt', '')
self._cache[cache_key] = prompt
return prompt
except Exception as e:
logger.error("Failed to load prompt file", file=str(prompt_file), error=str(e))
return self._get_fallback_prompt(agent_type)
def _get_fallback_prompt(self, agent_type: str) -> str:
"""Get fallback prompt if file loading fails"""
fallbacks = {
"customer_service": """You are a professional B2B customer service assistant. Help users with their questions.""",
"aftersale": """You are a professional B2B aftersale service assistant. Help users with returns and exchanges.""",
"order": """You are a professional B2B order assistant. Help users with order inquiries.""",
"product": """You are a professional B2B product assistant. Help users find products.""",
"router": """You are an AI assistant that routes user messages to appropriate agents."""
}
return fallbacks.get(agent_type, "You are a helpful AI assistant.")
# Global loader instance
_loader = PromptLoader()
def get_prompt(agent_type: str, locale: str) -> str:
"""Get system prompt for agent type and locale
Args:
agent_type: Type of agent (customer_service, aftersale, order, product, router)
locale: Language locale (en, nl, de, etc.)
Returns:
System prompt string
"""
return _loader.get_prompt(agent_type, locale)