内容
<div align="center">
```
████████╗███████╗██████╗ ██╗ ██╗
╚══██╔══╝██╔════╝██╔══██╗╚██╗██╔╝
██║ █████╗ ██████╔╝ ╚███╔╝
██║ ██╔══╝ ██╔══██╗ ██╔██╗
██║ ███████╗██║ ██║██╔╝ ██╗
╚═╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝
```
**浏览器代理内存。原始CDP。不依赖Playwright。**
[](https://github.com/ixchio/terx/actions)
[](https://pypi.org/project/terx/)
[](LICENSE)
[](https://python.org)
</div>
---
浏览器代理重复执行耗费巨大的工作。
它们登录到相同的仪表盘,重新发现相同的按钮,解析相同的屏幕,并花费模型令牌在已经解决的工作流程上。
TERX是一个用于浏览器代理的重放内存层。
运行1:您的代理找出路径。TERX将确切的Chrome DevTools协议(CDP)命令记录到本地SQLite缓存中。
运行2及以后:TERX直接重放CDP命令。无需LLM调用,无需截图解析,也无需重复推理循环。
<div align="center">
<img src="https://raw.githubusercontent.com/ixchio/terx/main/docs/assets/terx-demo.gif" alt="TERX本地重放演示" width="100%">
</div>
```
运行1:代理正常运行 3.05秒 · 1,985 个令牌 · $0.0065
TERX悄悄记录CDP命令
运行2:TERX重放 0.090秒 · 0 个令牌 · $0.0000
运行50:TERX重放 ~0.09秒 · 0 个令牌 · $0.0000
```
---
## 数据
真实测量。真实LLM(`openai/gpt-oss-120b` via Groq)。令牌计数来自API响应头。
| 任务 | 代理 | TERX | 加速比 | 令牌 |
|:-----|------:|-----:|--------:|-------:|
| 用户登录 | 3.05秒 · $0.0065 | **0.090秒 · $0** | 34.0倍 | 1,985 → 0 |
| 搜索 + 过滤 | 17.82秒 · $0.0108 | **0.099秒 · $0** | 179.3倍 | 2,634 → 0 |
| 多步骤注册 | 41.05秒 · $0.0142 | **0.103秒 · $0** | 399.4倍 | 4,339 → 0 |
| 数据表格 | 11.27秒 · $0.0093 | **0.088秒 · $0** | 128.7倍 | 1,756 → 0 |
| **平均值** | **160.93秒总计 · $0.0925** | **0.926秒总计 · $0** | **173.9倍** | **23,782 → 0** |
缓存命中率:**10/10**。复制:`GROQ_API_KEY=... python -m terx.benchmarks.real_agent`
完整方法 → [docs/benchmarks.md](https://github.com/ixchio/terx/blob/main/docs/benchmarks.md)
无需API密钥证明路径:
```bash
terx demo
terx eval-local
```
这些命令运行真正的无头Chrome浏览器,针对本地页面,并验证冷记录、热重放、变量、数据脱敏、后条件和重放报告。
---
## 安装
```bash
pip install terx
```
---
## 使用
**选项1:MCP服务器** — 与Claude Desktop、Cursor、Windsurf一起使用。
```bash
google-chrome --remote-debugging-port=9222 --no-first-run
terx-server
```
`mcp.json`:
```json
{ "mcpServers": { "terx": { "command": "terx-server" } } }
```
对于可重复的工作流程,请用以下内容包装浏览器操作:
```text
browser_task_start("登录到仪表盘")
...正常浏览器工具...
browser_task_finish(success=true)
```
在下一次匹配运行中,`browser_task_start`立即重放缓存的CDP序列。
每个任务响应都包含一个结构化的重放报告,其中包含重放的命令、使用的变量、删除的字段、后条件元数据和突变守卫统计。
---
**选项2:Python库** — 包装您现有的代理。
```python
from terx.cdp.session import BrowserSession
from terx.cache.cache import MemoryCache, session_for
cache = MemoryCache()
async with BrowserSession() as session:
bridge = session.bridge()
variables = {"email": "user@example.com", "password": "..."}
async with session_for(
cache,
bridge,
"登录到Salesforce",
variables=variables,
postcondition={"text_contains": "欢迎"},
) as ctx:
if ctx.hit:
await ctx.replay() # 0 个令牌,~80毫秒
else:
await your_agent.run() # 第一次:代理运行,TERX记录
```
与`variables`匹配的键值存储为`{{email}}`、`{{password}}`等。
敏感字段(如密码/令牌/API密钥输入)默认会被删除。
设置`TERX_REDACT_ALL_TEXT=1`以强制所有键入值通过占位符。
设置`TERX_REDACT_FIELDS=tenant,workspace`以添加自定义敏感标签。
---
**选项3:浏览器使用样式适配器** — 用异步`run()`包装任何代理对象。
```python
from terx.integrations.browser_use import wrap_browser_use
agent = BrowserUseAgent(...) # 或任何具有run()的Browser Use样式对象
agent = wrap_browser_use(
agent,
cache=cache,
bridge=bridge,
task="登录到仪表盘",
variables={"email": "...", "password": "..."},
postcondition={"text_contains": "欢迎"},
)
result = await agent.run()
```
---
## 工作原理
三件事情,每件事情都做一项工作:
**CDP桥接器** — 原始异步WebSocket到Chrome。无Playwright子进程。无Selenium。直接线协议。`<50毫秒`启动,`~2MB` RAM。
**DOM提取器** — 读取Chrome的可访问性树,而不是原始HTML。为交互元素分配稳定的数字ID。计算模糊结构哈希,在CSS重构和A/B测试中生存,无需破坏缓存命中。
**肌肉记忆缓存** — SQLite。在任务成功时:存储由`(domain, dom_hash, task)`键控的CDP命令序列。在未来运行中:直接重放。使用`INSERT OR IGNORE` — 第一次成功的记录是规范的,永远不会被静默覆盖。
在重放时,TERX重新快照DOM,并通过匹配`role + label`将旧的`backendNodeId`转换为当前的等价项 — 因此即使在Chrome重新启动后,重放仍然有效。
TERX还在重放后验证可选的后条件。如果重放执行命令但落在错误的页面上,则不计为命中。
在重放期间,MutationObserver守卫跟踪DOM变化,并在异常变化漂移发生之前引发,从而防止可疑的重放被视为健康。
`terx` CLI为操作员提供缓存可见性:
```bash
terx doctor
terx stats
terx inspect --domain app.example.com
terx purge app.example.com
```
---
## 为什么不使用Playwright?
Playwright是一个完整的浏览器自动化框架。TERX是一个精简的重放/内存层,用于已经知道如何驱动Chrome的代理。
| | Playwright | TERX |
|:--|:--:|:--:|
| 跨运行的内存 | ✗ | ✓ |
| 原始CDP(无子进程) | ✗ | ✓ |
| 每个实例的RAM | ~120MB | ~2MB |
| 与任何代理一起工作 | ✗ | ✓ |
| 内置MCP服务器 | ✗ | ✓ |
---
## MCP工具
`browser_task_start` `browser_task_finish` `browser_get_state` `browser_navigate`
`browser_click` `browser_click_at` `browser_type` `browser_screenshot`
`browser_screenshot_get` `browser_scroll` `browser_new_tab` `cache_stats`
`cache_invalidate`
截图返回哈希引用,而不是base64大二进制块 — 无上下文窗口污染。
导航验证URL方案 — 阻止`javascript:` `data:` `file:`注入。
任务包装器记录成功的工作流程,并在无需另一个LLM调用的情况下重放缓存命中。
任务包装器接受`variables`和`postcondition`,用于安全的参数化重放。
任务包装器还返回`report`对象,以便MCP客户端可以审计TERX执行的操作。
---
## 路线图
- [x] 原始CDP桥接器
- [x] AX树提取器 + 稳定元素ID
- [x] 模糊结构哈希器
- [x] 肌肉记忆缓存(SQLite,INSERT OR IGNORE)
- [x] 模式版本控制 + 迁移
- [x] MCP服务器(13个工具)
- [x] 自我修复重放(DOM漂移时的LLM回退)
- [x] 真实LLM基准测试套件(`terx-bench-real`)
- [x] 参数化重放 — `{{email}}`变量插值
- [x] 键入的密码/令牌/API密钥字段的机密删除
- [x] 重放后条件
- [x] 浏览器使用样式适配器
- [x] MutationObserver重放漂移守卫
- [x] CLI医生/统计/检查/清除
- [x] 本地Chrome评估套件(`terx eval-local`)
---
## 文档
[ixchio.github.io/terx](https://ixchio.github.io/terx) · [快速入门](https://github.com/ixchio/terx/blob/main/docs/quickstart.md) · [基准测试](https://github.com/ixchio/terx/blob/main/docs/benchmarks.md) · [架构](https://github.com/ixchio/terx/blob/main/docs/development.md) · [项目结构](https://github.com/ixchio/terx/blob/main/docs/project-structure.md) · [舞台管理](https://github.com/ixchio/terx/blob/main/docs/stagehand.md) · [变更日志](https://github.com/ixchio/terx/blob/main/docs/changelog.md)
---
## 开发
```bash
git clone https://github.com/ixchio/terx && cd terx
pip install -e ".[dev]"
pytest tests/ -v
terx demo # 本地Chrome演示,带有变量和数据删除
terx eval-local # 确定性本地浏览器重放评估套件
terx-bench # 建模基准(无需API密钥)
GROQ_API_KEY=... terx-bench-real # 真实LLM运行
```
---
MIT · 由 [ixchio](https://github.com/ixchio) 构建