diff --git a/agent/worker.go b/agent/worker.go index 6a3f9cd..ccd357e 100644 --- a/agent/worker.go +++ b/agent/worker.go @@ -208,7 +208,7 @@ const workerDefaultTmpl = `你是一个 ARTEX 平台授权渗透测试系统的" **边发现边写回**(写进图才算数,脑子/文字里的不算;每得一个结果立刻写,别攒到最后被步数耗尽丢掉)。三种写回,别串图: - **新资产/资源 → insert_assets(资产图)**:endpoint / parameter / tech 指纹 / service / 凭据 / 子域 等。你只传原始信息,key 与父子关联由代码算:新接口传完整 url+method(代码自动建 domain→site→endpoint、抽 URL query 参数,body/header 参数放 params);指纹传 type=tech,name=技术名,on_url=站点地址,props={version,category}。结构化属性写在资产自己的 props 上(状态码/标题/body 长/content_type 放 props.http),探索结论不写这里。多资产用 assets 数组一次批量登记。 -- **探索结论/事实 → record_fact(探索图,传 intent_id)**:正向结论(指纹/枚举)和否定/存疑观察(端口关闭、参数不可注入、未发现入口)都用它。**多个观察汇总成【一条】事实**(summary 一句总结 + detail 放技术栈/状态码/响应特征等细节),不要一个属性一条、一意图通常只一条,拆碎会让图谱无限膨胀;确有多条【彼此不同】的结论才用 facts 数组。**只写增量**:写前扫上方 recent_facts,只记这次【新得到】的,别把已有事实换措辞重记(只印证已有、无新增就不必记)。**只写真实看到的**:给 evidence(一行:命令+最能证明的一两行输出,简洁,细节在 detail)、标 confidence(observed=直接看到 / inferred=据现象推断)。**否定类结论只写"观察 + 试探性读法"**:陈述你实际看到什么 + 顶多一句暂时推断,方向是否放弃由规划者综合全局定(例:"对该参数试了 X/Y/Z 均无回显与报错(evidence:…),暂时看不出可注入点,未穷尽全部手法")。手段没走完、或证据只是"看起来像/大概率/只探一次"标 inferred;确已穷尽本意图手段(换编码/参数/路径/方法)且证据是直接看到的才标 observed;早期尤其宁可标 inferred 让规划者复核。 +- **探索结论/事实 → record_fact(探索图,传 intent_id)**:都用它。**多个观察汇总成【一条】事实**(summary 一句总结 + detail写对总结的拓展,依靠真实的执行过程),不要一个属性一条、一意图通常只一条,拆碎会让图谱无限膨胀——**默认就写一条,能并进 detail 的都并进去**;仅当确有【彼此完全独立、无法归并】的结论时才用 facts 数组分条,这是极少数例外,不是常规。**只写增量**:只记这次【新得到】的,别把已有事实换措辞重记(只印证已有、无新增就不必记)。**只写真实看到的**:给 evidence(一行:命令+最能证明的一两行输出,简洁,细节在 detail)、标 confidence(observed=直接看到 / inferred=据现象推断)。 - **确认漏洞 → report_finding(探索图,含 PoC,传 intent_id)**:**只有你本次真实触发过、拿到可复现证据(请求/响应或命令输出)才用**。严禁把"版本/指纹匹配到 CVE""参数看起来可注入""外部漏洞库/更新日志/代码 diff 推断"当已确认,也不要用查 CVE 库或对比补丁版本替代实际触发。触发不了但有嫌疑 → 用 record_fact 记一条 inferred 事实(嫌疑点+为何未触发)交规划者,别硬记成 finding。 **查上下文(按需)**:list_assets / asset_neighbors / list_facts(探索事实,分页最新在前,默认 20,可 q 过滤、before 翻页)/ list_findings / node_detail(探索节点 id,非资产 id)。 diff --git a/server/orchestration.go b/server/orchestration.go index 247535a..c1addf0 100644 --- a/server/orchestration.go +++ b/server/orchestration.go @@ -608,12 +608,13 @@ func (s *Server) reseedPlannerPrompt() { log.Printf("[prompts] planner 提示词已追加新默认版本(精简重构+克制降级去重+深度优先+否定复核上界,一次性)") } -// reseedWorkerPrompt 把 worker 提示词刷成【当前代码默认】——默认正文做了精简重构,并把否定结论改为 -// 「只写观察+试探性读法」、新增「跨意图线索写进 fact 交规划者、不自己追」。bump flag 至 v2 让存量旧库再刷一次。SeedPromptIfEmpty 首插入only, -// 旧库已有版本收不到,故用版本管理【追加一个新版本】并切过去,旧版本仍保留在历史里可找回。settings flag -// 守卫 → 只做一次。全新库无需处理。与 reseedGoalsPrompt 完全同构。 +// reseedWorkerPrompt 把 worker 提示词刷成【当前代码默认】——默认正文 record_fact 段删掉了「否定类结论 +// 写观察+试探性读法」整句、并把 confidence(observed/inferred)与「是否穷尽本意图手段」解耦(这些易误导规划者), +// 同时把 facts 数组分条收紧为「彼此完全独立、无法归并」的极少数例外。bump flag 至 v3 让存量旧库再刷一次。 +// SeedPromptIfEmpty 首插入only,旧库已有版本收不到,故用版本管理【追加一个新版本】并切过去,旧版本仍保留在历史里可找回。 +// settings flag 守卫 → 只做一次。全新库无需处理。与 reseedGoalsPrompt 完全同构。 func (s *Server) reseedWorkerPrompt() { - const flag = "worker_prompt_compact_v2" + const flag = "worker_prompt_compact_v3" if v, _, _ := s.m.pg.GetSetting(flag); v == "true" { return } @@ -634,7 +635,7 @@ func (s *Server) reseedWorkerPrompt() { log.Printf("[prompts] worker 提示词重刷为新默认失败: %v", err) return } - log.Printf("[prompts] worker 提示词已追加新默认版本(精简重构+否定改观察式+跨意图线索上报,一次性)") + log.Printf("[prompts] worker 提示词已追加新默认版本(record_fact 删否定结论段+confidence 与穷尽解耦+facts 分条收紧,一次性)") } // seedReporterAgent 预置一个「报告撰写」自定义 agent(builtin=false,可在 UI 编辑/删除):