minimal-agent 0.6.9 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "minimal-agent",
3
- "version": "0.6.9",
3
+ "version": "0.7.0",
4
4
  "description": "最小化 Agent 系统 —— 10 工具 + 插件系统 + workflow DSL + 自动压缩 + OpenAI 兼容 + Ink TUI;NodeNext + tsc 原地编译,dev 用 Bun .ts、install 用 Node .js(学习/教学用)",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": "Bill Wang <leiwang0359@gmail.com>",
@@ -0,0 +1,125 @@
1
+ ---
2
+ name: adversarial-review
3
+ description: 质疑一个结论 / 计划 / 既有评审 / 设计方案是否站得住脚——默认怀疑、逼出证据,把发现分成「真问题 / 误报 / 待澄清」。注意:若用户只是想给代码找冗余 / 反模式 / 做常规质量改进,用 /simplify 而非本 skill。
4
+ triggers: 对抗审查、反向提问、红队、挑战这个结论、验证某结论或方案是否站得住脚、哪些是误报哪些是真问题、审稿、复核这个判断
5
+ ---
6
+
7
+ # /adversarial-review —— 对抗式审查(反向提问,默认怀疑)
8
+
9
+ ## 目的
10
+
11
+ 验证一个**结论 / 计划 / 既有评审 / 设计方案 / 一段代码**是否站得住脚时,别让模型(或你自己)
12
+ 轻易点头。人和 LLM 面对「这个对吗?」都有**迎合反射**——倾向于附和、补论据、越夸越顺。
13
+ 本 skill 的目的:用「反向提问」把这种迎合反射**翻转成怀疑反射**,再用举证纪律把怀疑落到实处,
14
+ 最终把发现诚实地分成 🔴 真问题 / ⚪ 误报 / 🟡 待澄清。
15
+
16
+ ## 方法一:把问题转成「表面反向的提问」(扳机)
17
+
18
+ **永远不要问「X 对不对 / X 是否正确」,要问「X 是不是错的 / X 哪里站不住脚」。**
19
+
20
+ 为什么仅仅换个问法就有用?因为**举证责任被翻转**了:
21
+
22
+ - 问「X 对吗?」→ 回答者可以**零成本附和**("对的、挺好"),不费力就能交差,迎合反射全开。
23
+ - 问「X 错在哪?」→ 回答者**必须先假设它有错**,然后去枚举失败场景、找反例、回现场核对才能回答;
24
+ 哪怕最后发现 X 其实成立,那也是**认真攻击过之后**的结论,而不是反射性点头。
25
+
26
+ 类比面试:问「你会不会用 X?」对方反射答「会」;但问「你是不是其实不会 X?」对方被迫拿出
27
+ 真凭实据来反驳你——被逼着深度思考、自证清白。对抗审查就是把**每一次判断**都塞进后一种问法里。
28
+
29
+ > ⚠️ 「换问法」只是扳机,不是终点。光把问法反过来,模型同样可能编出**看似合理却牵强**的
30
+ > 假问题来"完成证伪任务",那是在制造新的误报。所以扳机必须接上「方法二:举证纪律」。
31
+
32
+ ## 方法二:举证纪律(引擎)
33
+
34
+ 反向提问扣动扳机后,每条判断都要过这三关,否则不算数:
35
+
36
+ 1. **拆成原子主张**:把审查对象切成一条条**能被单独证伪**的主张。整段"感觉对"没意义,可攻击的最小单元才有。
37
+ 2. **举证责任在主张方**:每条主张默认**未被证实**,靠具体反例 / 现场核对 / 可查依据来支撑或推翻。判定一律附证据,不附证据的判定本身就是错的。
38
+ 3. **去现场,不凭记忆**:涉及代码 / 事实的主张,一律 Read / Grep 核对原文。用脑内印象当证据是制造误报的头号来源。
39
+
40
+ **误报和漏报一样有害。** 把成立的主张硬说成问题,和放过真问题一样是审查失败——这与「默认怀疑」同等重要。
41
+
42
+ ## 反向提问转换示例(按情况直接套用)
43
+
44
+ 把用户原本(或心里)的「迎合式问法」翻成「反向式问法」,再走方法二的纪律:
45
+
46
+ | 你想确认的事(迎合式 ❌) | 反向提问的问法(✅ 套这个) |
47
+ |---|---|
48
+ | 这个方案对吗? | 这个方案**是不是错的**?它在什么输入 / 场景 / 规模下会崩?哪一步的假设最可能不成立? |
49
+ | 这份代码评审准吗? | 这份评审里**哪些是误报、哪些是真问题**?逐条去现场核对它说的代码是否真这样。 |
50
+ | 我刚写的这段代码没问题吧? | 这段代码**哪里有 bug**?给我一个能让它出错的具体输入 / 边界 / 并发时序。 |
51
+ | X 这个事实成立吗? | X **在什么情况下是假的**?反例是什么?它的依据经得起核对吗? |
52
+ | 该选方案 A 吗? | 选 A **会在什么场景下变成错误决定**?A 比 B 差在哪?A 的隐藏代价是什么? |
53
+ | 这个回答 / 总结完整吗? | 这个回答**漏了什么**?哪个边界 / 失败路径 / 反例没覆盖? |
54
+ | 这个重构安全吗? | 这个重构**会悄悄破坏什么**?哪些调用方 / 测试 / 契约依赖了被改掉的行为? |
55
+ | 文档 / 注释和代码一致吗? | 文档**哪一句和代码对不上**?逐句拿去和实现核对,找出已经过时(stale)的描述。 |
56
+
57
+ **worked example(评审复核——最常见场景)**
58
+
59
+ 输入:「上一阶段的改动,代码评审说有以下 N 个问题,是不是误报?」
60
+
61
+ - ❌ 迎合式追问「这些问题对吗?」→ 模型容易逐条附和"是的这是问题",等于没审。
62
+ - ✅ 反向式追问:「这 N 条里**哪些是误报、哪些是真问题,为什么**?每条都 Read 对应文件去现场核对它
63
+ 描述的代码是否属实;拿得出反例/实证的才标 🔴 真问题,只是'觉得没充分说明'但推不倒的标 🟡 待澄清,
64
+ 确认其实成立的标 ⚪ 误报并给出它为何成立。」
65
+ - 效果:模型被迫**为每条结论举证**(无论判真还是判误报),迎合空间被挤掉——这正是本 skill 要的。
66
+
67
+ ## Quick Reference
68
+
69
+ | 步骤 | 操作 |
70
+ |------|------|
71
+ | 1 | 用 Read 读取被审查对象(结论/计划/评审/设计/代码);必要时 Grep/Glob 取证,去现场核对而非凭记忆 |
72
+ | 2 | 把对象拆成一条条**独立、可被单独证伪**的原子主张 |
73
+ | 3 | 对每条问「哪里站不住脚」(见下方拷问清单),强迫找反例与证据 |
74
+ | 4 | 给每条分类:🔴 真问题 / ⚪ 误报 / 🟡 待澄清 |
75
+ | 5 | 每条都附**证据**与**为什么**(凭什么这么判,证据指向哪里);没证据就别下 🔴 结论 |
76
+
77
+ ## 第 3 步:对每条主张的拷问清单
78
+
79
+ 逐条追问,任意一条命中就标记下来:
80
+
81
+ - **证据不足?** —— 它的依据是什么?依据本身可靠吗,还是空口断言?
82
+ - **把假设当事实?** —— 哪些是已验证的事实,哪些只是"应该是这样"的假设被当成了前提?
83
+ - **想当然 / 跳步?** —— 推导链有没有缺环?"因为 A 所以 C"中间的 B 被默认了吗?
84
+ - **有反例?** —— 能不能举出一个让它崩掉的具体场景、输入、边界条件?
85
+ - **被现有代码/事实推翻?** —— 去 Grep/Read 核对,它描述的代码真长这样吗?实现真按它说的走吗?
86
+
87
+ ### 证明不了 ≠ 错
88
+
89
+ 一段文本里很多成立的主张本就不会附带完整证据——**省略不等于错误**。所以:
90
+
91
+ - 你能拿出反例 / 找到被现有代码推翻的实证 → 标 **🔴 真问题**。
92
+ - 你只是觉得它"没充分举证"、但也举不出反例 → 标 **🟡 待澄清**,并写明「缺哪个证据才能判定」,**不要**直接判 🔴。
93
+
94
+ 把「主张错误」与「主张未充分举证」混为一谈,是这类审查最常见的误报来源。
95
+
96
+ ## 输出格式
97
+
98
+ 三类同等呈现,不预设哪类一定有内容(真问题为 0 条是合法且常见的结论):
99
+
100
+ ```
101
+ ## 对抗审查结果
102
+
103
+ ### 🔴 真问题(拿得出反例/实证的)
104
+ 1. [主张/位置] 这条为什么站不住脚 → 证据(文件:行 / 反例 / 事实)→ 影响
105
+ 2. ...
106
+ (若无:「真问题:0 条——下方列出已尝试的攻击角度」)
107
+
108
+ ### ⚪ 误报(曾被怀疑、但其实成立)
109
+ 1. [主张/位置] 原审查/结论怀疑的点 → 为什么它其实成立 → 证据
110
+ 2. ...
111
+
112
+ ### 🟡 待澄清(未充分举证、但也推不倒)
113
+ 1. [主张/位置] 缺什么证据才能判定 → 需要用户/作者补充什么
114
+ 2. ...
115
+
116
+ ### 结论
117
+ 一句话定调:整体站得住脚 / 有 N 个真问题需修 / 关键前提待澄清。
118
+ ```
119
+
120
+ ## 注意事项
121
+
122
+ - **误报和漏报一样有害**(已在核心段强调,这里重申落地)。不要为了"显得严格"就把成立的结论硬说成问题——驳回一条主张同样要给证据,凭感觉拍砖等于制造新的误报。
123
+ - **找不到真问题就如实说**。如果对象本身扎实、你认真攻击后确实推不倒它,就直说"未发现真问题",并**列出你尝试过的反驳角度**(找过哪些反例、核对过哪些代码、质疑过哪些假设),证明你是真的攻击过、而非偷懒放水。
124
+ - **去现场,别凭记忆**。涉及代码/事实的主张,一律 Read/Grep 核对原文,不要用脑内印象当证据。
125
+ - **边界**:本 skill 用于质疑「结论 / 计划 / 既有评审 / 设计是否站得住脚」。若用户只是想给代码找冗余 / 反模式 / 做常规质量改进,那是 /simplify 的活,不要套用这里的「默认有罪」框架。
@@ -1,28 +1,26 @@
1
1
  # ============================================================
