jev-filter

托管执行

0.4 新增:操作/目标/值选择不充分时会在执行前返回 needs_review,默认胜出概率 0.55、前两名差距 0.10。独立 --verify-controls 检查唯一当前 checked/pressed/selected/值,失效的最终观察不能证明完成。观察支持显式无角色控件、带可见标签的透明控件和受守卫的嵌套垂直滚动;新标签页跟随仍不支持。详见策略与接入示例。

English

Jev Filter 不只过滤,也能执行。下面的命令都跑在程序自己掌控的循环里:程序枚举候选,Jev 在候选里选择,程序执行并校验结果。

命令 对象 作用
browse 网页(通过 DevTools 驱动 Chrome/Edge/Chromium,或 Camofox) 朝一个自然语言目标推进:点击、填入调用方提供的值、选下拉、滚动
desktop 一个 Windows 或 macOS 应用 同样的循环,作用在无障碍控件上;自绘界面用 OCR 兜底
extract 网页 把页面结构化成记录(表格行、文本块、链接),再选出相关的
survey 成千上万条记录 对每条记录做类型化判断,由代码汇总成分布、交叉表和代表样本

Jev 从不产出文字、选择器、坐标、命令或脚本。每个被执行的目标都是程序观察到的节点,执行前会重新核对它的身份和状态。

一步是怎么走的

flowchart LR
  O[观察:编号控件 + 可见文本] --> Q[一次 Jev 请求:操作 + 各操作的目标 + 填哪个值 + 是否不可逆]
  Q --> G{程序门禁}
  G -->|DONE/BLOCKED 置信度低| Q
  G -->|支付/发送/删除类| P[暂停:needs_confirmation + 令牌]
  G -->|字段没有可用的值| S[跳过一次;卡住则 needs_value]
  G -->|通过| F[新鲜度校验]
  F -->|已变化| O
  F -->|未变化| X[执行]
  X --> L[记录这一步] --> O

浏览器:browse

jev-filter browse --url https://shop.example/ \
  --goal 'Search for red shoes in the Shoes category, in stock only' \
  --value query='red shoes' \
  --verify-url 'results.*cat=shoes'

不可逆动作会暂停

两个独立信号判定不可逆:一是作用在提交型控件(按钮、链接、菜单项)上的关键词规则,例如"支付""下单""发送""删除"及对应英文;二是 Jev 对"下一步是否会产生用户无法撤销的效果"的概率。勾选框、选项卡、选项永远不拦。被拦下时,运行以待执行动作和 confirm_token 结束:

jev-filter browse --url https://shop.example/ --goal 'Buy the cheapest red shoes in size 42' \
  --value query='red shoes' --keep-open
# → {"status":"needs_confirmation","pending":{"label":"Place order"},
#    "confirm_token":"f25e…:e2","session":{"cdp_port":58111,"target_id":"0A92…"}}

# 用户同意后:
jev-filter browse --cdp-port 58111 --target-id 0A92… --confirm f25e…:e2 \
  --goal 'Buy the cheapest red shoes in size 42' --verify-text 'order has been placed' --close-browser

令牌绑定了页面指纹和动作,页面有任何变化都会以过期拒绝。默认续跑只执行被确认的那一个动作,校验后结束(--continue-after-confirm 可继续)。--allow-irreversible 对单次运行关闭门禁。

程序会在目标后追加一句固定说明:不可逆步骤由程序把关,照常推进。没有这句时,以"购买""下单"结尾的目标会让 Jev 过早选 BLOCKED(探针测得概率 0.46–0.60,加上后 0.09–0.13)。

页面数据:extract

jev-filter extract --url 'https://shop.example/results?q=red' \
  --task 'In-stock shoes under $70' --analysis analysis.json

表格变成带表头的行(Product: Red Runner | Price: $59 | …),标题、列表项、段落、链接变成带所属章节的记录,之后走和 query 完全相同的契约:selected_ids、review_ids、上下文准入、输出投影都一样。不会点击任何东西。

桌面:desktop

pip install 'jev-filter[desktop] @ git+https://github.com/apixly-ai/jev-filter.git@v0.4.1'   # Windows:UI Automation + OCR;macOS:pyobjc
jev-filter desktop --list                  # 列出候选窗口
jev-filter desktop --window '^Invoice Tool$' \
  --goal 'Set the customer name to Ada Lovelace, choose the Pro plan and save' \
  --value name='Ada Lovelace' --verify-text 'saved Ada Lovelace'

桌面安全门禁

以下确定性检查都在任何 Jev 信号之前执行:

大量记录:survey

jev-filter survey --input tickets.jsonl --spec survey.json --format md
{
  "task": "What do customers contact support about, how do they feel, and who may churn?",
  "keep": ["product"],
  "screen": {"instructions": "The record is a genuine support request (not spam)."},
  "questions": {
    "topic": {"type": "choice", "instructions": "Main topic?",
              "criteria": {"billing": "…", "bug": "…", "shipping": "…", "other": "…"}},
    "sentiment": {"type": "score", "instructions": "How does the customer feel?",
                  "criteria": ["Angry", "Neutral", "Positive"]},
    "churn": {"type": "noul", "instructions": "Threatens to cancel or switch."}
  },
  "group_by": ["topic", "product"],
  "confidence_floor": 0.6
}

状态与退出码

状态 含义 退出码
done 目标完成且所有校验通过 0
unverified 报告完成但校验未通过 2
needs_confirmation 下一步不可逆,附 pending 和 confirm_token 2
needs_value 某字段需要调用方未提供的值 2
blocked 没有可推进的操作;reason 为 challenge、login_required、model_blocked、no_progress 或 repeating 2
dry_run --dry-run:决定的动作在 pending 里,没有执行 2
origin_blocked 导航离开了允许的来源 2
budget_exhausted 步数或决策预算用尽 2
error 传输或服务端失败,没有盲目重试 2

标准输出是紧凑结果(状态、操作与标签轨迹、用量、校验结果)。archive 指向的文件保存完整历史、每步决策的概率分布和延迟。

限制