Skip to content

Commit 236a330

Browse files
committed
Add critic_features: per-step critic bundle + rule-based scorer
trajectory_eval scores a whole trajectory with no per-step evidence; agent_trace emits spans not quality; agent_replay stores steps but doesn't score. Compose action_effect + observation_delta + postcondition into one per-step record, then a deterministic rule-based scorer gives {outcome, process_score, reasons} (no model), and to_judge_prompt renders it for an optional LLM-as-judge.
1 parent 88e4a85 commit 236a330

15 files changed

Lines changed: 357 additions & 0 deletions

File tree

README/WHATS_NEW_zh-CN.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# 本次更新 — AutoControl
22

3+
## 本次更新 (2026-06-24) — 逐步评审特征 + 规则式步骤评分
4+
5+
把为代理步骤评分所需的证据打包,并内建规则式评分器。完整参考:[`docs/source/Zh/doc/new_features/v177_features_doc.rst`](../docs/source/Zh/doc/new_features/v177_features_doc.rst)
6+
7+
- **`build_critic_record` / `score_step_rule_based` / `to_judge_prompt`**(`AC_build_critic_record``AC_score_step`):`trajectory_eval` 对整条轨迹评分而无逐步证据;`agent_trace` 发出 span 而非质量;`agent_replay` 保存步骤却不评分。本功能把 `action_effect` + `observation_delta` + `postcondition` 组合成单一逐步记录,接着 `score_step_rule_based` 给出确定性的 `{outcome, process_score, reasons}`(不需模型),`to_judge_prompt` 把它渲染给可选的 LLM-as-judge。纯标准库聚合器;不导入 `PySide6`
8+
39
## 本次更新 (2026-06-24) — 标题与正文分类 + 文档大纲
410

511
以高度区分标题与正文,并建立文档大纲。完整参考:[`docs/source/Zh/doc/new_features/v176_features_doc.rst`](../docs/source/Zh/doc/new_features/v176_features_doc.rst)

README/WHATS_NEW_zh-TW.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# 本次更新 — AutoControl
22

3+
## 本次更新 (2026-06-24) — 逐步評審特徵 + 規則式步驟評分
4+
5+
把為代理步驟評分所需的證據打包,並內建規則式評分器。完整參考:[`docs/source/Zh/doc/new_features/v177_features_doc.rst`](../docs/source/Zh/doc/new_features/v177_features_doc.rst)
6+
7+
- **`build_critic_record` / `score_step_rule_based` / `to_judge_prompt`**(`AC_build_critic_record``AC_score_step`):`trajectory_eval` 對整條軌跡評分而無逐步證據;`agent_trace` 發出 span 而非品質;`agent_replay` 保存步驟卻不評分。本功能把 `action_effect` + `observation_delta` + `postcondition` 組合成單一逐步記錄,接著 `score_step_rule_based` 給出確定性的 `{outcome, process_score, reasons}`(不需模型),`to_judge_prompt` 把它渲染給可選的 LLM-as-judge。純標準函式庫聚合器;不匯入 `PySide6`
8+
39
## 本次更新 (2026-06-24) — 標題與內文分類 + 文件大綱
410

511
以高度區分標題與內文,並建立文件大綱。完整參考:[`docs/source/Zh/doc/new_features/v176_features_doc.rst`](../docs/source/Zh/doc/new_features/v176_features_doc.rst)

WHATS_NEW.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# What's New — AutoControl
22

3+
## What's new (2026-06-24) — Per-Step Critic Features + Rule-Based Step Scorer
4+
5+
Bundle the evidence to score an agent step, with a built-in rule-based scorer. Full reference: [`docs/source/Eng/doc/new_features/v177_features_doc.rst`](docs/source/Eng/doc/new_features/v177_features_doc.rst).
6+
7+
- **`build_critic_record` / `score_step_rule_based` / `to_judge_prompt`** (`AC_build_critic_record`, `AC_score_step`): `trajectory_eval` scores a whole trajectory with no per-step evidence; `agent_trace` emits spans not quality; `agent_replay` stores steps but doesn't score. This composes `action_effect` + `observation_delta` + `postcondition` into one per-step record, then `score_step_rule_based` gives a deterministic `{outcome, process_score, reasons}` (no model needed) and `to_judge_prompt` renders it for an optional LLM-as-judge. Pure-stdlib aggregator; no `PySide6`.
8+
39
## What's new (2026-06-24) — Heading vs Body Classification + Document Outline
410

