From 84743420075a94b05a46c5a27043d428fb19a99c Mon Sep 17 00:00:00 2001 From: jxxghp Date: Sat, 24 Jan 2026 11:24:59 +0800 Subject: [PATCH] =?UTF-8?q?feat(agent)=EF=BC=9A=E4=B8=8A=E4=B8=8B=E6=96=87?= =?UTF-8?q?=E8=B6=85=E9=95=BF=E6=97=B6=E8=87=AA=E5=8A=A8=E6=91=98=E8=A6=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/agent/__init__.py | 70 +++++++++++++++++++++++++++++++++++++++++++ app/chain/message.py | 6 ++-- 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/app/agent/__init__.py b/app/agent/__init__.py index c341120b..2a56993f 100644 --- a/app/agent/__init__.py +++ b/app/agent/__init__.py @@ -249,11 +249,81 @@ class MoviePilotAgent: logger.error(f"创建Agent执行器失败: {e}") raise e + async def _summarize_history(self): + """ + 总结提炼之前的对话和工具执行情况,并把会话总结变成新的系统提示词取代之前的对话 + """ + try: + # 获取当前历史记录 + chat_history = self.get_session_history(self.session_id) + messages = chat_history.messages + if not messages: + return + + logger.info(f"会话 {self.session_id} 历史消息长度已超过 90%,开始总结并重置上下文...") + + # 将消息转换为摘要所需的文本格式 + history_text = "" + for msg in messages: + if isinstance(msg, HumanMessage): + history_text += f"用户: {msg.content}\n" + elif isinstance(msg, AIMessage): + history_text += f"智能体: {msg.content}\n" + if getattr(msg, "tool_calls", None): + for tool_call in msg.tool_calls: + history_text += f"智能体调用工具: {tool_call.get('name')},参数: {tool_call.get('args')}\n" + elif isinstance(msg, ToolMessage): + history_text += f"工具响应: {msg.content}\n" + elif isinstance(msg, SystemMessage): + history_text += f"系统: {msg.content}\n" + + # 摘要提示词 + summary_prompt = ( + "Please provide a comprehensive and highly informational summary of the preceding conversation and tool executions. " + "Your goal is to condense the history while retaining all critical details for future reference. " + "Ensure you include:\n" + "1. User's core intents, specific requests, and any mentioned preferences.\n" + "2. Names of movies, TV shows, or other key entities discussed.\n" + "3. A concise log of tool calls made and their specific results/outcomes.\n" + "4. The current status of any tasks and any pending actions.\n" + "5. Any important context that would be necessary for the agent to continue the conversation seamlessly.\n" + "The summary should be dense with information and serve as the primary context for the next stage of the interaction." + ) + + # 调用 LLM 进行总结 (非流式) + summary_llm = LLMHelper.get_llm(streaming=False) + response = await summary_llm.ainvoke([ + SystemMessage(content=summary_prompt), + HumanMessage(content=f"Here is the conversation history to summarize:\n{history_text}") + ]) + summary_content = str(response.content) + + if not summary_content: + logger.warning("总结生成失败,跳过重置逻辑。") + return + + # 清空原有的会话记录并插入新的系统总结 + await conversation_manager.clear_memory(self.session_id, self.user_id) + await conversation_manager.add_conversation( + session_id=self.session_id, + user_id=self.user_id, + role="system", + content=f"\n{summary_content}\n" + ) + logger.info(f"会话 {self.session_id} 历史摘要替换完成。") + except Exception as e: + logger.error(f"执行会话总结出错: {str(e)}") + async def process_message(self, message: str) -> str: """ 处理用户消息 """ try: + # 检查上下文长度是否超过 90% + history = self.get_session_history(self.session_id) + if self._token_counter(history.messages) > settings.LLM_MAX_CONTEXT_TOKENS * 1000 * 0.9: + await self._summarize_history() + # 添加用户消息到记忆 await conversation_manager.add_conversation( self.session_id, diff --git a/app/chain/message.py b/app/chain/message.py index 2396f1cd..847b2732 100644 --- a/app/chain/message.py +++ b/app/chain/message.py @@ -40,7 +40,7 @@ class MessageChain(ChainBase): # 用户会话信息 {userid: (session_id, last_time)} _user_sessions: Dict[Union[str, int], tuple] = {} # 会话超时时间(分钟) - _session_timeout_minutes: int = 15 + _session_timeout_minutes: int = 30 @staticmethod def __get_noexits_info( @@ -856,8 +856,8 @@ class MessageChain(ChainBase): # 计算时间差 time_diff = current_time - last_time - # 如果时间差小于等于15分钟,复用会话ID - if time_diff <= timedelta(minutes=MessageChain._session_timeout_minutes): + # 如果时间差小于等于xx分钟,复用会话ID + if time_diff <= timedelta(minutes=self._session_timeout_minutes): # 更新最后使用时间 self._user_sessions[userid] = (session_id, current_time) logger.info(