LangGraph动态提示词实战:构建能记住用户身份的智能助手

在构建智能对话系统时,我们常常面临一个核心挑战:如何让AI记住用户是谁?想象一下,当你第二次与客服机器人对话时,它仍然需要你重复姓名;或者当你向个人助理询问日程时,它无法区分这是你的日程还是他人的。这种缺乏记忆的交互体验,让对话显得生硬而缺乏温度。

传统的静态提示词方案已经无法满足现代个性化服务的需求。每个用户都是独特的个体,他们有自己的偏好、习惯和身份信息。如果我们的AI系统无法记住这些关键信息,就无法提供真正个性化的服务体验。这正是动态提示词技术要解决的核心问题——让AI在运行时根据用户上下文动态调整自己的行为。

LangGraph作为新一代的智能体框架,提供了强大的动态提示词机制。与简单的字符串模板不同,它允许我们在对话流程中注入实时信息,让AI能够“记住”用户身份,并根据这些信息生成个性化的回应。这种能力对于客服系统、个人助理、教育辅导等场景至关重要。

1. 动态提示词的核心原理:从静态到动态的范式转变

1.1 静态提示词的局限性

在传统的AI应用开发中,提示词通常是硬编码的字符串。比如一个典型的客服系统提示词可能是这样的:

static_prompt = """你是一个客服助手,请礼貌地回答用户问题。
用户问题:{user_question}
请提供专业、友好的回答。"""

这种静态方式有几个明显的缺陷:

  • 缺乏个性化:对所有用户使用相同的称呼和语气
  • 无法记忆上下文:每次对话都是独立的,无法记住之前的交互
  • 信息注入困难:运行时无法动态添加用户特定信息
  • 维护成本高:每次需要调整提示词都要修改代码并重新部署

1.2 动态提示词的工作机制

LangGraph的动态提示词机制通过函数式编程的方式,在运行时动态构建提示词。核心思想是将提示词生成逻辑封装为一个函数,这个函数可以访问当前对话状态和配置信息:

def dynamic_prompt(state: AgentState, config: RunnableConfig) -> list[AnyMessage]:
    # 从配置中获取用户信息
    user_name = config.get("configurable", {}).get("user_name", "用户")
    user_role = config.get("configurable", {}).get("user_role", "普通用户")
    
    # 从对话历史中提取上下文
    conversation_history = state["messages"]
    last_topic = extract_last_topic(conversation_history)
    
    # 动态构建系统消息
    system_message = f"""你是一个专业的{user_role}助手。
当前用户:{user_name}
最近讨论的话题:{last_topic}

请根据用户的身份和对话历史,提供个性化的服务。
如果用户是VIP客户,请使用更尊重的语气。
如果用户是技术支持人员,请使用更专业的术语。"""
    
    return [{"role": "system", "content": system_message}] + conversation_history

这种动态生成方式带来了几个关键优势:

特性静态提示词动态提示词
个性化程度
上下文感知
运行时调整不可
维护灵活性
多用户支持困难容易

1.3 配置参数的传递机制

LangGraph通过config参数实现了信息的跨会话传递。这个机制的核心是RunnableConfig对象,它允许我们在调用智能体时传入任意配置信息:

# 定义配置信息
user_config = {
    "configurable": {
        "user_id": "user_12345",
        "user_name": "张三",
        "user_preferences": {
            "language": "中文",
            "formality_level": "正式",
            "interests": ["技术", "阅读", "旅行"]
        },
        "conversation_context": {
            "last_session_topic": "产品咨询",
            "user_mood": "满意",
            "pending_issues": ["订单跟踪"]
        }
    }
}

# 在调用时传入配置
response = agent.invoke(
    {"messages": [{"role": "user", "content": "我的订单状态如何?"}]},
    config=user_config
)

注意:配置信息应该只包含必要的用户元数据,避免传递敏感信息如密码、支付信息等。建议对配置数据进行加密或使用安全的存储机制。

配置信息在整个对话流程中都是可访问的,这意味着即使在多轮对话中,AI也能保持对用户身份的认知。这种持久化的上下文管理是构建真正个性化体验的基础。

2. 实战:构建记住用户身份的客服助手

2.1 环境准备与依赖安装

让我们从搭建基础环境开始。首先确保你已经安装了必要的Python包:

# 创建虚拟环境(推荐)
python -m venv langgraph_env
source langgraph_env/bin/activate  # Linux/Mac
# 或
langgraph_env\Scripts\activate  # Windows

# 安装核心依赖
pip install langgraph langchain-core langchain-community

# 安装大模型接口
# 这里以通义千问为例,你也可以使用其他兼容的模型
pip install dashscope

# 可选:安装开发工具
pip install python-dotenv  # 环境变量管理
pip install pydantic  # 数据验证
pip install typing-extensions  # 类型提示支持

接下来创建项目结构:

personalized_assistant/
├── config/
│   ├── __init__.py
│   └── settings.py      # 配置管理
├── core/
│   ├── __init__.py
│   ├── agents.py        # 智能体定义
│   ├── prompts.py       # 提示词管理
│   └── memory.py        # 记忆管理
├── services/
│   ├── __init__.py
│   └── user_service.py  # 用户服务
├── utils/
│   ├── __init__.py
│   └── helpers.py       # 工具函数
├── tests/               # 测试目录
├── .env.example         # 环境变量示例
├── requirements.txt     # 依赖列表
└── main.py             # 主程序入口

config/settings.py中配置模型参数:

import os
from typing import Optional
from pydantic_settings import BaseSettings

class Settings(BaseSettings):
    # 模型配置
    model_provider: str = "tongyi"
    model_name: str = "qwen-turbo"
    model_temperature: float = 0.1
    model_max_tokens: Optional[int] = 2000
    
    # API配置
    tongyi_api_key: Optional[str] = None
    tongyi_api_base: str = "https://dashscope.aliyuncs.com/compatible-mode/v1"
    
    # 应用配置
    app_name: str = "个性化AI助手"
    debug_mode: bool = False
    
    class Config:
        env_file = ".env"
        env_file_encoding = "utf-8"

# 创建全局配置实例
settings = Settings()

# 从环境变量加载API密钥
if not settings.tongyi_api_key:
    settings.tongyi_api_key = os.getenv("TONGYI_API_KEY")

2.2 用户信息管理与动态注入

用户信息的管理是动态提示词系统的核心。我们需要一个可靠的方式来存储、检索和更新用户数据:

# services/user_service.py
from typing import Dict, Any, Optional
from datetime import datetime
import json

