diff --git a/agent/planner.go b/agent/planner.go index 36ed693..3a13830 100644 --- a/agent/planner.go +++ b/agent/planner.go @@ -313,7 +313,7 @@ const plannerDefaultTmpl = `你是一个网络安全平台授权渗透测试系 - **要更深细节才按需调**:list_facts(分页,最新在前,默认 20,可 q 过滤、before 翻页,带 total/has_more)、list_findings(全部漏洞)、node_detail(id)(完整证据/详情;列表/recent_facts 只给摘要)、list_assets(pull:q 搜索、type/company_id/task_id 过滤、分页,或 id/ids 直取)、asset_neighbors。资产全局共享,别默认拉全量。 2. **判目标(核心职责)**:goals 字段已含目标与状态;对已被某发现/事实证明的未达成目标,调 prove_goal(goal_id, evidence_id, reason) 标 met。**当你标记的恰是最后一个未完成目标时,系统自动判定整个任务完成**——收官只由逐个 prove_goal 驱动,没有别的"一键完成"手段。 - - ⚠️ **量化验收核对(严禁提前盖章)**:目标含可量化条件(覆盖度达 X%、拿 N 个 flag、获得某权限)时,prove_goal 前【必须】核对上方 graph_overview 的实测值(coverage.pct、findings 计数等):未达标就【禁止】prove_goal,改派意图补差;不得以"大体达成/核心已拿下"为由提前标 met。例:要求覆盖度 100% 而实测 coverage.pct=40% → 未达成,继续派补测意图。 + - ⚠️ **量化验收核对(严禁提前盖章)**:目标含可量化条件(覆盖度达 X%、拿 N 个 flag、获得某权限)时,prove_goal 前【必须】核对上方 graph_overview 的实测值(coverage.pct、findings_total 计数等):未达标就【禁止】prove_goal,改派意图补差;不得以"大体达成/核心已拿下"为由提前标 met。例:要求覆盖度 100% 而实测 coverage.pct=40% → 未达成,继续派补测意图。 3. **(可选,仅开局、极轻量)探测理解**:仅当图里几乎还没有 fact(recent_facts 基本为空、任务刚开始)、仅凭态势无法把初始意图说具体时,才用 Bash 等对目标做极少量、只读的探测(如 1–2 次 curl 看首页/指纹)。**唯一合法产物是一句更精准的意图描述**——绝不是漏洞的发现/验证/利用,也不是端点/目录/参数的枚举结果(那些是 worker 的活,写成意图派下去)。三条硬边界: - 图里已有 worker 产出的 fact(facts>0 / recent_facts 非空)→【禁止】再自己探测,一切判断基于已有 fact,本轮产物只能是"派新意图"或"结束";想深挖某线索 → 派意图让 worker 去查,不是自己 curl。 diff --git a/agent/tools.go b/agent/tools.go index c9b4350..47d841a 100644 --- a/agent/tools.go +++ b/agent/tools.go @@ -461,14 +461,18 @@ func (t *ToolSet) graphOverviewData() map[string]any { // via node_detail(id). vulnNodes, _ := t.ts.ListByKind(db.KindFinding, 1000) factNodes, _ := t.ts.ListByKind(db.KindFact, 1000) // newest first - out["findings"] = len(vulnNodes) // 确认漏洞数(目标判定看它) + out["findings_total"] = len(vulnNodes) // 确认漏洞总数(目标判定看它);明细见 finding_list(最新一窗) out["facts"] = len(factNodes) // 探索事实/结论数(含否定结论) - // findings 是任务里最高价值的产物、单任务通常也不多 → 直接全量带进概览(不像 facts 那样 - // 只给最近窗口),让 planner 每轮判目标时一眼看全所有确认漏洞,无需再调 list_findings。 + // findings 是任务里最高价值的产物 → 概览带最新一窗(≤10 条,vulnNodes 已按 id 降序即最新在前), + // 让 planner 每轮判目标时一眼看到最近确认的漏洞;全量/更早的用 list_findings 取。 // 每条只留 {id, summary, from_intent?}:from_intent 是产生本漏洞的意图。 // evidence/assets/vulnclass/severity/state 等仍可用 list_findings / node_detail(id) 取。 - findingList := make([]map[string]any, 0, len(vulnNodes)) + const findingListCap = 10 + findingList := make([]map[string]any, 0, findingListCap) for _, n := range vulnNodes { + if len(findingList) >= findingListCap { + break + } var fp map[string]any _ = json.Unmarshal(n.Payload, &fp) m := map[string]any{"id": n.ID, "summary": fp["summary"]}