内容
<h1 align="center">Agent Native Web</h1>
<p align="center">
<strong>自动化合约,而非屏幕。</strong><br>
为合作站点提供原生输入能力,以及为传统站点上的标准表单提供保守的HTTP桥接。
</p>
<p align="center">
<img src="./assets/hero.svg" alt="Agent Native Web直接自动化流程,从发现到接收" width="100%">
</p>
<p align="center">
<a href="https://github.com/avasis-ai/agent-native-web/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/avasis-ai/agent-native-web/actions/workflows/ci.yml/badge.svg"></a>
<img alt="状态:实验性" src="https://img.shields.io/badge/status-experimental-B8FFD8?style=flat-square&labelColor=08110F">
<img alt="Node.js 22.19 或更新版本" src="https://img.shields.io/badge/node-%3E%3D22.19-75A7FF?style=flat-square&labelColor=08110F">
<img alt="零浏览器依赖" src="https://img.shields.io/badge/browser_dependencies-0-B8FFD8?style=flat-square&labelColor=08110F">
<a href="./LICENSE"><img alt="MIT许可证" src="https://img.shields.io/badge/license-MIT-FF8066?style=flat-square&labelColor=08110F"></a>
</p>
合作站点会暴露一个清单、稳定的域名ID、直接媒体、序列化状态和类型化操作。包含的商店前端在不加载其人类页面、启动浏览器、读取DOM或截取屏幕截图的情况下完成身份验证的购买。单独的兼容性桥接器可以从惰性标准HTML推断出确定性的应用程序请求计划。
> [!IMPORTANT]
> 原生合约和推断的HTML是不同的信任轨道。`AgentWebClient`仍然拒绝仅支持HTML的站点,并带有`UNSUPPORTED_AGENT_SITE`;它绝不会将原生承载令牌静默发送到后备。`HttpBridgeClient`必须显式选择,从不执行JavaScript,并在未经审查的适配器提供更强有力的证据之前,将远程结果报告为未经验证。
## 运行证明
您需要Node.js 22.19或更新版本。
```bash
npm ci
npm run verify
npm run demo
```
演示发现站点,查询产品,读取有界源图像区域,预览和提交购物车更新,消耗其状态补丁,请求结账批准,并返回两个收据。
<p align="center">
<img src="./assets/terminal-demo.svg" alt="验证的无浏览器购买运行,无HTML、渲染、截图和浏览器依赖计数" width="100%">
</p>
以下是一个紧凑的复合值,由`npm run demo`和`npm run verify`内部的单独无浏览器扫描器发出;它不是一个字面上的单一命令响应信封:
```json
{
"inspection_mark": "NOVA731",
"receipts": 2,
"human_html_requests": 0,
"render_requests": 0,
"screenshot_requests": 0,
"production_browser_dependencies": 0
}
```
## 无浏览器兼容性
对于传统站点,桥接器获取原始HTTP,使用惰性WHATWG导向的解析器解析HTML,保留实际的表单语义(例如重复名称和提交者覆盖),并发出编辑过的`request_preview`。
```bash
node src/cli.mjs bridge inspect https://example.com/login
# 将可重用的cookie与一次性调度权限分开。
mkdir -m 700 .agentweb-private
printf '表单JSON(输入被隐藏):' >&2
IFS= read -r -s form_input
printf '\n' >&2
printf '%s' "$form_input" |
node src/cli.mjs bridge prepare https://example.com/login \
--action action_id --input - \
--session-file .agentweb-private/session.json \
--approval-file .agentweb-private/approval.json
# 审查preview.approval_binding_digest,然后提交相同的输入:
printf '%s' "$form_input" |
node src/cli.mjs bridge submit https://example.com/login \
--action action_id --input - \
--session-file .agentweb-private/session.json \
--approval-file .agentweb-private/approval.json \
--approval-binding-digest 'hmac-sha256:from-prepare' \
--allow-unverified-write
# 审批文件已消失;响应cookie保留用于下一次安全读取。
node src/cli.mjs bridge inspect https://example.com/account \
--session-file .agentweb-private/session.json
unset form_input
```
在任何提交之前,它会重新获取表单并检查其结构、完整规范化语义文本、可访问名称源、操作、提交者、验证模式、隐藏值、新检测的身份验证交互以及为目标源、路径和SameSite上下文选择的精确Cookie头。公共审查文本保持有界,而私有新鲜度摘要涵盖完整的相关文本。每个可编辑控件都需要显式值:空字符串、`false`、`[]`或`null`必须有意选择,而不是继承不可见的HTML默认值。每个推断的请求都需要其绑定应用程序请求计划的批准和`--allow-unverified-write`确认。带有私钥的密钥HMAC用于机密指纹和每个不受信任的公共URL路径段,而不是离线可猜测的哈希。结果是一个具有单独调度状态和结果状态的`attempt_receipt`;HTTP 200、重定向或新cookie不会被误标为业务成功。
当前桥接器处理静态UTF-8 GET表单和URL编码的POST表单,包括普通的用户名/密码和用户提供的OTP字段以及精确源cookie jar。它拒绝跨源导航/操作、文件/图像提交者、多部分、暂时无法忠实表示的控件以及仅脚本工作流。直接检测到的已知CAPTCHA标记和仅passkey或OAuth授权表单生成类型化交接;启发式身份验证文本永远不会阻止,并且可以准备密码后备。OAuth元数据验证仅检查调用者提供的数据的保守语法;它不建立发行者信任或运行令牌流。桥接器还遵守相关的CSP表单限制和浏览器验证绕过。包含JavaScript的页面即使其静态表单仍然可准备,也被标记为较低保证。
<p align="center">
<img src="./assets/bridge-flow.svg" alt="HTTP表单桥接流程,显示原始HTML、强化网络验证、惰性表单编译、绑定请求计划、一次调度以及结果有限的尝试收据" width="100%">
</p>
桥接器不会加载CSS、图像或其他子资源,因此无法建立视觉可见性或相关性,并且不会读取任意页面图像。直接源媒体访问属于原生合约或审查适配器;当渲染像素是证据时,仍然需要截图。
在本地Apple Silicon验收运行中,100个惰性解析/编译样本测量了0.509毫秒的p50,100个完整的本地HTTP检查测量了0.942毫秒的p50。这些是桥接开销测量,而不是受控的Playwright比较。在您的机器上运行`npm run benchmark:bridge -- 100`。
参见[HTTP表单桥接器0.1草案](./docs/http-bridge.md),了解保证模型、身份验证矩阵、威胁边界、CLI流程和用例分析。[风景审查](./docs/landscape.md)比较了CloakBrowser、OpenCLI、AutomatiQ、WebMCP和主要的浏览器代理栈,而不声称相邻工作不存在。
## 合约原生自动化
| 问题 | UI驱动自动化 | Agent Native Web |
|---|---|---|
| 运行时目标 | 浏览器引擎中的渲染页面 | 类型化站点合约 |
| 身份 | 选择器、文本匹配、坐标 | 稳定域名ID |
| 读取 | DOM、辅助树、截图 | 作用域状态和RFC 6902补丁 |
| 图像 | 渲染像素或OCR | 原始字节和有界源区域 |
| 图表和地图 | 从表示中恢复数据 | 数据/规范或场景图 |
| 写入 | 点击、类型、等待 | 预览、确认、幂等提交 |
| 证据 | 日志、记录、截图 | 收据和序列化状态事件 |
| 覆盖 | 浏览器可访问接口 | 暴露合约的站点 |
| 不支持工作 | 工具特定后备 | 类型化拒绝,无渲染后备 |
HTTP桥接器现在为未修改站点的保守标准表单子集删除了浏览器。浏览器自动化仍然是任意JavaScript和视觉交互的兼容性路径。原生合约仍然是唯一可以提供站点权威效果预览、幂等提交和持久结果收据的轨道。
## 架构
两个表面都调用一个权威域核心。CLI和MCP服务器重用HTTP客户端;它们不包含第二个模拟存储或第二个策略实现。
<p align="center">
<img src="./assets/architecture.svg" alt="共享域核心,为人类HTML表面和直接代理接口提供媒体、状态和安全事务层" width="100%">
</p>
引用实现四个连接层:
- **资源:** 版本化实体、结构化查询、协商表示和稳定链接。
- **媒体:** 原始PNG字节、命名源区域、内容哈希、图表数据/规范和仓库场景图。
- **状态:** 键控语义基线,然后是SSE的JSON补丁事件流。
- **操作:** 严格模式、效果预览、审批、过时状态检查、幂等提交和持久收据。
兼容性桥接器位于该权威核心之外。它观察遗留HTTP,编译一个较低保证的请求候选者,并且从不将本地尝试收据升级为站点收据。保持这些平面分离可以防止推断的表单继承原生合约权限。
## 直接媒体
蓝色产品描述符命名一个`inspection-mark`区域,但不暴露其值。`NOVA731`仅存在于光栅像素中。客户端请求该50×50源区域,验证其哈希,并将字节馈送到样本解码器。
```bash
node src/cli.mjs media read-mark 'media:trailpack-blue:hero'
node src/cli.mjs media fetch 'media:trailpack-blue:hero' \
--region inspection-mark \
--output inspection.png
```
MCP工具`agent.media.read`返回与`ImageContent`相同的原始或区域字节。多模态模型可以在不捕获页面的情况下使用这些字节。图表和地图端点返回其源数据和场景图,因为代理不应从像素中重建已知数据。
## 安全写入
每个突变都遵循一个服务器拥有的路径:
```text
严格输入 → 预览 → 需要时审批 → 幂等提交 → 收据
```
预览验证参数,捕获相关修订,模拟效果,并在五分钟后过期。它不会创建持久的域更改。提交再次验证主体,检查捕获的修订,需要确认结账,记录一个事件,并存储收据。
每个提交都需要`Idempotency-Key`。使用相同的主题、预览和密钥重试会返回第一个收据。重用密钥进行另一个请求会返回`IDEMPOTENCY_CONFLICT`。测试套件发送20个并发重试并观察到一个突变。
推断的HTML写入 **不** 继承这些保证。它们使用`request_preview → approval → one dispatch → attempt_receipt`;桥接器不会重试模糊的POST,也不会声称上游幂等性或成功。
## 接口
| 接口 | 入口点 | 目的 |
|---|---|---|
| 发现 | `GET /agent/manifest.json` | 合约、身份验证、功能、适配器 |
| OpenAPI | `GET /openapi.json` | HTTP操作描述 |
| 协商 | `GET /products/:id` | HTML、Markdown、JSON-LD或实验性代理JSON |
| 查询 | `QUERY /api/agent/v1/entities` | 安全的结构化产品搜索 |
| 状态 | `GET /api/agent/v1/state?scope=cart` | 键控基线和序列 |
| 更改 | `GET /api/agent/v1/events?since=N` | SSE JSON补丁事件流 |
| 媒体 | `GET /api/agent/v1/media/:id` | 源元数据、哈希、区域、来源 |
| 预览 | `POST /api/agent/v1/actions/:action/preview` | 验证和公开效果 |
| 提交 | `POST /api/agent/v1/commits` | 重新验证和一次更改 |
| 收据 | `GET /api/agent/v1/receipts/:id` | 持久本地审计记录 |
| NLWeb | `POST /ask` | NLWeb 0.55响应结构适配器 |
| MCP | `node src/mcp.mjs` | 工具和二进制/JSON资源通过stdio |
Agent Resource Web配置文件和`application/agent+json`媒体类型仍处于实验阶段。实现使用现有的标准,只要它们适合,包括HTTP内容协商、JSON-LD、RFC 6902 JSON补丁、SSE、MCP、Schema.org和W3C风格的片段选择器。
## CLI
```bash
node src/cli.mjs discover
node src/cli.mjs query --colour blue --in-stock
node src/cli.mjs state --scope cart
node src/cli.mjs actions
node src/cli.mjs preview cart.add \
--args '{"product_id":"product:trailpack-blue","quantity":1}'
node src/cli.mjs events --since 0
node src/cli.mjs media data 'media:inventory:chart'
```
`agentweb bridge inspect|prepare|submit`在创建原生客户端之前路由,因此`AGENT_TOKEN`不会泄漏到检查的HTML源。表单字段值仅作为标准输入上的JSON接受;cookie仅通过专用会话状态进入。跨进程工作使用两个仅所有者的`0600`文件:可重用、精确源cookie状态和短期一次性审批,包含私有HMAC密钥。命令使用每个会话锁序列化。在批准的调度之前,CLI会持久地推进会话生成并删除审批;复制的审批无法重放对抗实时会话。然后,响应cookie被原子地持久化以供后续身份验证表单。这些文件是敏感的,不加密或防回滚。CLI以JSON写入成功结果,以JSON写入stderr的协议问题,并使用[记录的类别退出代码](./docs/http-bridge.md#cli)。
## MCP
启动HTTP服务,然后将MCP客户端指向stdio适配器:
```json
{
"command": "node",
"args": ["/absolute/path/to/agent-native-web/src/mcp.mjs"],
"env": {
"AGENT_BASE_URL": "http://127.0.0.1:4317",
"AGENT_TOKEN": "replace-this-token"
}
}
```
适配器实现MCP `2025-11-25`初始化、工具、资源列表和资源读取。身份验证保留在传输配置中,而不是工具参数中。
## 运行服务
```bash
AGENT_TOKEN='replace-this-token' npm start
```
人类商店前端运行在`http://127.0.0.1:4317/`。代理从`/agent/manifest.json`启动,不请求`/`。
Docker Compose以非特权用户和只读根文件系统运行服务:
```bash
AGENT_TOKEN='replace-this-token' docker compose up --build
```
独立服务器将状态、事件、收据和幂等性账本写入`data/state.json`。设置`AGENT_DATA_FILE=:memory:`进行一次性运行。
## 验证
```bash
npm run verify
npm run benchmark -- 100
```
最后一次本地验收运行通过了原生HTTP/CLI/MCP路径和对抗性桥接表单、身份验证、cookie/会话绑定、CSP、SSRF、重定向、漂移、审批、隐私、有界执行和模糊传输案例的94项测试。扫描器检查了20个生产源文件,在四个直接生产依赖项中发现了零个浏览器包或运行时钩子。
| 本地操作 | 样本 | p50 | p95 |
|---|---:|---:|---:|
| 类型化产品查询 | 100 | 1.737毫秒 | 3.212毫秒 |
| 作用域状态基线 | 100 | 1.423毫秒 | 1.825毫秒 |
| 直接源图像区域 | 100 | 2.838毫秒 | 3.334毫秒 |
| 惰性HTML解析 + 表单编译 | 100 | 0.265毫秒 | 1.007毫秒 |
| 完整本地HTTP表单检查 | 100 | 0.818毫秒 | 2.087毫秒 |
这些数字衡量了开发Apple Silicon机器上的本地开销。它们排除了模型时间,不构成与Playwright或CloakBrowser的受控比较。参见[VERIFICATION.md](./VERIFICATION.md),获取证据记录。
## 项目状态
标签`v0.1.0`证明了包含的商店前端的完整合约原生路径。默认分支添加了实验性的HTTP表单桥接器0.1草案。它对稳定的标准表单很有用,但它不是完整的浏览器替代品,不应作为未经身份验证的远程获取服务使用。
公共原生合约部署仍需要OAuth 2.0授权代码与PKCE(RFC 9700),事务数据库和出队,租户隔离,加密敏感字段,分布式限制和签名审计保留。公共桥接器部署还需要经过身份验证的本地/租户边界,出口允许列表,加密凭证保险库和审查站点适配器,用于后果严重的运营。
计划工作:
- 从演示域中提取两个配置文件一致性套件;
- 为一个经过身份验证的SaaS应用程序添加签名、版本固定适配器和后置条件验证器;
- 添加授权的工件句柄和有界多部分支持,无需接受任意文件系统路径;
- 添加OAuth保护的资源发现和外部用户代理交接,无需刮取登录页面;
- 发布受控的浏览器和合约原生基准测试工作负载;
- 测试互操作的IIIF、C2PA、OAuth和远程MCP部署。
## 文档
- [协议配置文件](./docs/protocol.md)
- [HTTP表单桥接器](./docs/http-bridge.md)
- [浏览器自动化景观](./docs/landscape.md)
- [采用指南](./docs/adopting.md)
- [安全边界](./docs/security.md)
- [验证记录](./VERIFICATION.md)
- [贡献指南](./CONTRIBUTING.md)
- [变更日志](./CHANGELOG.md)
## 贡献
欢迎提出问题和专注的拉取请求。在提出协议变更之前,请阅读[CONTRIBUTING.md](./CONTRIBUTING.md)。安全报告应遵循[SECURITY.md](./SECURITY.md)。
## 许可证
[MIT](./LICENSE)