Skip to content

Commit 5ee9e22

Browse files
lintsinghuaclaude
andcommitted
feat(agent): 修复Agent间TaskHandoff通信机制
- Orchestrator: 添加_build_handoff_for_agent()构建并传递TaskHandoff - Orchestrator: 保存子Agent返回的handoff到_agent_handoffs字典 - Recon Agent: 添加_create_recon_handoff()生成结构化交接信息 - Analysis Agent: 添加_create_analysis_handoff()传递漏洞发现 - Verification Agent: 添加_create_verification_handoff()返回验证结果 通信流程: Recon → Analysis → Verification → Orchestrator 每个Agent现在都能正确接收、使用和生成TaskHandoff Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent f7369d4 commit 5ee9e22

File tree

4 files changed

+525
-14
lines changed

4 files changed

+525
-14
lines changed

backend/app/services/agent/agents/analysis.py

Lines changed: 102 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from typing import List, Dict, Any, Optional
1818
from dataclasses import dataclass
1919

20-
from .base import BaseAgent, AgentConfig, AgentResult, AgentType, AgentPattern
20+
from .base import BaseAgent, AgentConfig, AgentResult, AgentType, AgentPattern, TaskHandoff
2121
from ..json_parser import AgentJsonParser
2222
from ..prompts import CORE_SECURITY_PRINCIPLES, VULNERABILITY_PRIORITIES
2323

@@ -789,6 +789,9 @@ async def run(self, input_data: Dict[str, Any]) -> AgentResult:
789789
# 🔥 CRITICAL: Log final findings count before returning
790790
logger.info(f"[{self.name}] Returning {len(standardized_findings)} standardized findings")
791791

792+
# 🔥 创建 TaskHandoff - 传递给 Verification Agent
793+
handoff = self._create_analysis_handoff(standardized_findings)
794+
792795
return AgentResult(
793796
success=True,
794797
data={
@@ -807,6 +810,7 @@ async def run(self, input_data: Dict[str, Any]) -> AgentResult:
807810
tool_calls=self._tool_calls,
808811
tokens_used=self._total_tokens,
809812
duration_ms=duration_ms,
813+
handoff=handoff, # 🔥 添加 handoff
810814
)
811815

812816
except Exception as e:
@@ -816,7 +820,103 @@ async def run(self, input_data: Dict[str, Any]) -> AgentResult:
816820
def get_conversation_history(self) -> List[Dict[str, str]]:
817821
"""获取对话历史"""
818822
return self._conversation_history
819-
823+
820824
def get_steps(self) -> List[AnalysisStep]:
821825
"""获取执行步骤"""
822826
return self._steps
827+
828+
def _create_analysis_handoff(self, findings: List[Dict[str, Any]]) -> TaskHandoff:
829+
"""
830+
创建 Analysis Agent 的任务交接信息
831+
832+
Args:
833+
findings: 分析发现的漏洞列表
834+
835+
Returns:
836+
TaskHandoff 对象,供 Verification Agent 使用
837+
"""
838+
# 按严重程度排序
839+
severity_order = {"critical": 0, "high": 1, "medium": 2, "low": 3}
840+
sorted_findings = sorted(
841+
findings,
842+
key=lambda x: severity_order.get(x.get("severity", "low"), 3)
843+
)
844+
845+
# 提取关键发现(优先高危漏洞)
846+
key_findings = sorted_findings[:15]
847+
848+
# 构建建议行动 - 哪些漏洞需要优先验证
849+
suggested_actions = []
850+
for f in sorted_findings[:10]:
851+
suggested_actions.append({
852+
"action": "verify_vulnerability",
853+
"target": f.get("file_path", ""),
854+
"line": f.get("line_start", 0),
855+
"vulnerability_type": f.get("vulnerability_type", "unknown"),
856+
"severity": f.get("severity", "medium"),
857+
"priority": "high" if f.get("severity") in ["critical", "high"] else "normal",
858+
"reason": f.get("title", "需要验证")
859+
})
860+
861+
# 统计漏洞类型和严重程度
862+
severity_counts = {}
863+
type_counts = {}
864+
for f in findings:
865+
sev = f.get("severity", "unknown")
866+
vtype = f.get("vulnerability_type", "unknown")
867+
severity_counts[sev] = severity_counts.get(sev, 0) + 1
868+
type_counts[vtype] = type_counts.get(vtype, 0) + 1
869+
870+
# 构建洞察
871+
insights = [
872+
f"发现 {len(findings)} 个潜在漏洞需要验证",
873+
f"严重程度分布: Critical={severity_counts.get('critical', 0)}, "
874+
f"High={severity_counts.get('high', 0)}, "
875+
f"Medium={severity_counts.get('medium', 0)}, "
876+
f"Low={severity_counts.get('low', 0)}",
877+
]
878+
879+
# 最常见的漏洞类型
880+
if type_counts:
881+
top_types = sorted(type_counts.items(), key=lambda x: x[1], reverse=True)[:3]
882+
insights.append(f"主要漏洞类型: {', '.join([f'{t}({c})' for t, c in top_types])}")
883+
884+
# 需要关注的文件
885+
attention_points = []
886+
files_with_findings = {}
887+
for f in findings:
888+
fp = f.get("file_path", "")
889+
if fp:
890+
files_with_findings[fp] = files_with_findings.get(fp, 0) + 1
891+
892+
for fp, count in sorted(files_with_findings.items(), key=lambda x: x[1], reverse=True)[:10]:
893+
attention_points.append(f"{fp} ({count}个漏洞)")
894+
895+
# 优先验证的区域 - 高危漏洞所在文件
896+
priority_areas = []
897+
for f in sorted_findings[:10]:
898+
if f.get("severity") in ["critical", "high"]:
899+
fp = f.get("file_path", "")
900+
if fp and fp not in priority_areas:
901+
priority_areas.append(fp)
902+
903+
# 上下文数据
904+
context_data = {
905+
"severity_distribution": severity_counts,
906+
"vulnerability_types": type_counts,
907+
"files_with_findings": files_with_findings,
908+
}
909+
910+
# 构建摘要
911+
high_count = severity_counts.get("critical", 0) + severity_counts.get("high", 0)
912+
summary = f"完成代码分析: 发现{len(findings)}个漏洞, 其中{high_count}个高危"
913+
914+
return self.create_handoff(
915+
to_agent="verification",
916+
summary=summary,
917+
key_findings=key_findings,
918+
suggested_actions=suggested_actions,
919+
attention_points=attention_points,
920+
priority_areas=priority_areas,
921+
context_data=context_data,
922+
)

0 commit comments

Comments
 (0)