2
- # workflows/plan.yaml —— 复刻 Claude Code「plan」流程的动态工作流
2
+ # workflows/plan.yaml —— 复刻 Claude Code「plan」流程(Analyze→Verify→Synthesize→Critic→Gate)
3
3
  # ------------------------------------------------------------
4
- # 旗舰演示 AskUserQuestion + 「受工作流指导的有界 TAOR」+ 人机交互:
5
- # 探索(agent 只读调研) → 澄清(直接用工具问用户,带推荐项)
6
- # → 产出计划(agent 综合上下文落盘,遇取舍再回头问用户拍板) → 守门 assert。
7
- #
8
- # 与 adaptive-research 的区别:那条线演示「指导 + 随机应变」的旋钮,
9
- # 这条线把「交互(向用户提问)」也编进确定性骨架里 —— 既有 agent 节点的自主,
10
- # 又有 tool: AskUserQuestion 节点的「停下来问人」,二者共骑同一座 askBridge。
11
- #
12
- # 非交互宿主(-p / gateway / 子进程)下没有 UI handler,AskUserQuestion
13
- # 会自动选每题首项(约定=推荐项),整条流程照常跑完、绝不挂起。
4
+ # 把 Ultracode 动态工作流的多阶段编进确定性 DAG,全用现有 StepKind(不改引擎):
5
+ # Analyze : analyze(agent 只读探索) → extract_findings(llm 固化成可验证 claims) → clarify_depth(AskUserQuestion 人机交互)
6
+ # Verify : verify_findings(type:vote 红队对抗——对每条 finding 反向提问证伪,存活的才进下游)
7
+ # Synthesize: draft_plan(agent 综合"通过验证的结论"+用户选择,写 ./PLAN.md)
8
+ # Critic : critic_plan(skill:adversarial-review 反向提问审稿,把审稿意见追加进 ./PLAN.md)
9
+ # Gate : verify(assert 守门,确认 ./PLAN.md 确实生成)
10
+ # 非交互宿主(-p/gateway)下 AskUserQuestion 自动选推荐项、vote 走 LLM,整条流程照常跑完。
11
+ # ------------------------------------------------------------
12
+ # 注:critic 阶段用 skill: 节点 dogfood 仓库自带的 adversarial-review skill —— 演示
13
+ # 「同一套对抗审查方法既能 standalone(/adversarial-review)用、也能在 workflow 里被复用」。
14
+ # skill 双源查找(cwd 优先、packageRoot fallback);万一异地 cwd 缺该 skill,
15
+ # critic 的 onError:continue 兜底——审稿出岔不应推翻已写好的计划。
14
16
  # ============================================================