class UserProfile:
    """用户档案管理类"""
    
    def __init__(self, user_id: str):
        self.user_id = user_id
        self.profile = self._load_profile()
    
    def _load_profile(self) -> Dict[str, Any]:
        """加载用户档案"""
        # 这里可以替换为数据库、Redis或其他存储
        # 示例使用文件存储
        try:
            with open(f"data/users/{self.user_id}.json", "r", encoding="utf-8") as f:
                return json.load(f)
        except FileNotFoundError:
            # 返回默认档案
            return {
                "basic_info": {
                    "name": "用户",
                    "preferred_name": None,
                    "language": "zh-CN",
                    "timezone": "Asia/Shanghai"
                },
                "preferences": {
                    "formality": "balanced",  # formal, casual, balanced
                    "response_length": "medium",  # short, medium, detailed
                    "topics_of_interest": []
                },
                "interaction_history": {
                    "total_sessions": 0,
                    "last_session": None,
                    "frequent_topics": [],
                    "average_response_time": 0
                },
                "custom_data": {}
            }
    
    def update_profile(self, updates: Dict[str, Any]) -> None:
        """更新用户档案"""
        # 深度合并更新
        def deep_update(target: Dict, source: Dict) -> Dict:
            for key, value in source.items():
                if key in target and isinstance(target[key], dict) and isinstance(value, dict):
                    deep_update(target[key], value)
                else:
                    target[key] = value
            return target
        
        self.profile = deep_update(self.profile, updates)
        self._save_profile()
    
    def _save_profile(self) -> None:
        """保存用户档案"""
        import os
        os.makedirs("data/users", exist_ok=True)
        with open(f"data/users/{self.user_id}.json", "w", encoding="utf-8") as f:
            json.dump(self.profile, f, ensure_ascii=False, indent=2)
    
    def get_preferred_name(self) -> str:
        """获取用户偏好的称呼"""
        preferred = self.profile["basic_info"].get("preferred_name")
        name = self.profile["basic_info"].get("name", "用户")
        return preferred or name
    
    def get_interaction_context(self) -> Dict[str, Any]:
        """获取交互上下文"""
        return {
            "user_name": self.get_preferred_name(),
            "user_tier": self._calculate_user_tier(),
            "preferred_formality": self.profile["preferences"]["formality"],
            "last_interaction": self.profile["interaction_history"]["last_session"],
            "known_interests": self.profile["preferences"]["topics_of_interest"][:5]  # 只取前5个
        }
    
    def _calculate_user_tier(self) -> str:
        """计算用户等级"""
        total_sessions = self.profile["interaction_history"]["total_sessions"]
        if total_sessions > 50:
            return "vip"
        elif total_sessions > 10:
            return "regular"
        else:
            return "new"
    
    def record_interaction(self, topic: str, response_time: float) -> None:
        """记录交互历史"""
        self.profile["interaction_history"]["total_sessions"] += 1
        self.profile["interaction_history"]["last_session"] = datetime.now().isoformat()
        
        # 更新频繁话题
        topics = self.profile["interaction_history"]["frequent_topics"]
        if topic not in topics:
            topics.append(topic)
        # 只保留最近10个话题
        if len(topics) > 10:
            topics.pop(0)
        
        # 更新平均响应时间
        current_avg = self.profile["interaction_history"]["average_response_time"]
        total = self.profile["interaction_history"]["total_sessions"]
        new_avg = (current_avg * (total - 1) + response_time) / total
        self.profile["interaction_history"]["average_response_time"] = new_avg
        
        self._save_profile()

2.3 实现动态提示词生成器

现在让我们实现核心的动态提示词生成逻辑:

# core/prompts.py
from typing import List, Dict, Any
from langchain_core.messages import AnyMessage, SystemMessage, HumanMessage
from langchain_core.runnables import RunnableConfig
from datetime import datetime
import json

class DynamicPromptGenerator:
    """动态提示词生成器"""
    
    def __init__(self, user_service):
        self.user_service = user_service
    
    def generate_system_prompt(self, 
                              user_context: Dict[str, Any],
                              conversation_state: Dict[str, Any]) -> str:
        """生成系统提示词"""
        
        user_name = user_context.get("user_name", "用户")
        user_tier = user_context.get("user_tier", "new")
        formality = user_context.get("preferred_formality", "balanced")
        
        # 根据用户等级调整语气
        if user_tier == "vip":
            greeting = f"尊敬的{user_name},您好!"
            tone = "非常荣幸为您服务。我将以最专业、最贴心的态度回答您的问题。"
        elif user_tier == "regular":
            greeting = f"{user_name},您好!"
            tone = "很高兴再次为您服务。我会尽力提供准确的帮助。"
        else:
            greeting = f"您好!"
            tone = "我是您的智能助手,有什么可以帮您的吗?"
        
        # 根据正式程度调整语言风格
        if formality == "formal":
            style_guide = """
            请使用正式、专业的语言风格。
            使用完整的句子和规范的表达。
            避免使用网络用语和缩写。
            在适当的时候使用敬语。
            """
        elif formality == "casual":
            style_guide = """
            请使用自然、亲切的语言风格。
            可以使用一些日常用语。
            保持友好但不过于随意。
            适当使用表情符号(如合适)。
            """
        else:  # balanced
            style_guide = """
            请使用自然、专业的语言风格。
            保持友好但不失专业性。
            根据问题类型调整语气。
            """
        
        # 构建个性化上下文
        known_interests = user_context.get("known_interests", [])
        interests_context = ""
        if known_interests:
            interests_context = f"\n我知道您对以下话题感兴趣:{', '.join(known_interests)}。"
        
        # 时间上下文
        current_hour = datetime.now().hour
        time_greeting = ""
        if 5 <= current_hour < 12:
            time_greeting = "早上好!"
        elif 12 <= current_hour < 18:
            time_greeting = "下午好!"
        elif 18 <= current_hour < 22:
            time_greeting = "晚上好!"
        else:
            time_greeting = "您好!"
        
        # 组合完整的系统提示词
        system_prompt = f"""{time_greeting}{greeting}

{tone}

## 您的身份信息
- 称呼:{user_name}
- 用户类型:{user_tier}用户
- 偏好风格:{formality}

## 对话指导原则
{style_guide}

## 个性化服务指南
{interests_context}
1. 如果用户询问之前讨论过的话题,请参考历史记录
2. 根据用户等级调整响应详细程度
3. 如果用户是VIP,提供更主动的服务建议
4. 对于新用户,提供更详细的引导说明

## 响应要求
1. 始终使用用户偏好的称呼
2. 保持前后对话的一致性
3. 如果用户的问题涉及专业领域,请确保信息准确
4. 如果无法确定答案,请诚实地说明并提供替代方案

请基于以上信息,为用户提供最合适的帮助。"""
        
        return system_prompt
    
    def create_dynamic_messages(self,
                               state: Dict[str, Any],
                               config: RunnableConfig) -> List[AnyMessage]:
        """创建动态消息列表"""
        
        # 从配置中获取用户ID
        configurable = config.get("configurable", {})
        user_id = configurable.get("user_id")
        
        if not user_id:
            # 如果没有用户ID,使用默认提示词
            return [
                SystemMessage(content="您是一个有帮助的AI助手。"),
                *state["messages"]
            ]
        
        # 获取用户上下文
        user_profile = self.user_service.get_profile(user_id)
        user_context = user_profile.get_interaction_context()
        
        # 分析对话状态
        conversation_state = self._analyze_conversation_state(state)
        
        # 生成系统提示词
        system_content = self.generate_system_prompt(user_context, conversation_state)
        
        # 构建消息列表
        messages = [SystemMessage(content=system_content)]
        
        # 添加对话历史(可选:可以在这里进行历史消息的智能筛选)
        messages.extend(self._filter_relevant_messages(state["messages"], user_context))
        
        return messages
    
    def _analyze_conversation_state(self, state: Dict[str, Any]) -> Dict[str, Any]:
        """分析对话状态"""
        messages = state.get("messages", [])
        
        if not messages:
            return {"topic": None, "sentiment": "neutral", "complexity": "low"}
        
        # 简单的话题提取(实际项目中可以使用更复杂的NLP技术)
        last_user_message = None
        for msg in reversed(messages):
            if msg["role"] == "user":
                last_user_message = msg["content"]
                break
        
        # 这里可以添加更复杂的分析逻辑
        return {
            "topic": self._extract_topic(last_user_message) if last_user_message else None,
            "sentiment": "neutral",  # 可以集成情感分析
            "complexity": self._assess_complexity(last_user_message) if last_user_message else "low",
            "message_count": len(messages)
        }
    
    def _extract_topic(self, text: str) -> str:
        """简单的话题提取"""
        # 实际项目中可以使用关键词提取或分类模型
        topics = {
            "天气": ["天气", "气温", "下雨", "下雪", "温度"],
            "产品": ["产品", "商品", "购买", "价格", "订单"],
            "技术": ["技术", "代码", "编程", "开发", "bug"],
            "服务": ["客服", "服务", "帮助", "支持", "咨询"]
        }
        
        text_lower = text.lower()
        for topic, keywords in topics.items():
            if any(keyword in text_lower for keyword in keywords):
                return topic
        
        return "其他"
    
    def _assess_complexity(self, text: str) -> str:
        """评估问题复杂度"""
        word_count = len(text.split())
        if word_count > 50:
            return "high"
        elif word_count > 20:
            return "medium"
        else:
            return "low"
    
    def _filter_relevant_messages(self, 
                                 messages: List[AnyMessage],
                                 user_context: Dict[str, Any]) -> List[AnyMessage]:
        """筛选相关的历史消息"""
        # 简单的实现:返回最近5条消息
        # 实际项目中可以根据话题相关性进行智能筛选
        return messages[-5:] if len(messages) > 5 else messages

