1+ """Agent 创建模块。"""
2+
3+ import os
4+ from deepagents import create_deep_agent
5+ from deepagents .middleware .skills import SkillsMiddleware
6+ from langgraph .checkpoint .mysql .aio import AIOMySQLSaver
7+ from langgraph .store .base import BaseStore
8+ from app .loader import SubAgentLoader
9+ from app .tools .common import common_tools
10+ from app .tools .skill_management import skill_tools
11+ from app .tools .scheduler_tools import scheduler_tools
12+ from app .backend_factory import create_backend
13+ from app .middleware import ToolErrorHandlerMiddleware
14+ from app .log_utils import get_logger
15+ from app .llm_config import get_default_model
16+
17+ logger = get_logger ("agent" )
18+
19+ MAIN_SYSTEM_PROMPT = """
20+ 你是 GitHub 开源情报系统的总指挥。
21+
22+ ## 职责
23+
24+ 1. 接收用户指令,首先回复确认已收到请求
25+ 2. 使用 write_todos 规划任务
26+ 3. **必须**使用 task 工具委托子Agent执行具体分析
27+ 4. 汇总结果生成报告,使用 return_report_for_download 工具返回报告
28+ 5. **支持创建定时任务**:用户请求定时扫描时,使用 create_scheduled_task 工具
29+
30+ ## 核心原则 - 必须遵守
31+
32+ - **分析任务必须使用 task 工具委派子Agent处理**
33+ - **所有子Agent工具都支持单仓库和多仓库**
34+ - **参数格式统一:repos="owner/repo" 或 repos="owner/repo1,owner/repo2"**
35+ - **定时任务请求必须使用 create_scheduled_task 工具**
36+
37+ ## 定时任务工具
38+
39+ 当用户说"帮我每天扫描"、"每周检查"等定时需求时,使用以下工具:
40+
41+ - create_scheduled_task: 创建定时扫描任务
42+ - list_scheduled_tasks: 查看所有定时任务
43+ - pause_scheduled_task: 暂停任务
44+ - resume_scheduled_task: 恢复任务
45+ - delete_scheduled_task: 删除任务
46+
47+ **Cron 表达式说明**:
48+ - "0 9 * * *" = 每天 9:00
49+ - "0 9 * * 1" = 每周一 9:00
50+ - "*/10 * * * *" = 每 10 分钟
51+ - "0 0 * * *" = 每天凌晨
52+
53+ **创建定时任务示例**:
54+ 用户: "帮我每天凌晨3点扫描 github 组织的安全漏洞"
55+ Agent 调用: create_scheduled_task(
56+ name="每日github安全扫描",
57+ target_type="org",
58+ target_name="github",
59+ cron_expression="0 3 * * *",
60+ prompt="扫描 github 组织的 CVE 漏洞和敏感信息",
61+ dimensions=["cve", "secret"]
62+ )
63+
64+ ## 可用子Agent(通过 task 工具调用)
65+
66+ - security-analyzer: 安全风控扫描(CVE、漏洞、敏感信息)
67+ - compliance-analyzer: 合规审计(许可证、版权)
68+ - community-analyzer: 社区健康分析(Issue、PR、贡献者)
69+ - trend-analyzer: 技术趋势分析(Star、增长)
70+
71+ ## 委派策略 - 根据范围选择正确的描述
72+
73+ **关键原则**:在委派描述中明确告诉子Agent参数格式!
74+
75+ | 用户请求范围 | 委派描述示例 |
76+ |-------------|-------------|
77+ | 整个组织 | "使用 scan_org 扫描 GitHub 组织" |
78+ | 多个仓库 | "使用 check_cve_repos 检查 repos='microsoft/vscode,microsoft/typescript'" |
79+ | 单个仓库 | "使用 check_cve_repos 检查 repos='microsoft/vscode'" |
80+
81+ ## 并发委派示例
82+
83+ 用户请求: "分析 SOFAStack 组织的安全和合规情况"
84+
85+ ```json
86+ [
87+ {"name": "task", "args": {"subagent_type": "security-analyzer", "description": "使用 scan_org(org_name='sofastack', dimensions='cve,secret') 扫描整个组织的安全漏洞"}},
88+ {"name": "task", "args": {"subagent_type": "compliance-analyzer", "description": "使用 scan_org(org_name='sofastack', dimensions='license') 扫描整个组织的许可证合规"}}
89+ ]
90+ ```
91+
92+ **错误做法**: 逐个仓库委派(效率极低)
93+
94+ ## 工作流程
95+
96+ 用户请求: "分析 sofa-rpc 和 sofa-boot 的安全漏洞"
97+
98+ 正确流程:
99+ 1. write_todos: ["委派 security-analyzer 检查两个仓库"]
100+ 2. task: {"description": "使用 check_cve_repos(repos='sofastack/sofa-rpc,sofastack/sofa-boot')"}
101+ 3. 等待结果
102+ 4. 汇总报告
103+ 5. return_report_for_download
104+
105+ 用户请求: "每10分钟扫描 ant-group 组织"
106+
107+ 正确流程:
108+ 1. write_todos: ["创建定时任务"]
109+ 2. create_scheduled_task: {
110+ name: "ant-group 定时扫描",
111+ target_type: "org",
112+ target_name: "ant-group",
113+ cron_expression: "*/10 * * * *",
114+ prompt: "扫描 ant-group 组织的安全漏洞和合规问题",
115+ dimensions: ["cve", "license"]
116+ }
117+ 3. 告知用户任务已创建
118+ """
119+
120+
121+ async def create_agent (checkpointer = None , store : BaseStore = None ):
122+ """创建 DeepAgents 主 Agent(仅支持沙箱模式)。
123+
124+ Args:
125+ checkpointer: 可选的 checkpoint saver 实例
126+ store: 可选的 BaseStore 实例(用于长期记忆和技能存储)
127+
128+ Returns:
129+ tuple: (agent, backend) - Agent 实例和沙箱后端实例
130+
131+ Raises:
132+ RuntimeError: 如果沙箱初始化失败
133+ """
134+ logger .info ("create_agent_start" )
135+
136+ # ---------- 1. 配置百炼大模型平台 ----------
137+ dashscope_api_key = os .getenv ("DASHSCOPE_API_KEY" )
138+ if dashscope_api_key :
139+ os .environ ["OPENAI_API_KEY" ] = dashscope_api_key
140+ os .environ ["OPENAI_API_BASE" ] = os .getenv (
141+ "OPENAI_API_BASE" ,
142+ "https://dashscope.aliyuncs.com/compatible-mode/v1"
143+ )
144+ logger .info ("bailian_platform_configured" , api_key_present = True )
145+
146+ # ---------- 2. 初始化模型(使用统一配置)----------
147+ model = get_default_model ()
148+ logger .info ("model_initialized" , use_responses_api = False )
149+
150+ # ---------- 3. 创建沙箱 Backend(必须成功)----------
151+ logger .info ("backend_creating" , mode = "sandbox_required" )
152+
153+ backend_factory = await create_backend () # 强制使用沙箱
154+ logger .info ("backend_created" )
155+
156+ # 获取实际 backend 实例(用于下载路由和技能加载)
157+ actual_backend = None
158+ composite = None
159+ try :
160+ composite = backend_factory (None )
161+ actual_backend = composite .default
162+ logger .info ("sandbox_backend_extracted" ,
163+ backend_type = type (actual_backend ).__name__ ,
164+ sandbox_id = actual_backend .id )
165+ except Exception as e :
166+ logger .error ("backend_extract_failed" , error = str (e ))
167+ raise RuntimeError (f"沙箱后端初始化失败: { e } " )
168+
169+ # ---------- 4. 加载子Agent ----------
170+ subagents_dir = os .getenv ("SUBAGENTS_DIR" , "./subagents" )
171+ logger .info ("subagents_loading" , directory = subagents_dir )
172+
173+ loader = SubAgentLoader (subagents_dir )
174+ subagents = loader .load_all ()
175+ logger .info ("subagents_loaded" , count = len (subagents ), names = [s ["name" ] for s in subagents ])
176+
177+ # ---------- 5. 配置 Store ----------
178+ if store :
179+ logger .info ("store_configured" , store_type = type (store ).__name__ )
180+ else :
181+ logger .warning ("store_not_configured" , message = "StoreBackend operations may fail" )
182+
183+ # ---------- 6. 配置 memory(沙箱路径)----------
184+ memory_config = ["/memories/AGENTS.md" ]
185+ logger .info ("memory_config_sandbox" , path = "/memories/AGENTS.md" )
186+
187+ logger .info ("deep_agent_creating" ,
188+ has_checkpointer = checkpointer is not None ,
189+ has_memory = memory_config is not None )
190+
191+ agent = create_deep_agent (
192+ model = model ,
193+ system_prompt = MAIN_SYSTEM_PROMPT ,
194+ memory = memory_config ,
195+ subagents = subagents ,
196+ tools = common_tools + skill_tools + scheduler_tools ,
197+ checkpointer = checkpointer ,
198+ backend = backend_factory ,
199+ store = store ,
200+ middleware = [
201+ SkillsMiddleware (
202+ backend = composite ,
203+ sources = ["/skills/main/" ],
204+ ),
205+ ToolErrorHandlerMiddleware (),
206+ ],
207+ )
208+ logger .info ("agent_created_successfully" ,
209+ tool_count = len (common_tools ) + len (skill_tools ) + len (scheduler_tools ),
210+ sandbox_id = actual_backend .id )
211+
212+ return agent , actual_backend
0 commit comments