15
17
  name: plan
16
18
  description: |
17
- 受工作流指导 + 可向用户提问 + 有界 TAOR 的动态计划流程。
18
- - 先用有界子 agent 只读调研目标,梳理关键事实与未决点(不写盘、不副作用);
19
- - 再用 AskUserQuestion 直接问用户「计划要做到多详细」(带推荐项的单选);
20
- - 然后子 agent 综合调研与用户选择产出中文实现计划落到 ./PLAN.md,
21
- 遇到取舍 / 模糊点可再调 AskUserQuestion 让用户拍板;
22
- - 最后 assert 守门,确认 PLAN.md 确实生成。
23
- 这是 minimal-agent 的旗舰演示:把「探索→澄清→(带推荐的)选择→产出计划」
24
- 编成确定性骨架,每个 agent 节点内是有界 TAOR,交互骑在 tool_call 回路上。
25
- version: "0.1"
19
+ 受工作流指导 + 红队对抗验证 + 反向提问审稿 + 人机交互的动态计划流程。
20
+ Analyze(探索+固化+问深度) → Verify(vote 红队证伪候选结论) → Synthesize(综合通过验证的结论写 PLAN.md)
21
+ → Critic(反向提问审稿,把意见追加进 PLAN.md) → Gate(assert 守门确认文件生成)。
22
+ minimal-agent 的旗舰演示。
23
+ version: "0.2"
26
24
 