2.4 集成到LangGraph智能体

现在我们将动态提示词生成器集成到LangGraph智能体中:

# core/agents.py
from typing import List, Dict, Any
from langchain_core.messages import AnyMessage
from langchain_core.runnables import RunnableConfig
from langgraph.prebuilt import create_react_agent
from langchain_community.chat_models.tongyi import ChatTongyi
from langchain_core.tools import tool
import time

class PersonalizedAssistant:
    """个性化AI助手"""
    
    def __init__(self, prompt_generator, user_service):
        self.prompt_generator = prompt_generator
        self.user_service = user_service
        
        # 初始化大模型
        self.llm = ChatTongyi(
            model="qwen-turbo",
            temperature=0.1,
            verbose=True,
        )
        
        # 定义工具集
        self.tools = [
            self._create_lookup_tool(),
            self._create_calculation_tool(),
            self._create_reminder_tool()
        ]
        
        # 创建智能体
        self.agent = create_react_agent(
            model=self.llm,
            tools=self.tools,
            prompt=self._dynamic_prompt_function
        )
    
    def _dynamic_prompt_function(self, 
                                 state: Dict[str, Any], 
                                 config: RunnableConfig) -> List[AnyMessage]:
        """动态提示词函数 - 供LangGraph调用"""
        return self.prompt_generator.create_dynamic_messages(state, config)
    
    @tool
    def _create_lookup_tool(self):
        """信息查询工具"""
        def lookup_information(query: str) -> str:
            """查询相关信息"""
            # 这里可以集成知识库、数据库或API
            information_base = {
                "营业时间": "我们的营业时间是周一至周五 9:00-18:00,周末 10:00-17:00。",
                "联系方式": "客服电话:400-123-4567,邮箱:support@example.com。",
                "常见问题": "1. 如何修改订单?登录后在我的订单中操作。\n2. 退货政策?7天无理由退货。\n3. 配送时间?一般1-3个工作日。",
                "产品信息": "我们提供多种产品,包括A系列、B系列和C系列。具体信息请访问官网产品页面。"
            }
            
            for key, value in information_base.items():
                if key in query:
                    return value
            
            return "抱歉,我没有找到相关信息。您可以尝试联系人工客服获取更详细的帮助。"
        
        return lookup_information
    
    @tool
    def _create_calculation_tool(self):
        """计算工具"""
        def perform_calculation(expression: str) -> str:
            """执行简单计算"""
            try:
                # 安全地执行计算
                allowed_chars = set("0123456789+-*/(). ")
                if not all(c in allowed_chars for c in expression):
                    return "请输入有效的数学表达式,只支持加减乘除和括号。"
                
                result = eval(expression)
                return f"计算结果:{expression} = {result}"
            except Exception as e:
                return f"计算错误:{str(e)},请检查表达式格式。"
        
        return perform_calculation
    
    @tool
    def _create_reminder_tool(self):
        """提醒工具"""
        def set_reminder(task: str, time: str) -> str:
            """设置提醒"""
            from datetime import datetime
            
            try:
                # 尝试解析时间
                reminder_time = datetime.strptime(time, "%Y-%m-%d %H:%M")
                current_time = datetime.now()
                
                if reminder_time < current_time:
                    return "提醒时间不能是过去的时间。"
                
                # 这里可以集成到实际的提醒系统
                return f"已设置提醒:在{time}提醒您{task}。"
            except ValueError:
                return "时间格式不正确,请使用'YYYY-MM-DD HH:MM'格式。"
        
        return set_reminder
    
    def invoke(self, 
               user_input: str, 
               user_id: str,
               conversation_history: List[Dict] = None) -> Dict[str, Any]:
        """调用智能体"""
        
        start_time = time.time()
        
        # 准备配置
        config = {
            "configurable": {
                "user_id": user_id,
                "timestamp": datetime.now().isoformat(),
                "session_id": f"session_{int(time.time())}"
            }
        }
        
        # 准备消息
        messages = []
        if conversation_history:
            messages.extend(conversation_history)
        messages.append({"role": "user", "content": user_input})
        
        # 调用智能体
        try:
            response = self.agent.invoke(
                {"messages": messages},
                config=config
            )
            
            # 计算响应时间
            response_time = time.time() - start_time
            
            # 记录交互
            topic = self.prompt_generator._extract_topic(user_input)
            self.user_service.record_interaction(topic, response_time)
            
            # 提取AI回复
            ai_messages = [msg for msg in response["messages"] if msg["role"] == "assistant"]
            last_ai_message = ai_messages[-1] if ai_messages else None
            
            return {
                "success": True,
                "response": last_ai_message["content"] if last_ai_message else "未收到回复",
                "full_conversation": response["messages"],
                "response_time": response_time,
                "tools_used": self._extract_tools_used(response["messages"])
            }
            
        except Exception as e:
            return {
                "success": False,
                "error": str(e),
                "response_time": time.time() - start_time
            }
    
    def _extract_tools_used(self, messages: List[Dict]) -> List[str]:
        """提取使用的工具"""
        tools_used = []
        for msg in messages:
            if msg.get("tool_calls"):
                for tool_call in msg["tool_calls"]:
                    tools_used.append(tool_call["name"])
        return list(set(tools_used))