511
Tell headings from body text by height and build a document outline. Full reference: [`docs/source/Eng/doc/new_features/v176_features_doc.rst`](docs/source/Eng/doc/new_features/v176_features_doc.rst).
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
Per-Step Critic Features + Rule-Based Step Scorer
2+
=================================================
3+
4+
Scoring an agent's step needs the evidence in one place — what the action was, what changed,
5+
whether it landed on target, whether the declared postcondition held. ``trajectory_eval``
6+
scores a *finished whole trajectory* against a static rubric and has no per-step evidence;
7+
``agent_trace`` emits OTel spans (tokens / latency), not decision quality; ``agent_replay``
8+
persists ``{obs, action, result}`` but does no scoring. ``critic_features`` is the missing
9+
per-step layer: it composes ``action_effect`` (did it do anything, where),
10+
``observation_delta`` (how much changed) and ``postcondition`` (did the expected outcome hold)
11+
into one compact record, and ships a deterministic rule-based scorer so the feature works fully
12+
headless — leaving the optional LLM-as-judge to the integrator.
13+
14+
Pure-stdlib; composes existing pure modules; deterministic and unit-testable with no device.
15+
Imports no ``PySide6``.
16+
17+
Headless API
18+
------------
19+
20+
.. code-block:: python
21+
22+
from je_auto_control import (build_critic_record, score_step_rule_based,
23+
to_judge_prompt)
24+
25+
record = build_critic_record({"type": "click", "x": 480, "y": 260},
26+
before_elements, after_elements,
27+
postcondition={"appears": {"role": "dialog"}})
28+
score = score_step_rule_based(record)
29+
# {"outcome": True, "process_score": 1.0, "reasons": [...]}
30+
31+
prompt = to_judge_prompt(record) # compact text for an LLM-as-judge
32+
33+
``build_critic_record`` returns ``{action, effect, delta_counts}`` plus a ``postcondition``
34+
report when a spec is given. ``score_step_rule_based`` returns ``{outcome, process_score,
35+
reasons}`` — ``outcome`` is a binary success (the action did something *and* any postcondition
36+
held), ``process_score`` is a 0..1 quality from the effect class (halved if the postcondition
37+
failed). ``to_judge_prompt`` renders the record for an external judge.
38+
39+
Executor commands
40+
-----------------
41+
42+
``AC_build_critic_record`` (``action`` / ``before`` / ``after`` / ``postcondition`` /
43+
``radius`` → the record) and ``AC_score_step`` (``record`` → ``{outcome, process_score,
44+
reasons}``). They are exposed as the MCP tools ``ac_build_critic_record`` / ``ac_score_step``
45+
(read-only) and as the Script Builder commands **Build Critic Record** / **Score Step
46+
(rule-based)** under **Native UI**.

docs/source/Eng/eng_index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ Comprehensive guides for all AutoControl features.
199199
doc/new_features/v174_features_doc
200200
doc/new_features/v175_features_doc
201201
doc/new_features/v176_features_doc
202+
doc/new_features/v177_features_doc
202203
doc/ocr_backends/ocr_backends_doc
203204
doc/observability/observability_doc
204205
doc/operations_layer/operations_layer_doc
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
逐步評審特徵 + 規則式步驟評分
2+
==============================
3+
4+
為代理的步驟評分需要把證據集中一處——動作是什麼、變了什麼、是否落在目標、宣告的後置條件
5+
是否成立。``trajectory_eval`` 對*已完成的整條軌跡*依靜態準則評分,沒有逐步證據;
6+
``agent_trace`` 發出 OTel span(權杖 / 延遲),而非決策品質;``agent_replay`` 保存
7+
``{obs, action, result}`` 卻不評分。``critic_features`` 正是缺少的逐步層:它把 ``action_effect``
8+
(有無效果、落在何處)、``observation_delta``(變了多少)與 ``postcondition``(預期結果是否成立)
9+
組合成單一精簡記錄,並附上確定性的規則式評分器,使此功能可完整無頭運作——把可選的
10+
LLM-as-judge 留給整合者。
11+
12+
純標準函式庫;組合既有純模組;確定性、可在無裝置下單元測試。不匯入 ``PySide6``。
13+
14+
無頭 API
15+
--------
16+
17+
.. code-block:: python
18+
19+
from je_auto_control import (build_critic_record, score_step_rule_based,
20+
to_judge_prompt)
21+
22+
record = build_critic_record({"type": "click", "x": 480, "y": 260},
23+
before_elements, after_elements,
24+
postcondition={"appears": {"role": "dialog"}})
25+
score = score_step_rule_based(record)
26+
# {"outcome": True, "process_score": 1.0, "reasons": [...]}
27+
28+
prompt = to_judge_prompt(record) # 給 LLM-as-judge 的精簡文字
29+
30+
``build_critic_record`` 回傳 ``{action, effect, delta_counts}``,並在給定規格時附上
31+
``postcondition`` 報告。``score_step_rule_based`` 回傳 ``{outcome, process_score, reasons}``
32+
——``outcome`` 為二元成功(動作有效果*且*任何後置條件成立),``process_score`` 為依效果類別的
33+
0..1 品質(後置條件失敗時減半)。``to_judge_prompt`` 把記錄渲染給外部評審。
34+
35+
執行器指令
36+
----------
37+
38+
``AC_build_critic_record``(``action`` / ``before`` / ``after`` / ``postcondition`` /
39+
``radius`` → 該記錄)與 ``AC_score_step``(``record`` → ``{outcome, process_score, reasons}``)。
40+
兩者以 MCP 工具 ``ac_build_critic_record`` / ``ac_score_step``(唯讀)及 Script Builder 指令
41+
**Build Critic Record** / **Score Step (rule-based)**(位於 **Native UI** 分類下)形式提供。