27
25
  inputs:
28
26
  - name: goal
@@ -31,19 +29,41 @@ inputs:
31
29
  description: "要做的事 / 目标"
32
30
 
33
31
  steps:
34
- # 1. 探索:agent 只读调研,自主用 Read/Grep/Glob 梳理事实与未决点(不写盘)
35
- - id: research
32
+ # ===================== Analyze =====================
33
+ # [Analyze-1] 只读探索:agent 自主用 Read/Grep/Glob 摸清现状(不写盘、不副作用)
34
+ - id: analyze
36
35
  agent: |
37
36
  只读调研目标「${inputs.goal}」相关的代码 / 资料:用 Read、Grep、Glob 工具
38
- (不要写文件、不要执行副作用命令)摸清现状,梳理出 3-6 条关键事实
39
- 以及 1-3 个仍然未决 / 需要用户拍板的点。
40
- 用简洁的中文 markdown 列点整理后直接作为你的最终回答返回,供后续步骤参考。
37
+ (不要写文件、不要执行副作用命令)摸清现状,整理出 3-6 条候选关键事实
38
+ 以及 1-3 个仍未决 / 需用户拍板的点,用简洁中文 markdown 列点返回。
41
39
  allowed_tools: [Read, Grep, Glob]
42
40
  capture:
43
- content: findings
41
+ content: analysis
42
+
43
+ # [Analyze-2] 固化成可验证 claims:llm 单轮 + output_schema,把笔记抽成数组(供 vote 逐条验证)
44
+ - id: extract_findings
45
+ llm: |
46
+ 从下面的调研笔记中抽取「候选关键事实」与「未决问题」,原样保留信息、不要新增臆测。
47
+ 调研笔记:
48
+ ${analysis}
49
+ output_schema:
50
+ type: object
51
+ additionalProperties: false
52
+ required: [findings, open_questions]
53
+ properties:
54
+ findings:
55
+ type: array
56
+ items: { type: string }
57
+ description: "每条独立成句的候选关键事实(便于逐条对抗验证)"
58
+ open_questions:
59
+ type: array
60
+ items: { type: string }
61
+ description: "仍需进一步验证 / 用户拍板的点"
62
+ capture:
63
+ findings: findings
64
+ open_questions: open_questions
44
65
 
45
- # 2. 澄清:直接用 AskUserQuestion 工具问用户「计划深度」(演示 tool 节点交互)
46
- # 第一个选项是推荐项(label 末尾标「(推荐)」),非交互宿主会自动选它。
66
+ # [Analyze-3] 人机交互:直接用 AskUserQuestion 问「计划深度」(第一项=推荐,非交互自动选它)
47
67
  - id: clarify_depth
48
68
  tool: AskUserQuestion
49
69
  args:
@@ -60,30 +80,68 @@ steps:
60
80
  capture:
61
81
  content: depth_answer
62
82
 