3. 高级特性:上下文感知与个性化优化

3.1 基于对话历史的动态调整

真正的个性化不仅需要记住用户身份,还需要理解对话的上下文。让我们实现一个更智能的上下文管理系统:

# core/context_manager.py
from typing import List, Dict, Any
from collections import defaultdict
import hashlib

class ConversationContextManager:
    """对话上下文管理器"""
    
    def __init__(self, max_history_length: int = 20):
        self.max_history_length = max_history_length
        self.conversation_memory = defaultdict(list)
    
    def add_message(self, 
                   conversation_id: str, 
                   role: str, 
                   content: str,
                   metadata: Dict[str, Any] = None):
        """添加消息到对话历史"""
        message = {
            "role": role,
            "content": content,
            "timestamp": datetime.now().isoformat(),
            "metadata": metadata or {}
        }
        
        history = self.conversation_memory[conversation_id]
        history.append(message)
        
        # 保持历史长度
        if len(history) > self.max_history_length:
            self.conversation_memory[conversation_id] = history[-self.max_history_length:]
    
    def get_relevant_context(self, 
                            conversation_id: str,
                            current_query: str,
                            max_tokens: int = 1000) -> List[Dict]:
        """获取相关上下文(基于语义相似度)"""
        history = self.conversation_memory.get(conversation_id, [])
        
        if not history:
            return []
        
        # 简单实现:返回最近的消息
        # 实际项目中可以集成向量数据库进行语义搜索
        recent_messages = history[-5:]  # 返回最近5条
        
        # 计算token数量(简化版)
        total_tokens = sum(len(msg["content"].split()) for msg in recent_messages)
        
        if total_tokens > max_tokens:
            # 如果token太多,只返回最近的消息
            return history[-2:]
        
        return recent_messages
    
    def extract_conversation_themes(self, conversation_id: str) -> List[str]:
        """提取对话主题"""
        history = self.conversation_memory.get(conversation_id, [])
        
        if len(history) < 3:
            return ["general"]
        
        # 简单的主题提取逻辑
        themes = []
        content_keywords = defaultdict(int)
        
        for msg in history:
            if msg["role"] == "user":
                words = msg["content"].lower().split()
                for word in words[:10]:  # 只考虑前10个词
                    if len(word) > 2:  # 忽略短词
                        content_keywords[word] += 1
        
        # 找出高频词
        common_words = {"the", "and", "you", "for", "this", "that", "with"}
        top_keywords = [
            word for word, count in sorted(content_keywords.items(), 
                                         key=lambda x: x[1], reverse=True)[:5]
            if word not in common_words
        ]
        
        # 映射到主题
        theme_mapping = {
            "weather": ["天气", "气温", "下雨", "温度"],
            "product": ["产品", "购买", "价格", "订单", "商品"],
            "support": ["帮助", "客服", "问题", "解决", "支持"],
            "technical": ["技术", "代码", "错误", "bug", "开发"]
        }
        
        for keyword in top_keywords:
            for theme, keywords in theme_mapping.items():
                if any(k in keyword for k in keywords):
                    if theme not in themes:
                        themes.append(theme)
        
        return themes if themes else ["general"]
    
    def generate_context_summary(self, conversation_id: str) -> str:
        """生成上下文摘要"""
        themes = self.extract_conversation_themes(conversation_id)
        history = self.conversation_memory.get(conversation_id, [])
        
        if not history:
            return "这是第一次对话。"
        
        # 统计信息
        user_messages = [msg for msg in history if msg["role"] == "user"]
        assistant_messages = [msg for msg in history if msg["role"] == "assistant"]
        
        summary = f"""
## 对话摘要
- 对话主题:{', '.join(themes)}
- 总消息数:{len(history)} 条
- 用户消息:{len(user_messages)} 条
- 助手消息:{len(assistant_messages)} 条
- 最近话题:{self._get_recent_topic(history)}
- 对话情绪:{self._analyze_sentiment(history)}
"""
        return summary
    
    def _get_recent_topic(self, history: List[Dict]) -> str:
        """获取最近话题"""
        if not history:
            return "无"
        
        recent_user_messages = [
            msg["content"] for msg in reversed(history) 
            if msg["role"] == "user"
        ][:3]  # 最近3条用户消息
        
        if not recent_user_messages:
            return "无"
        
        # 简单提取关键词
        all_words = []
        for msg in recent_user_messages:
            words = msg.lower().split()
            all_words.extend([w for w in words if len(w) > 2])
        
        from collections import Counter
        if all_words:
            common_word = Counter(all_words).most_common(1)[0][0]
            return common_word
        
        return "未识别"
    
    def _analyze_sentiment(self, history: List[Dict]) -> str:
        """简单情感分析"""
        # 实际项目中可以集成情感分析模型
        positive_words = {"好", "谢谢", "满意", "优秀", "棒", "赞", "厉害"}
        negative_words = {"不好", "糟糕", "问题", "错误", "失败", "失望"}
        
        positive_count = 0
        negative_count = 0
        
        for msg in history:
            content = msg["content"].lower()
            for word in positive_words:
                if word in content:
                    positive_count += 1
            for word in negative_words:
                if word in content:
                    negative_count += 1
        
        if positive_count > negative_count * 2:
            return "积极"
        elif negative_count > positive_count * 2:
            return "消极"
        else:
            return "中性"

3.2 个性化响应风格调整

不同的用户偏好不同的交流风格。让我们实现一个响应风格调整器:

# core/style_adapter.py
from typing import Dict, Any, List
import re

