From 5134c0d8a6d5bbfe4f878a17fd82dd8fba59b470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E6=BD=AE?= Date: Sun, 25 Jan 2026 21:46:02 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=8E=AF=E5=A2=83=E5=8F=98?= =?UTF-8?q?=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- agent/agent_config.py | 20 ++++++++++++++++++++ agent/deep_assistant.py | 20 +++++++++++++++----- agent/prompt_loader.py | 16 +++++++++------- prompt/system_prompt_deep_agent.md | 2 +- 4 files changed, 45 insertions(+), 13 deletions(-) diff --git a/agent/agent_config.py b/agent/agent_config.py index 16c4374..31e2111 100644 --- a/agent/agent_config.py +++ b/agent/agent_config.py @@ -31,6 +31,7 @@ class AgentConfig: user_identifier: Optional[str] = None session_id: Optional[str] = None dataset_ids: Optional[List[str]] = field(default_factory=list) + trace_id: Optional[str] = None # 请求追踪ID,从 X-Request-ID header 获取 # 响应控制参数 stream: bool = False @@ -72,6 +73,7 @@ class AgentConfig: 'messages': self.messages, 'enable_memori': self.enable_memori, 'memori_semantic_search_top_k': self.memori_semantic_search_top_k, + 'trace_id': self.trace_id, } def safe_print(self): @@ -93,10 +95,18 @@ class AgentConfig: ) from .checkpoint_utils import prepare_checkpoint_message from .checkpoint_manager import get_checkpointer_manager + from utils.log_util.context import g if messages is None: messages = [] + # 从全局上下文获取 trace_id + trace_id = None + try: + trace_id = getattr(g, 'trace_id', None) + except LookupError: + pass + robot_type = request.robot_type if robot_type == "catalog_agent": robot_type = "deep_agent" @@ -130,6 +140,7 @@ class AgentConfig: dataset_ids=request.dataset_ids, enable_memori=enable_memori, memori_semantic_search_top_k=getattr(request, 'memori_semantic_search_top_k', None) or MEM0_SEMANTIC_SEARCH_TOP_K, + trace_id=trace_id, ) # 在创建 config 时尽早准备 checkpoint 消息 @@ -158,9 +169,17 @@ class AgentConfig: ) from .checkpoint_utils import prepare_checkpoint_message from .checkpoint_manager import get_checkpointer_manager + from utils.log_util.context import g if messages is None: messages = [] + + # 从全局上下文获取 trace_id + trace_id = None + try: + trace_id = getattr(g, 'trace_id', None) + except LookupError: + pass language = request.language or bot_config.get("language", "zh") preamble_text, system_prompt = get_preamble_text(language, bot_config.get("system_prompt")) robot_type = bot_config.get("robot_type", "general_agent") @@ -194,6 +213,7 @@ class AgentConfig: dataset_ids=bot_config.get("dataset_ids", []), # 从后端配置获取dataset_ids enable_memori=enable_memori, memori_semantic_search_top_k=bot_config.get("memori_semantic_search_top_k", MEM0_SEMANTIC_SEARCH_TOP_K), + trace_id=trace_id, ) # 在创建 config 时尽早准备 checkpoint 消息 diff --git a/agent/deep_assistant.py b/agent/deep_assistant.py index 800bc3d..5082d2a 100644 --- a/agent/deep_assistant.py +++ b/agent/deep_assistant.py @@ -137,7 +137,7 @@ async def init_agent(config: AgentConfig): # 加载配置 final_system_prompt = await load_system_prompt_async( - config.project_dir, config.language, config.system_prompt, config.robot_type, config.bot_id, config.user_identifier + config.project_dir, config.language, config.system_prompt, config.robot_type, config.bot_id, config.user_identifier, config.trace_id or "" ) final_mcp_settings = await load_mcp_settings_async( config.project_dir, config.mcp_settings, config.bot_id, config.robot_type @@ -240,7 +240,11 @@ async def init_agent(config: AgentConfig): enable_memory=False, workspace_root=workspace_root, middleware=middleware, - checkpointer=checkpointer + checkpointer=checkpointer, + shell_env={ + "ASSISTANT_ID": config.bot_id, + "TRACE_ID": config.trace_id + } ) else: # 只有在 enable_thinking 为 True 时才添加 GuidelineMiddleware @@ -369,6 +373,7 @@ def create_custom_cli_agent( workspace_root: str | None = None, checkpointer: Checkpointer | None = None, store: BaseStore | None = None, + shell_env: dict[str, str] | None = None, ) -> tuple[Pregel, CompositeBackend]: """Create a CLI-configured agent with custom workspace_root for shell commands. @@ -393,6 +398,8 @@ def create_custom_cli_agent( workspace_root: Working directory for shell commands. If None, uses Path.cwd(). checkpointer: Optional checkpointer for persisting conversation state store: Optional BaseStore for persisting user preferences and agent memory + shell_env: Optional custom environment variables to pass to ShellMiddleware. + These will be merged with os.environ. Custom vars take precedence. Returns: 2-tuple of (agent_graph, composite_backend) @@ -440,15 +447,18 @@ def create_custom_cli_agent( # Add shell middleware (only in local mode) if enable_shell: # Create environment for shell commands - # Restore user's original LANGSMITH_PROJECT so their code traces separately - shell_env = os.environ.copy() + # Start with a copy of current environment + final_shell_env = os.environ.copy() + # Merge custom environment variables if provided (custom vars take precedence) + if shell_env: + final_shell_env.update(shell_env) # Use custom workspace_root if provided, otherwise use current directory shell_workspace = workspace_root if workspace_root is not None else str(Path.cwd()) agent_middleware.append( ShellMiddleware( workspace_root=shell_workspace, - env=shell_env, + env=final_shell_env, ) ) else: diff --git a/agent/prompt_loader.py b/agent/prompt_loader.py index 09c8bef..e9ac699 100644 --- a/agent/prompt_loader.py +++ b/agent/prompt_loader.py @@ -69,9 +69,9 @@ def format_datetime_by_language(language: str) -> str: return utc_now.strftime("%Y-%m-%d %H:%M:%S") + " UTC" -async def load_system_prompt_async(project_dir: str, language: str = None, system_prompt: str=None, robot_type: str = "general_agent", bot_id: str="", user_identifier: str = "") -> str: +async def load_system_prompt_async(project_dir: str, language: str = None, system_prompt: str=None, robot_type: str = "general_agent", bot_id: str="", user_identifier: str = "", trace_id: str = "") -> str: """异步版本的系统prompt加载 - + Args: project_dir: 项目目录路径,可以为None language: 语言代码,如 'zh', 'en', 'jp' 等 @@ -79,7 +79,8 @@ async def load_system_prompt_async(project_dir: str, language: str = None, syste robot_type: 机器人类型,取值 agent/catalog_agent bot_id: 机器人ID user_identifier: 用户标识符 - + trace_id: 请求追踪ID,用于日志追踪 + Returns: str: 加载到的系统提示词内容 """ @@ -122,12 +123,13 @@ async def load_system_prompt_async(project_dir: str, language: str = None, syste # agent_dir_path = f"~/.deepagents/{bot_id}" #agent_dir_path 其实映射的就是 project_dir目录,只是给ai看的目录路径 prompt = system_prompt_default.format( - readme=str(readme), + readme=str(readme), extra_prompt=system_prompt or "", - language=language_display, - user_identifier=user_identifier, + language=language_display, + user_identifier=user_identifier, datetime=datetime_str, - agent_dir_path="." + agent_dir_path=".", + trace_id=trace_id or "" ) elif system_prompt: prompt = system_prompt.format(language=language_display, user_identifier=user_identifier, datetime=datetime_str) diff --git a/prompt/system_prompt_deep_agent.md b/prompt/system_prompt_deep_agent.md index a6119fa..26b709f 100644 --- a/prompt/system_prompt_deep_agent.md +++ b/prompt/system_prompt_deep_agent.md @@ -47,7 +47,7 @@ When executing scripts from SKILL.md files, you MUST convert relative paths to a - **`{agent_dir_path}/skills/`** - Skill packages with embedded scripts - **`{agent_dir_path}/dataset/`** - Store file datasets and document data -- **`{agent_dir_path}/scripts/`** - Place generated executable scripts here (not skill scripts) +- **`{agent_dir_path}/executable_code/`** - Place generated executable scripts here (not skill scripts) - **`{agent_dir_path}/download/`** - Store downloaded files and content **Path Examples:**