From 8d7ff2bd1dd9468345d98b80233d46ee85eae203 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Fri, 27 Mar 2026 20:12:01 +0800 Subject: [PATCH] =?UTF-8?q?feat(agent):=20=E6=96=B0=E5=A2=9EAI=5FAGENT=5FV?= =?UTF-8?q?ERBOSE=E5=BC=80=E5=85=B3=EF=BC=8C=E6=8E=A7=E5=88=B6=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E8=B0=83=E7=94=A8=E8=BF=87=E7=A8=8B=E5=9B=9E=E5=A4=8D?= =?UTF-8?q?=E5=8F=8A=E6=8F=90=E7=A4=BA=E8=AF=8D=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/agent/__init__.py | 8 +++++--- app/agent/prompt/__init__.py | 9 +++++++++ app/agent/tools/base.py | 3 ++- app/core/config.py | 2 ++ 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/app/agent/__init__.py b/app/agent/__init__.py index e1c66c68..6c438580 100644 --- a/app/agent/__init__.py +++ b/app/agent/__init__.py @@ -81,19 +81,21 @@ class MoviePilotAgent: """ if not content: return "" - if isinstance(content, str): - return content + # 跳过思考/推理类型的内容块 if isinstance(content, list): text_parts = [] for block in content: if isinstance(block, str): text_parts.append(block) elif isinstance(block, dict): - # 跳过思考/推理类型的内容块 + # 优先检查 thought 标志(LangChain Google GenAI 方案) + if block.get("thought"): + continue if block.get("type") in ( "thinking", "reasoning_content", "reasoning", + "thought", ): continue if block.get("type") == "text": diff --git a/app/agent/prompt/__init__.py b/app/agent/prompt/__init__.py index 38a3d369..3859791c 100644 --- a/app/agent/prompt/__init__.py +++ b/app/agent/prompt/__init__.py @@ -3,6 +3,7 @@ from pathlib import Path from typing import Dict +from app.core.config import settings from app.log import logger from app.schemas import ( ChannelCapability, @@ -73,6 +74,14 @@ class PromptManager: # 始终替换占位符,避免后续 .format() 时因残留花括号报 KeyError base_prompt = base_prompt.replace("{markdown_spec}", markdown_spec) + # 据 VERBOSE 开关动态调整提示词:关闭时要求避免工具调用前的废话 + if not settings.AI_AGENT_VERBOSE: + base_prompt += ( + "\n\n[Important Instruction] If you need to call a tool, DO NOT output any conversational " + "text or explanations before calling the tool. Call the tool directly without transitional " + "phrases like 'Let me check', 'I will look this up', etc." + ) + return base_prompt @staticmethod diff --git a/app/agent/tools/base.py b/app/agent/tools/base.py index 6413f2ef..791b33b6 100644 --- a/app/agent/tools/base.py +++ b/app/agent/tools/base.py @@ -7,6 +7,7 @@ from pydantic import PrivateAttr from app.agent import StreamingHandler from app.chain import ChainBase +from app.core.config import settings from app.log import logger from app.schemas import Notification @@ -53,7 +54,7 @@ class MoviePilotTool(BaseTool, metaclass=ABCMeta): if explanation: tool_message = explanation - if not is_background: + if not is_background and settings.AI_AGENT_VERBOSE: # 非后台模式:发送工具执行过程消息 if self._stream_handler and self._stream_handler.is_streaming: # 流式渠道:工具消息直接追加到 buffer 中,与 Agent 文字合并为同一条流式消息 diff --git a/app/core/config.py b/app/core/config.py index ab904648..cabb04c5 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -531,6 +531,8 @@ class ConfigModel(BaseModel): LLM_MAX_TOOLS: int = 0 # AI智能体定时任务检查间隔(小时),0为不启用,默认24小时 AI_AGENT_JOB_INTERVAL: int = 0 + # AI智能体啰嗦模式,开启后会回复工具调用过程 + AI_AGENT_VERBOSE: bool = False class Settings(BaseSettings, ConfigModel, LogConfigModel):