class ResponseStyleAdapter:
    """响应风格适配器"""
    
    def __init__(self):
        self.style_profiles = {
            "formal": {
                "greeting": ["您好", "尊敬的客户", "很高兴为您服务"],
                "closing": ["祝您愉快", "感谢您的咨询", "期待再次为您服务"],
                "phrases": {
                    "i_dont_know": "抱歉,我暂时无法提供这个信息。建议您联系相关专业人员获取准确解答。",
                    "confirm": "我理解您的需求。",
                    "apology": "对于给您带来的不便,我深表歉意。"
                },
                "formality_level": "high",
                "use_emojis": False,
                "sentence_length": "long"
            },
            "casual": {
                "greeting": ["嗨", "你好呀", "很高兴见到你"],
                "closing": ["拜拜", "下次聊", "有问题随时找我"],
                "phrases": {
                    "i_dont_know": "这个我不太清楚呢,要不你试试问问别人?",
                    "confirm": "明白啦!",
                    "apology": "不好意思哈,这个我没搞明白。"
                },
                "formality_level": "low",
                "use_emojis": True,
                "sentence_length": "short"
            },
            "balanced": {
                "greeting": ["你好", "您好", "很高兴为您服务"],
                "closing": ["祝好", "感谢咨询", "随时联系"],
                "phrases": {
                    "i_dont_know": "这个问题我目前无法准确回答,建议您查阅相关资料或咨询专业人士。",
                    "confirm": "好的,明白了。",
                    "apology": "抱歉,这个问题我暂时无法解决。"
                },
                "formality_level": "medium",
                "use_emojis": False,
                "sentence_length": "medium"
            },
            "technical": {
                "greeting": ["您好", "开始技术支持", "准备分析问题"],
                "closing": ["技术支持结束", "问题已记录", "如需进一步帮助请提供日志"],
                "phrases": {
                    "i_dont_know": "该问题超出当前知识范围,需要更详细的错误日志或系统信息。",
                    "confirm": "确认收到,开始分析。",
                    "apology": "当前无法复现该问题,请提供更多上下文信息。"
                },
                "formality_level": "high",
                "use_emojis": False,
                "sentence_length": "medium",
                "use_technical_terms": True
            }
        }
    
    def adapt_response(self, 
                      response: str, 
                      user_style: str,
                      user_tier: str = "regular") -> str:
        """适配响应风格"""
        
        # 获取样式配置
        style_config = self.style_profiles.get(user_style, self.style_profiles["balanced"])
        
        # 根据用户等级调整
        if user_tier == "vip":
            style_config = self._enhance_for_vip(style_config)
        
        # 应用样式调整
        adapted_response = response
        
        # 调整正式程度
        if style_config["formality_level"] == "high":
            adapted_response = self._make_more_formal(adapted_response)
        elif style_config["formality_level"] == "low":
            adapted_response = self._make_less_formal(adapted_response)
        
        # 调整句子长度
        if style_config["sentence_length"] == "short":
            adapted_response = self._shorten_sentences(adapted_response)
        elif style_config["sentence_length"] == "long":
            adapted_response = self._lengthen_sentences(adapted_response)
        
        # 添加表情符号
        if style_config.get("use_emojis", False):
            adapted_response = self._add_appropriate_emojis(adapted_response)
        
        # 替换特定短语
        for key, replacement in style_config["phrases"].items():
            adapted_response = adapted_response.replace(
                self._get_default_phrase(key), 
                replacement
            )
        
        return adapted_response
    
    def _enhance_for_vip(self, style_config: Dict[str, Any]) -> Dict[str, Any]:
        """为VIP用户增强样式"""
        enhanced = style_config.copy()
        
        # 添加VIP专属问候语
        vip_greetings = ["尊敬的VIP客户", "尊贵的用户", "欢迎您"]
        enhanced["greeting"] = vip_greetings + enhanced.get("greeting", [])
        
        # 添加VIP专属结束语
        vip_closings = ["感谢您一直以来的支持", "期待继续为您提供优质服务"]
        enhanced["closing"] = vip_closings + enhanced.get("closing", [])
        
        # 提高正式程度
        enhanced["formality_level"] = "high"
        
        return enhanced
    
    def _make_more_formal(self, text: str) -> str:
        """使文本更正式"""
        replacements = {
            r"\b我\b": "本人",
            r"\b你\b": "您",
            r"\b咱们\b": "我们",
            r"\b搞\b": "处理",
            r"\b弄\b": "操作",
            r"\b啥\b": "什么",
            r"\b咋\b": "如何",
            r"\b挺\b": "相当",
            r"\b特别\b": "非常",
            r"!": "。",
            r"\?": "?"
        }
        
        for pattern, replacement in replacements.items():
            text = re.sub(pattern, replacement, text)
        
        return text
    
    def _make_less_formal(self, text: str) -> str:
        """使文本更随意"""
        replacements = {
            r"\b本人\b": "我",
            r"\b您\b": "你",
            r"\b我们\b": "咱们",
            r"\b处理\b": "搞",
            r"\b操作\b": "弄",
            r"\b什么\b": "啥",
            r"\b如何\b": "咋",
            r"\b相当\b": "挺",
            r"\b非常\b": "特别",
            r"。": "!",
            r"?": "?"
        }
        
        for pattern, replacement in replacements.items():
            text = re.sub(pattern, replacement, text)
        
        return text
    
    def _shorten_sentences(self, text: str) -> str:
        """缩短句子"""
        # 将长句拆分为短句
        sentences = re.split(r'[。!?]', text)
        short_sentences = []
        
        for sentence in sentences:
            if sentence.strip():
                words = sentence.split()
                if len(words) > 15:
                    # 将长句拆分为两个短句
                    midpoint = len(words) // 2
                    short_sentences.append(' '.join(words[:midpoint]))
                    short_sentences.append(' '.join(words[midpoint:]))
                else:
                    short_sentences.append(sentence)
        
        return '。'.join(short_sentences) + '。'
    
    def _lengthen_sentences(self, text: str) -> str:
        """加长句子(通过添加连接词)"""
        # 实际项目中可以使用更复杂的句子合并逻辑
        connectors = ["此外,", "同时,", "另外,", "值得注意的是,"]
        
        sentences = re.split(r'[。!?]', text)
        if len(sentences) > 1:
            # 在句子间添加连接词
            connected = []
            for i, sentence in enumerate(sentences):
                if sentence.strip():
                    if i > 0 and i <= len(connectors):
                        connected.append(connectors[i-1] + sentence)
                    else:
                        connected.append(sentence)
            text = '。'.join(connected) + '。'
        
        return text
    
    def _add_appropriate_emojis(self, text: str) -> str:
        """添加合适的表情符号"""
        emoji_map = {
            r"谢谢": "🙏",
            r"恭喜": "🎉",
            r"欢迎": "👋",
            r"开心": "😊",
            r"抱歉": "😅",
            r"问题": "❓",
            r"解决": "✅",
            r"错误": "❌",
            r"成功": "🎯",
            r"提醒": "🔔"
        }
        
        for pattern, emoji in emoji_map.items():
            if re.search(pattern, text):
                # 在匹配的词语后添加表情符号
                text = re.sub(f'({pattern})', f'\\1{emoji}', text)
        
        return text
    
    def _get_default_phrase(self, key: str) -> str:
        """获取默认短语"""
        default_phrases = {
            "i_dont_know": "我不知道。",
            "confirm": "好的。",
            "apology": "抱歉。"
        }
        return default_phrases.get(key, "")

3.3 性能优化与缓存策略

对于生产环境,我们需要考虑性能优化。以下是一个带缓存的动态提示词系统:

# core/cached_prompt_generator.py
from typing import Dict, Any, Optional
from functools import lru_cache
import hashlib
import json
from datetime import datetime, timedelta