63
- # 3. 产出计划:agent 综合 findings + 用户选择落盘 ./PLAN.md,
64
- # 遇取舍/模糊点可再调 AskUserQuestion 让用户拍板(带推荐项),写完用 Read 自检。
83
+ # ===================== Verify =====================
84
+ # [Verify] 红队对抗:vote 节点对每条 finding 反向提问证伪(voter 默认倾向 refuted=true)
85
+ # refuted 票数 >= threshold 的 finding 被驳回,只有存活的进下游 —— 杜绝未证实结论污染计划。
86
+ # 注:voter 偏向证伪,存活集可能偏少甚至为空;下游 draft_plan 对此做了 graceful degrade(见其提示)。
87
+ - id: verify_findings
88
+ type: vote
89
+ input: "findings"
90
+ voters_count: 3
91
+ threshold: 2
92
+ rules: |
93
+ 判断这条「调研结论」是否站得住脚。不要问"它对不对",要问"它哪里是错的":
94
+ 是否证据不足、把假设当事实、想当然、会被反例或现有代码/资料推翻。
95
+ 只有当你找不到任何合理反驳、且它确有依据时,才认定成立(refuted=false)。
96
+ capture:
97
+ survived: verified_findings
98
+ kept: kept_count
99
+ total: total_count
100
+
101
+ # ===================== Synthesize =====================
102
+ # [Synthesize] 综合产出:agent 用"通过验证的结论"+用户选择落盘 ./PLAN.md,遇取舍可再问用户
65
103
  - id: draft_plan
66
104
  agent: |
67
- 综合下面两份输入,为目标「${inputs.goal}」写一份中文实现计划,
68
- 用 Write 工具落到 ./PLAN.md(目录不存在就先创建)。
105
+ 综合下列输入,为目标「${inputs.goal}」写一份中文实现计划,用 Write 落到 ./PLAN.md
106
+ (目录不存在先创建)。
107
+
108
+ —— 通过红队对抗验证的结论(${kept_count}/${total_count} 条存活)——
109
+ ${verified_findings}
69
110
 
70
- —— 调研结论(findings)——
71
- ${findings}
111
+ —— 仍未决的问题 ——
112
+ ${open_questions}
72
113
 
73
- —— 用户对计划深度的选择 ——
114
+ —— 用户选择的计划深度 ——
74
115
  ${depth_answer}
75
116
 
76
117
  要求:
77
118
  - 计划详细程度遵循用户上面的选择;
78
- - 若过程中遇到方案取舍或关键信息模糊、继续做风险大,调用 AskUserQuestion
79
- 让用户拍板(每题第一个选项放你的推荐并在 label 末尾标「(推荐)」),
80
- 据用户回答继续;
81
- - 写完后用 Read 自检 ./PLAN.md 内容确实落好了再收尾。
119
+ - 关于上面"存活结论"为空的两种情形请分别处理:若原本就没抽出 finding,按目标从头调研;
120
+ 若是被红队全部驳回(存活 0 但 total>0),别盲信被否的结论,用 Read/Grep/Glob 重新取证后再写;
121
+ - 若遇方案取舍或关键信息模糊、继续做风险大,调 AskUserQuestion 让用户拍板
122
+ (每题第一个选项放推荐并在 label 末尾标「(推荐)」),据回答继续;
123
+ - 写完用 Read 自检 ./PLAN.md 内容确实落好了再收尾。
82
124
  allowed_tools: [Read, Grep, Glob, Write, AskUserQuestion]
83
125
  capture:
84
126
  content: plan_text
85
127
 
86
- # 4. 守门:确认计划文件确实生成,否则给出中文排查提示
128
+ # ===================== Critic =====================
129
+ # [Critic] 反向提问审稿:dogfood 仓库自带的 adversarial-review skill —— 同一套对抗审查
130
+ # 方法,既能 standalone(/adversarial-review)用,也能在 workflow 里被 skill: 复用。
131
+ # 产出由 skill 子 agent 直接 Edit/Write 追加进 ./PLAN.md(不 capture——下游无人消费)。
132
+ # onError:continue —— 审稿出岔(含异地 cwd 缺 skill)不应推翻已写好的计划。
133
+ - id: critic_plan
134
+ skill: adversarial-review
135
+ maxTurns: 25
136
+ input: |
137
+ 对当前目录下的 ./PLAN.md 做一次对抗审查(先用 Read 读它)。审完用 Edit / Write 在文件
138
+ 末尾追加一节 "## 审稿意见(反向提问对抗审查)",按 skill 的输出格式分
139
+ 「🔴 真问题 / ⚪ 误报 / 🟡 待澄清」三类列出并附结论(真问题为 0 条也如实写)。
140
+ 只新增这一节,不要重写或删改计划正文。
141
+ onError: continue
142
+
143
+ # ===================== Gate =====================
144
+ # [Gate] 守门:确认计划文件确实生成
87
145
  - id: verify
88
146
  type: assert
89
147
  condition: 'fileExists("./PLAN.md")'