docs/source/Zh/zh_index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ AutoControl 所有功能的完整使用指南。
199199
doc/new_features/v174_features_doc
200200
doc/new_features/v175_features_doc
201201
doc/new_features/v176_features_doc
202+
doc/new_features/v177_features_doc
202203
doc/ocr_backends/ocr_backends_doc
203204
doc/observability/observability_doc
204205
doc/operations_layer/operations_layer_doc

je_auto_control/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,10 @@
351351
from je_auto_control.utils.settle_detector import (
352352
SettleState, SettleTracker, is_settled, settle_point,
353353
)
354+
# Per-step critic feature bundle + rule-based step scorer
355+
from je_auto_control.utils.critic_features import (
356+
build_critic_record, score_step_rule_based, to_judge_prompt,
357+
)
354358
# Locate on-screen regions by colour (mask + connected components)
355359
from je_auto_control.utils.color_region import (
356360
find_color_region, find_color_regions,
@@ -1318,6 +1322,9 @@ def start_autocontrol_gui(*args, **kwargs):
13181322
"SettleTracker",
13191323
"settle_point",
13201324
"is_settled",
1325+
"build_critic_record",
1326+
"score_step_rule_based",
1327+
"to_judge_prompt",
13211328
"find_color_region",
13221329
"find_color_regions",
13231330
"ssim_compare",

je_auto_control/gui/script_builder/command_schema.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3303,6 +3303,29 @@ def _add_set_of_marks_specs(specs: List[CommandSpec]) -> None:
33033303
),
33043304
description="Index where a churn series first settles (offline settle check).",
33053305
))
3306+
specs.append(CommandSpec(
3307+
"AC_build_critic_record", "Native UI", "Build Critic Record",
3308+
fields=(
3309+
FieldSpec("action", FieldType.STRING,
3310+
placeholder='{"type":"click","x":50,"y":50}'),
3311+
FieldSpec("before", FieldType.STRING,
3312+
placeholder='[{"role":"button","x":0,"y":0}]'),
3313+
FieldSpec("after", FieldType.STRING,
3314+
placeholder='[{"role":"dialog","x":40,"y":40}]'),
3315+
FieldSpec("postcondition", FieldType.STRING, optional=True,
3316+
placeholder='{"appears":{"role":"dialog"}}'),
3317+
FieldSpec("radius", FieldType.INT, optional=True, default=64),
3318+
),
3319+
description="Per-step critic evidence (effect + delta + postcondition).",
3320+
))
3321+
specs.append(CommandSpec(
3322+
"AC_score_step", "Native UI", "Score Step (rule-based)",
3323+
fields=(
3324+
FieldSpec("record", FieldType.STRING,
3325+
placeholder='{"effect":{"effect":"changed_near_target"}}'),
3326+
),
3327+
description="Rule-based outcome + process score of a critic record.",
3328+
))
33063329
specs.append(CommandSpec(
33073330
"AC_consensus_element", "Native UI", "Grounding Consensus Element",
33083331
fields=(
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
"""Per-step critic feature bundle + a rule-based step scorer."""
2+
from je_auto_control.utils.critic_features.critic_features import (
3+
build_critic_record, score_step_rule_based, to_judge_prompt,
4+
)
5+
6+
__all__ = ["build_critic_record", "score_step_rule_based", "to_judge_prompt"]

0 commit comments

Comments
 (0)