class CachedPromptGenerator:
    """带缓存的提示词生成器"""
    
    def __init__(self, base_generator, cache_ttl: int = 300):
        self.base_generator = base_generator
        self.cache_ttl = cache_ttl  # 缓存有效期(秒)
        self.cache = {}
    
    def generate_prompt_key(self, 
                           user_context: Dict[str, Any],
                           conversation_state: Dict[str, Any]) -> str:
        """生成缓存键"""
        # 创建可哈希的键
        key_data = {
            "user_id": user_context.get("user_id"),
            "user_tier": user_context.get("user_tier"),
            "formality": user_context.get("preferred_formality"),
            "topics": tuple(user_context.get("known_interests", [])[:3]),
            "conversation_topic": conversation_state.get("topic"),
            "message_count": conversation_state.get("message_count", 0)
        }
        
        # 转换为JSON字符串并哈希
        key_str = json.dumps(key_data, sort_keys=True)
        return hashlib.md5(key_str.encode()).hexdigest()
    
    def is_cache_valid(self, cache_entry: Dict) -> bool:
        """检查缓存是否有效"""
        if not cache_entry:
            return False
        
        timestamp = cache_entry.get("timestamp")
        if not timestamp:
            return False
        
        cache_time = datetime.fromisoformat(timestamp)
        return datetime.now() - cache_time < timedelta(seconds=self.cache_ttl)
    
    @lru_cache(maxsize=100)
    def get_cached_prompt(self, cache_key: str) -> Optional[str]:
        """获取缓存的提示词"""
        cache_entry = self.cache.get(cache_key)
        
        if cache_entry and self.is_cache_valid(cache_entry):
            return cache_entry["prompt"]
        
        return None
    
    def set_cached_prompt(self, cache_key: str, prompt: str):
        """设置缓存"""
        self.cache[cache_key] = {
            "prompt": prompt,
            "timestamp": datetime.now().isoformat(),
            "hits": self.cache.get(cache_key, {}).get("hits", 0) + 1
        }
        
        # 清理过期缓存
        self._clean_expired_cache()
    
    def _clean_expired_cache(self):
        """清理过期缓存"""
        current_time = datetime.now()
        expired_keys = []
        
        for key, entry in self.cache.items():
            cache_time = datetime.fromisoformat(entry["timestamp"])
            if current_time - cache_time > timedelta(seconds=self.cache_ttl):
                expired_keys.append(key)
        
        for key in expired_keys:
            del self.cache[key]
    
    def generate_system_prompt(self, 
                             user_context: Dict[str, Any],
                             conversation_state: Dict[str, Any]) -> str:
        """生成系统提示词(带缓存)"""
        
        # 生成缓存键
        cache_key = self.generate_prompt_key(user_context, conversation_state)
        
        # 尝试从缓存获取
        cached_prompt = self.get_cached_prompt(cache_key)
        if cached_prompt:
            return cached_prompt
        
        # 缓存未命中,生成新提示词
        prompt = self.base_generator.generate_system_prompt(
            user_context, conversation_state
        )
        
        # 存入缓存
        self.set_cached_prompt(cache_key, prompt)
        
        return prompt
    
    def get_cache_stats(self) -> Dict[str, Any]:
        """获取缓存统计信息"""
        total_entries = len(self.cache)
        hit_count = sum(entry.get("hits", 0) for entry in self.cache.values())
        
        # 计算命中率(基于历史数据)
        total_accesses = hit_count + total_entries  # 简化计算
        hit_rate = hit_count / total_accesses if total_accesses > 0 else 0
        
        return {
            "total_entries": total_entries,
            "hit_count": hit_count,
            "estimated_hit_rate": f"{hit_rate:.2%}",
            "cache_size_mb": self._estimate_cache_size(),
            "oldest_entry": self._get_oldest_entry_age()
        }
    
    def _estimate_cache_size(self) -> float:
        """估算缓存大小(MB)"""
        total_size = 0
        for entry in self.cache.values():
            total_size += len(json.dumps(entry).encode('utf-8'))
        return total_size / (1024 * 1024)  # 转换为MB
    
    def _get_oldest_entry_age(self) -> str:
        """获取最旧缓存条目的年龄"""
        if not self.cache:
            return "无缓存"
        
        oldest_time = None
        for entry in self.cache.values():
            cache_time = datetime.fromisoformat(entry["timestamp"])
            if oldest_time is None or cache_time < oldest_time:
                oldest_time = cache_time
        
        if oldest_time:
            age = datetime.now() - oldest_time
            return f"{age.total_seconds():.0f}秒"
        
        return "未知"

4. 部署与监控:生产环境的最佳实践

4.1 配置管理与环境变量

在生产环境中,配置管理至关重要。让我们创建一个完整的配置系统:

# config/production_config.py
import os
from typing import Dict, Any, Optional
from pydantic import BaseSettings, Field, validator
from enum import Enum

class Environment(str, Enum):
    DEVELOPMENT = "development"
    TESTING = "testing"
    STAGING = "staging"
    PRODUCTION = "production"

class ModelProvider(str, Enum):
    TONGYI = "tongyi"
    OPENAI = "openai"
    ANTHROPIC = "anthropic"
    LOCAL = "local"

class CacheConfig(BaseSettings):
    """缓存配置"""
    enabled: bool = Field(True, description="是否启用缓存")
    ttl_seconds: int = Field(300, description="缓存有效期(秒)")
    max_size_mb: int = Field(100, description="最大缓存大小(MB)")
    redis_url: Optional[str] = Field(None, description="Redis连接URL")
    
    @validator("redis_url")
    def validate_redis_url(cls, v, values):
        if values.get("enabled") and not v:
            raise ValueError("启用缓存时必须提供Redis URL")
        return v

class ModelConfig(BaseSettings):
    """模型配置"""
    provider: ModelProvider = Field(ModelProvider.TONGYI, description="模型提供商")
    model_name: str = Field("qwen-turbo", description="模型名称")
    temperature: float = Field(0.1, ge=0.0, le=2.0, description="温度参数")
    max_tokens: Optional[int] = Field(2000, description="最大token数")
    timeout_seconds: int = Field(30, description="请求超时时间")
    max_retries: int = Field(3, description="最大重试次数")
    
    # 提供商特定配置
    api_key: Optional[str] = Field(None, description="API密钥")
    api_base: Optional[str] = Field(None, description="API基础URL")
    
    class Config:
        env_prefix = "MODEL_"

class MonitoringConfig(BaseSettings):
    """监控配置"""
    enabled: bool = Field(True, description="是否启用监控")
    metrics_port: int = Field(9090, description="指标端口")
    log_level: str = Field("INFO", description="日志级别")
    enable_tracing: bool = Field(False, description="是否启用分布式追踪")
    tracing_endpoint: Optional[str] = Field(None, description="追踪端点")
    
    # 性能阈值
    max_response_time_ms: int = Field(5000, description="最大响应时间(毫秒)")
    error_rate_threshold: float = Field(0.01, description="错误率阈值")
    
    class Config:
        env_prefix = "MONITORING_"

