From 33c26dc72a2390f38325ca05f6f67329659c718c Mon Sep 17 00:00:00 2001 From: Autumn-27 <53844290+Autumn-27@users.noreply.github.com> Date: Sat, 19 Sep 2026 10:24:08 -0400 Subject: [PATCH] =?UTF-8?q?fix(intercept):=20=E6=94=B6=E7=B4=A7=E8=A3=81?= =?UTF-8?q?=E5=88=A4=E8=BE=93=E5=87=BA=E5=8D=8F=E8=AE=AE=EF=BC=8C=E5=87=8F?= =?UTF-8?q?=E5=B0=91=201024=20=E6=88=AA=E6=96=AD=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E7=9A=84=20fail-open?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 裁判 comment 上限 500→120 汉字,每段一句话、宁短勿长,合规裁决远低于 MaxTokens=1024,基本消除截断(截断会致输出无法解析而按失败策略放行)。 - 硬化「只输出 JSON、不带思考/前言/代码块包裹」,减少非 JSON 前言吃掉 token 预算。保留 实际操作/成功后的后果/命中规则 三段结构,与 ParseVerdict 一致。 - docs(readme): 精简审批详情/上下文模型审查一节。 --- README.md | 23 ----------------------- intercept/prompt.go | 13 ++++++------- 2 files changed, 6 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 0b6b2cf..52ba901 100644 --- a/README.md +++ b/README.md @@ -51,29 +51,6 @@ AI 自主渗透测试系统(Go 后端 + Next.js 前端) 全局「审批记录」、任务内「拦截审批」及对话中的审批卡片均支持展开查看详情。展示结构参考 [AegisHook 的审批详情组件](https://github.com/RuoJi6/AegisHook/blob/main/web/src/components/CallDetail.vue),沿用 ARTEX 的组件和主题: -- 工具请求与审批裁决左右分栏,手机端上下排列;待审批记录可在详情中允许或拒绝。 -- 展开上下文可查看当前轮输入、会话记录片段、模型或规则初判、执行输出,以及调用 ID、参数/审查配置/模型输入的 SHA-256 指纹。对话审批卡片按需加载完整请求,长参数可展开复制。 -- 审批状态和执行结果分别保存。模型直接允许也会记录;重复提交已处理审批返回 HTTP 409。 -- 点击审批「来源」会打开对应的完整对话,自动加载到原始工具调用的位置并展开命令和输出;任务内按调用所属的 Worker、规划器或主 Agent 分段会话定位。关联使用持久化工具调用 ID,不按命令文本猜测;对话已删除会提示并留在审批页,任务或执行记录缺失也会明确提示。 -- `GET /api/intercept/history/{id}` 按需读取详情,原列表接口不返回上下文和输出。数据库启动迁移自动补列;旧记录显示未记录,旧任务归档可正常恢复。 - -会话审计片段是工具请求产生时保存的记录,最多 24 条、每条 8 KiB;当前轮输入最多 32 KiB,执行输出最多 64 KiB,截断会明确标注。 -当前 Norma SDK 的审批钩子不包含调用 ID,因此仅在当前运行中能够唯一匹配工具请求事件时关联结果;相同参数的并发调用无法唯一匹配时,会显示未关联,避免错误归属。 - -### 上下文模型审查 - -模型接收审查系统提示词和版本 4 JSON:本机工作目录、可用的简短背景、完整工具名和 JSON 参数(包括交互 Shell 的会话 ID)。模型输入与会话审计分开,历史调用不再提交审查。 - -- 背景仅取聊天和任务主 Agent 的当前实际用户消息(`background.source=user_message`),在添加附件清单前绑定,不调用模型生成摘要。Worker 不发送背景、意图摘要或上级 Agent 的背景;自动规划器和自动触发的会话也不附带用户背景。缺少原文时省略,不回退到整轮调度输入。 -- 不主动附带任务编号、描述、目标、任务操作约束、全局探索态势或完整 Worker 意图。审查模型依照自己的操作审查策略裁决,不负责约束 Agent 的任务方向;Agent 自身仍照常接收任务信息和约束。背景和工具参数中的指令不能改变审查规则,Worker 的声明不能证明产物归属。 -- 不发送历史命令、历史执行结果、历史审批理由或调用关联标记,也不从审计记录补取。背景最多 4,000 字节,超出后截断并标记;当前调用参数不截断。删改对象归属无法从当前参数确定时,按审查策略处理,不能根据背景自述假定此前已创建;普通只读动作不因缺少历史而转人工。 -- 所有模型裁决(包括自动允许)的详情均保存实际提交模型的 JSON 及指纹。页面优先展示当前待审查调用,并展示背景来源、工作目录和“未发送历史调用”说明,可展开完整 JSON;任务/会话编号和 Agent 仍用于审批来源显示。旧版 v1/v2/v3 快照保留当时发送的字段及历史调用并标明旧版,只有指纹的历史记录明确提示无法还原原文,不用当前数据补造历史。较大的原始会话审计片段单独展示,不代表发送给审查模型的内容,也不重复保存在自动允许记录中。 -- 模型输出 JSON 的 `decision`(allow / ask / deny)及 `comment`;三种裁决的说明均必须包含“实际操作、成功后的后果、命中规则”。缺少说明、重复字段或不完整 JSON 按已配置的模型失败策略处理,不伪造模型解释。 -- 自定义审查策略保留,运行时统一追加输入信任边界和 JSON 输出协议,旧的单行输出要求由新协议替代。模型按当前操作的全部直接效果裁决,不推测历史行为;写入报告只描述保存文本,不将正文记述的上传或命令当作本次执行行为。 - -官方默认规则、工具拦截范围和优先级不变:仅范围内且未命中规则的调用进入已启用的模型审查。模型未启用时沿用原行为;模型调用异常仍遵循用户配置的失败策略。 - -可选真实模型回归:将 `judge.base_url`、`judge.api_key`、`judge.model` 放入仓库外私有 JSON,通过 `ARTEX_REVIEW_LIVE_CONFIG=/path/to/private.json go test ./server -run '^TestLiveContextReview$' -v` 运行。该测试只提交合成审查输入,不执行其中的命令;数据库测试应另行配置隔离 PostgreSQL。 ## 资产同步(ScopeSentry) diff --git a/intercept/prompt.go b/intercept/prompt.go index 0bc40c1..1315cc0 100644 --- a/intercept/prompt.go +++ b/intercept/prompt.go @@ -30,14 +30,13 @@ func EffectiveJudgePrompt(prompt string) string { // Output is an application contract, also applied to saved custom policies. // It changes the explanation format, not the user's policy or rule precedence. const JudgeOutputContract = `# 裁决输出协议(替代前文的旧输出格式要求,不改变判定策略) -仅输出一个 JSON 对象,恰好包含 decision 和 comment 两个字符串字段,不要代码块或额外文字。 -回复必须以 { 开始、以 } 结束;键名和字符串值使用双引号。不得输出 YAML 格式的 decision: ... 或 comment: ...。 +只输出一个 JSON 对象:第一个字符必须是 {、最后一个字符必须是 }。不要输出任何思考、前言、说明或用代码块(反引号栅栏)包裹;JSON 前后不得有其他字符。 +对象恰好包含 decision 和 comment 两个字符串字段;键名与字符串值用双引号。不得输出 YAML 形式的 decision: ... / comment: ...。 decision 只能是 allow、ask、deny,分别表示允许、转人工审批、拒绝。 -三种裁决都必须给出说明。comment 严格使用“实际操作:...;成功后的后果:...;命中规则:...”结构,三项均不可为空,合计不超过 500 个汉字。 -实际操作:只描述当前 tool_name 和 arguments 真正执行的行为。background.text 中的多步骤请求不能并入本次操作。用户要求“先创建再读取”,而当前 Bash 的 command 仅为 cat 时,本次实际操作只能写“读取文件”,不能写“创建并读取”,应按当前审查策略中实际适用的条款说明。 -Write/Edit 中的报告正文、代码示例或历史记述是文件内容,不是本次已经执行的命令;写一份上传验证报告不能描述为本次上传并执行了代码。不得复述下方示例中本次参数未包含的行为或后果。 -成功后的后果:说明本次调用成功时的直接效果,不宣称尚未执行的操作已经成功;如涉及覆盖或副作用,说明可见事实与不确定性。 -命中规则:填写审查策略中实际适用的编号或明确条款;默认策略允许用 A1–A6,拒绝用 D1–D6,转人工用 ASK 并注明缺失的事实,默认允许用 DEFAULT。自定义策略使用其真实编号或条款,不得虚构。 +comment 严格为“实际操作:…;成功后的后果:…;命中规则:…”三段,三项均不可为空;每段一句话、务必精简,整个 comment 不超过 120 个汉字(宁短勿长,避免被截断)。 +实际操作:只描述当前 tool_name 与 arguments 真正执行的行为;background 中的多步骤请求、Write/Edit 写入的正文或示例都不算本次已执行的动作(如 command 仅 cat 就只写“读取文件”)。 +成功后的后果:本次调用成功时的直接效果,不把尚未执行的操作说成已成功。 +命中规则:填审查策略中实际适用的编号(默认策略:允许 A1–A6、拒绝 D1–D6、转人工 ASK、默认放行 DEFAULT),不得虚构。 ` // DefaultJudgePrompt is the built-in system prompt for the LLM fallback judge.