class ProductionConfig(BaseSettings):
    """生产环境配置"""
    
    # 环境设置
    environment: Environment = Field(Environment.PRODUCTION, description="运行环境")
    debug: bool = Field(False, description="调试模式")
    
    # 组件配置
    model: ModelConfig = ModelConfig()
    cache: CacheConfig = CacheConfig()
    monitoring: MonitoringConfig = MonitoringConfig()
    
    # 应用配置
    app_name: str = Field("个性化AI助手", description="应用名称")
    version: str = Field("1.0.0", description="应用版本")
    host: str = Field("0.0.0.0", description="监听主机")
    port: int = Field(8000, description="监听端口")
    
    # 安全配置
    api_key_header: str = Field("X-API-Key", description="API密钥头")
    rate_limit_per_minute: int = Field(60, description="每分钟请求限制")
    
    # 数据库配置
    database_url: Optional[str] = Field(None, description="数据库URL")
    
    class Config:
        env_file = ".env"
        env_file_encoding = "utf-8"
        case_sensitive = False
    
    @validator("database_url")
    def validate_database_url(cls, v, values):
        if values.get("environment") == Environment.PRODUCTION and not v:
            raise ValueError("生产环境必须配置数据库URL")
        return v
    
    def get_model_config(self) -> Dict[str, Any]:
        """获取模型配置字典"""
        config = {
            "provider": self.model.provider.value,
            "model_name": self.model.model_name,
            "temperature": self.model.temperature,
            "max_tokens": self.model.max_tokens,
            "timeout": self.model.timeout_seconds,
            "max_retries": self.model.max_retries,
        }
        
        # 添加提供商特定配置
        if self.model.api_key:
            config["api_key"] = self.model.api_key
        if self.model.api_base:
            config["api_base"] = self.model.api_base
        
        return config

# 创建配置实例
config = ProductionConfig()

# 环境特定的配置覆盖
if config.environment == Environment.DEVELOPMENT:
    config.debug = True
    config.monitoring.log_level = "DEBUG"
elif config.environment == Environment.TESTING:
    config.model.temperature = 0.0  # 测试时使用确定性输出
elif config.environment == Environment.PRODUCTION:
    # 生产环境强制要求API密钥
    if not config.model.api_key:
        raise ValueError("生产环境必须设置模型API密钥")

4.2 性能监控与日志记录

为了确保系统稳定运行,我们需要实现全面的监控和日志:

# core/monitoring.py
import time
import logging
from typing import Dict, Any, Optional, Callable
from functools import wraps
from datetime import datetime
import statistics
from collections import defaultdict

class PerformanceMonitor:
    """性能监控器"""
    
    def __init__(self):
        self.metrics = defaultdict(list)
        self.start_time = time.time()
        
        # 设置日志
        self.logger = logging.getLogger("performance")
        self.logger.setLevel(logging.INFO)
        
        # 添加控制台处理器
        if not self.logger.handlers:
            handler = logging.StreamHandler()
            formatter = logging.Formatter(
                '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
            )
            handler.setFormatter(formatter)
            self.logger.addHandler(handler)
    
    def record_metric(self, name: str, value: float, tags: Dict[str, str] = None):
        """记录指标"""
        key = name
        if tags:
            # 将标签转换为字符串键
            tag_str = ",".join(f"{k}={v}" for k, v in sorted(tags.items()))
            key = f"{name}[{tag_str}]"
        
        self.metrics[key].append({
            "value": value,
            "timestamp": datetime.now().isoformat(),
            "tags": tags or {}
        })
        
        # 保持最近1000个数据点
        if len(self.metrics[key]) > 1000:
            self.metrics[key] = self.metrics[key][-1000:]
    
    def get_statistics(self, name: str, tags: Dict[str, str] = None) -> Dict[str, float]:
        """获取统计信息"""
        key = name
        if tags:
            tag_str = ",".join(f"{k}={v}" for k, v in sorted(tags.items()))
            key = f"{name}[{tag_str}]"
        
        values = [m["value"] for m in self.metrics.get(key, [])]
        
        if not values:
            return {}
        
        return {
            "count": len(values),
            "mean": statistics.mean(values),
            "median": statistics.median(values),
            "min": min(values),
            "max": max(values),
            "p95": statistics.quantiles(values, n=20)[18],  # 95th percentile
            "p99": statistics.quantiles(values, n=100)[98],  # 99th percentile
            "std_dev": statistics.stdev(values) if len(values) > 1 else 0
        }
    
    def monitor_function(self, metric_name: str):
        """函数性能监控装饰器"""
        def decorator(func: Callable):
            @wraps(func)
            def wrapper(*args, **kwargs):
                start_time = time.time()
                try:
                    result = func(*args, **kwargs)
                    duration = (time.time() - start_time) * 1000  # 转换为毫秒
                    
                    # 记录成功指标
                    self.record_metric(
                        f"{metric_name}.duration",
                        duration,
                        {"status": "success"}
                    )
                    self.record_metric(
                        f"{metric_name}.success_count",
                        1,
                        {"status": "success"}
                    )
                    
                    return result
                except Exception as e:
                    duration = (time.time() - start_time) * 1000
                    
                    # 记录失败指标
                    self.record_metric(
                        f"{metric_name}.duration",
                        duration,
                        {"status": "error", "error_type": type(e).__name__}
                    )
                    self.record_metric(
                        f"{metric_name}.error_count",
                        1,
                        {"status": "error", "error_type": type(e).__name__}
                    )
                    
                    # 记录错误日志
                    self.logger.error(
                        f"Function {func.__name__} failed after {duration:.2f}ms: {str(e)}",
                        exc_info=True
                    )
                    
                    raise
            
            return wrapper
        return decorator
    
    def generate_report(self) -> Dict[str, Any]:
        """生成性能报告"""
        report = {
            "timestamp": datetime.now().isoformat(),
            "uptime_seconds": time.time() - self.start_time,
            "metrics": {}
        }
        
        # 计算所有指标的统计信息
        for metric_name in self.metrics.keys():
            # 提取基础指标名(去掉标签)
            base_name = metric_name.split('[')[0] if '[' in metric_name else metric_name
            
            if base_name not in report["metrics"]:
                report["metrics"][base_name] = {
                    "total_count": 0,
                    "success_rate": 0,
                    "average_duration_ms": 0,
                    "breakdown": {}
                }
            
            # 获取该指标的所有变体(不同标签)
            variants = [k for k in self.metrics.keys() if k.startswith(base_name)]
            
            for variant in variants:
                stats = self.get_statistics(variant)
                if stats:
                    report["metrics"][base_name]["breakdown"][variant] = stats
                    
                    # 更新总计
                    if "duration" in base_name:
                        report["metrics"][base_name]["average_duration_ms"] = stats.get("mean", 0)
                    elif "count" in base_name:
                        report["metrics"][base_name]["total_count"] = stats.get("count", 0)
        
        # 计算成功率
        for metric_name, data in report["metrics"].items():
            if "success_count" in metric_name or "error_count" in metric_name:
                success_key = f"{metric_name}.success_count"
                error_key = f"{metric_name}.error_count"
                
                success_stats = self.get_statistics(success_key) if success_key in self.metrics else {}
                error_stats = self.get_statistics(error_key) if error_key in self.metrics else {}
                
                success_count = success_stats.get("count", 0)
                error_count = error_stats.get("count", 0)
                total = success_count + error_count
                
                if total > 0:
                    data["success_rate"] = success_count / total
        
        return report
    
    def check_alerts(self, thresholds: Dict[str, float]) -> Dict[str, bool]:
        """检查警报阈值"""
        alerts = {}
        
        for metric_name, threshold in thresholds.items():
            stats = self.get_statistics(metric_name)
            
            if not stats:
                continue
            
            # 检查平均响应时间
            if "duration" in metric_name and "mean" in stats:
                if stats["mean"] > threshold:
                    alerts[metric_name] = {
                        "triggered": True,
                        "value": stats["mean"],
                        "threshold": threshold,
                        "message": f"{metric_name}平均响应时间{stats['mean']:.2f}ms超过阈值{threshold}ms"
                    }
            
            # 检查错误率
            elif "error_rate" in metric_name:
                success_key = metric_name.replace("error_rate", "success_count")
                error_key = metric_name.replace("error_rate", "error_count")
                
                success_stats = self.get_statistics(success_key) if success_key in self.metrics else {}
                error_stats = self.get_statistics(error_key) if error_key in self.metrics else {}
                
                success_count = success_stats.get("count", 0)
                error_count = error_stats.get("count", 0)
                total = success_count + error_count
                
                if total > 0:
                    error_rate = error_count / total
                    if error_rate > threshold:
                        alerts[metric_name] = {
                            "triggered": True,
                            "value": error_rate,
                            "threshold": threshold,
                            "message": f"{metric_name}错误率{error_rate:.2%}超过阈值{threshold:.2%}"
                        }
        
        return alerts

# 使用示例
monitor = PerformanceMonitor()

@monitor.monitor_function("prompt_generation")
def generate_prompt_with_monitoring(user_context, conversation_state):
    """带监控的提示词生成函数"""
    # 实际生成逻辑
    time.sleep(0.1)  # 模拟处理时间
    return "生成的提示词"

# 记录自定义指标
monitor.record_metric("user_session.count", 1, {"user_tier": "vip"})
monitor.record_metric("api_request.duration", 150.5, {"endpoint": "/chat"})

# 获取报告
report = monitor.generate_report()
alerts = monitor.check_alerts({
    "prompt_generation.duration": 1000,  # 1秒阈值
    "api_request.duration": 500,  # 500毫秒阈值
    "error_rate": 0.05  # 5%错误率阈值
})

4.3 部署配置与健康检查

最后,让我们创建一个完整的部署配置和健康检查系统:

# deployment/deploy.py
import uvicorn
from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.trustedhost import TrustedHostMiddleware
from contextlib import asynccontextmanager
from typing import Dict, Any, List
import asyncio
from datetime import datetime
import json

from config.production_config import config, Environment
from core.agents import PersonalizedAssistant
from core.prompts import DynamicPromptGenerator
from services.user_service import UserProfile
from core.monitoring import PerformanceMonitor

class HealthCheck:
    """健康检查系统"""
    
    def __init__(self):
        self.checks = {}
        self.last_check = {}
    
    def register_check(self, name: str, check_func: callable, interval_seconds: int = 30):
        """注册健康检查"""
        self.checks[name] = {
            "function": check_func,
            "interval": interval_seconds,
            "last_run": None,
            "status": "unknown",
            "details": {}
        }
    
    async def run_checks(self) -> Dict[str, Any]:
        """运行所有健康检查"""
        results = {
            "timestamp": datetime.now().isoformat(),
            "status": "healthy",
            "checks": {}
        }
        
        for name, check_info in self.checks.items():
            try:
                # 检查是否需要运行
                should_run = (
                    check_info["last_run"] is None or
                    (datetime.now() - check_info["last_run"]).total_seconds() > check_info["interval"]
                )
                
                if should_run:
                    check_result = await check_info["function"]()
                    check_info["status"] = check_result.get("status", "unknown")
                    check_info["details"] = check_result.get("details", {})
                    check_info["last_run"] = datetime.now()
                
                results["checks"][name] = {
                    "status": check_info["status"],
                    "details": check_info["details"],
                    "last_run": check_info["last_run"].isoformat() if check_info["last_run"] else None
                }
                
                if check_info["status"] != "healthy":
                    results["status"] = "unhealthy"
                    
            except Exception as e:
                results["checks"][name] = {
                    "status": "error",
                    "details": {"error": str(e)},
                    "last_run": datetime.now().isoformat()
                }
                results["status"] = "unhealthy"
        
        return results

# 创建健康检查实例
health_check = HealthCheck()

# 定义健康检查函数
async def check_database():
    """检查数据库连接"""
    # 实际项目中实现数据库连接检查
    return {"status": "healthy", "details": {"connection": "ok"}}

async def check_model_api():
    """检查模型API可用性"""
    # 实际项目中实现模型API检查
    return {"status": "healthy", "details": {"api_status": "available"}}

async def check_cache():
    """检查缓存系统"""
    # 实际项目中实现缓存检查
    return {"status": "healthy", "details": {"cache_hit_rate": "95%"}}

# 注册健康检查
health_check.register_check("database", check_database, interval_seconds=60)
health_check.register_check("model_api", check_model_api, interval_seconds=30)
health_check.register_check("cache", check_cache, interval_seconds=45)

@asynccontextmanager
async def lifespan(app: FastAPI):
    """应用生命周期管理"""
    # 启动时初始化
    print("启动个性化AI助手服务...")
    
    # 初始化组件
    app.state.user_service = UserProfile
    app.state.prompt_generator = DynamicPromptGenerator(app.state.user_service)
    app.state.assistant = PersonalizedAssistant(
        prompt_generator=app.state.prompt_generator,
        user_service=app.state.user_service
    )
    app.state.monitor = PerformanceMonitor()
    
    # 启动健康检查任务
    app.state.health_task = asyncio.create_task(health_check_loop())
    
    yield
    
    # 关闭时清理
    print("关闭个性化AI助手服务...")
    app.state.health_task.cancel()
    try:
        await app.state.health_task
    except asyncio.CancelledError:
        pass

async def health_check_loop():
    """健康检查循环"""
    while True:
        try:
            await asyncio.sleep(30)  # 每30秒检查一次
            await health_check.run_checks()
        except asyncio.CancelledError:
            break
        except Exception as e:
            print(f"健康检查错误: {e}")

# 创建FastAPI应用
app = FastAPI(
    title=config.app_name,
    version=config.ve
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