docs: 项目架构设计文档(中文)及使用指南
- architecture.md: 完整架构设计(技术栈、API、CLI、生命周期、测试策略) - api.md: REST + WebSocket 接口文档 - cli.md: CLI 命令参考 - contributing.md: 开发规范与 JSON 转义要求 - quickstart.md: 快速开始指南 - llm-integration.md: 智能体集成指南 - examples.md: 8 个典型使用场景
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
# VisionL 使用示例
|
||||
|
||||
> 面向智能体和人工用户的典型场景。
|
||||
|
||||
## 场景一:搜索引擎查询
|
||||
|
||||
```bash
|
||||
# 1. 打开百度
|
||||
visionl page open https://www.baidu.com --alias search
|
||||
# → {"ok":true,"data":{"id":"p_1234","alias":"search",...}}
|
||||
|
||||
# 2. 输入搜索词
|
||||
visionl type search "#kw" "VisionL 浏览器"
|
||||
|
||||
# 3. 点击搜索
|
||||
visionl click search "#su"
|
||||
|
||||
# 4. 等待结果加载
|
||||
visionl wait search --selector "#content_left"
|
||||
|
||||
# 5. 获取页面文本
|
||||
visionl text search
|
||||
# → {"ok":true,"data":{"text":"搜索结果..."}}
|
||||
|
||||
# 6. 用完关闭
|
||||
visionl page kill search
|
||||
```
|
||||
|
||||
## 场景二:多页面信息收集
|
||||
|
||||
```bash
|
||||
# 同时打开多个信息源
|
||||
visionl page open https://news.ycombinator.com --alias hn
|
||||
visionl page open https://www.reddit.com/r/programming --alias reddit
|
||||
visionl page open https://github.com/trending --alias gh
|
||||
|
||||
# 分别提取内容
|
||||
visionl text hn
|
||||
visionl text reddit
|
||||
visionl text gh
|
||||
|
||||
# 用完批量关闭
|
||||
visionl page kill-all
|
||||
```
|
||||
|
||||
## 场景三:表单填写
|
||||
|
||||
```bash
|
||||
# 1. 打开登录页
|
||||
visionl page open https://example.com/login --alias login
|
||||
|
||||
# 2. 填写表单
|
||||
visionl type login "#email" "user@example.com"
|
||||
visionl type login "#password" "s3cret"
|
||||
|
||||
# 3. 提交
|
||||
visionl click login "button[type=submit]"
|
||||
|
||||
# 4. 截图验证
|
||||
visionl screenshot login -o logged-in.png
|
||||
```
|
||||
|
||||
## 场景四:页面截图
|
||||
|
||||
```bash
|
||||
# 打开并截图
|
||||
visionl page open https://www.example.com --alias page
|
||||
visionl wait page --ms 2000 # 等待渲染
|
||||
visionl screenshot page -o page.png
|
||||
|
||||
# 滚动后截图
|
||||
visionl scroll page --down 600
|
||||
visionl screenshot page -o page-scrolled.png
|
||||
```
|
||||
|
||||
## 场景五:JS 数据提取
|
||||
|
||||
```bash
|
||||
# 1. 打开页面
|
||||
visionl page open https://api.example.com/data --alias data
|
||||
|
||||
# 2. 执行 JS 提取 JSON 数据
|
||||
visionl eval data "JSON.parse(document.body.innerText)"
|
||||
# → {"ok":true,"data":{"result":{"items":[...]}}}
|
||||
|
||||
# 3. 获取页面标题
|
||||
visionl eval data "document.title"
|
||||
# → {"ok":true,"data":{"result":"API Data Page"}}
|
||||
```
|
||||
|
||||
## 场景六:REST 直通(高级)
|
||||
|
||||
```bash
|
||||
# 不使用子命令,直接调用 HTTP API
|
||||
visionl raw POST /pages '{"url":"https://example.com","alias":"test"}'
|
||||
# → {"ok":true,"data":{"id":"p_5678",...}}
|
||||
|
||||
visionl raw GET /pages/p_5678/text
|
||||
# → {"ok":true,"data":{"text":"..."}}
|
||||
|
||||
visionl raw DELETE /pages/p_5678
|
||||
# → {"ok":true,"data":null}
|
||||
```
|
||||
|
||||
## 场景七:智能体自动化工作流
|
||||
|
||||
LLM 通过 VisionL 完成机票比价:
|
||||
|
||||
```
|
||||
1. visionl page open https://flights.example.com --alias flights
|
||||
2. visionl type flights "#from" "北京"
|
||||
3. visionl type flights "#to" "上海"
|
||||
4. visionl type flights "#date" "2026-08-20"
|
||||
5. visionl click flights "#search"
|
||||
6. visionl wait flights --selector ".results"
|
||||
7. visionl text flights
|
||||
→ 提取票价信息
|
||||
8. visionl eval flights "document.querySelectorAll('.price').length"
|
||||
→ 统计结果数量
|
||||
9. visionl page kill flights
|
||||
```
|
||||
|
||||
## 场景八:长时间运行的任务
|
||||
|
||||
```bash
|
||||
# 打开监控面板
|
||||
visionl page open https://monitor.example.com --alias monitor --pretty
|
||||
# ✓ 页面已打开
|
||||
# ID: p_mon_001
|
||||
# URL: https://monitor.example.com
|
||||
# 别名: monitor
|
||||
|
||||
# ... 过了一段时间 ...
|
||||
|
||||
# 还是同一个页面
|
||||
visionl page list --pretty
|
||||
# ✓ 1 个页面
|
||||
# p_mon_001 monitor https://monitor.example.com active
|
||||
|
||||
# 刷新重新截图
|
||||
visionl navigate monitor https://monitor.example.com
|
||||
visionl screenshot monitor -o latest.png
|
||||
```
|
||||
@@ -0,0 +1,138 @@
|
||||
# 在 LLM 智能体中集成 VisionL
|
||||
|
||||
> 本文档介绍如何让 LLM 通过工具调用使用 VisionL-CLI 操控浏览器。
|
||||
|
||||
## 原理
|
||||
|
||||
LLM 将 `visionl` 注册为一个系统命令/工具,在需要浏览网页时调用。
|
||||
所有命令输出结构化的 JSON,LLM 直接解析结果并决定下一步操作。
|
||||
|
||||
## 集成方式
|
||||
|
||||
### 方式一:Function Calling(推荐)
|
||||
|
||||
在 LLM 的 function/tool 定义中注册 VisionL 命令。大多数 LLM 平台(OpenAI、Claude、本地模型)都支持。
|
||||
|
||||
**工具定义示例(OpenAI 格式):**
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "visionl",
|
||||
"description": "通过 VisionL 浏览器操控网页。子命令: page open|list|info|kill|kill-all, click, type, scroll, navigate, eval, wait, screenshot, text, html, daemon start|stop|status, raw",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"command": {
|
||||
"type": "string",
|
||||
"description": "完整 visionl 命令,例如 'page open https://example.com'"
|
||||
}
|
||||
},
|
||||
"required": ["command"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**使用流程:**
|
||||
|
||||
1. LLM 决策需要访问网页
|
||||
2. LLM 生成 `visionl page open <url>` 调用
|
||||
3. 宿主程序在终端执行该命令,将 JSON 输出返回给 LLM
|
||||
4. LLM 解析结果,继续决策(截图、点击、提取文本等)
|
||||
|
||||
### 方式二:MCP Server
|
||||
|
||||
可以封装一个 MCP(Model Context Protocol)Server,将 VisionL-CLI 包装为 MCP 工具:
|
||||
|
||||
```typescript
|
||||
// 伪代码示意
|
||||
server.tool(
|
||||
"visionl",
|
||||
"通过 VisionL 浏览器操控网页",
|
||||
{ command: z.string() },
|
||||
async ({ command }) => {
|
||||
const { stdout } = await exec(`visionl ${command}`);
|
||||
return JSON.parse(stdout);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
### 方式三:Agent 框架集成
|
||||
|
||||
与 LangChain、AutoGPT、CrewAI 等框架集成,注册为自定义工具。
|
||||
|
||||
**LangChain 示例:**
|
||||
|
||||
```python
|
||||
from langchain.tools import Tool
|
||||
import subprocess, json
|
||||
|
||||
def visionl_tool(command: str) -> str:
|
||||
result = subprocess.run(
|
||||
["visionl", *command.split()],
|
||||
capture_output=True, text=True
|
||||
)
|
||||
return result.stdout
|
||||
|
||||
visionl = Tool(
|
||||
name="visionl",
|
||||
description="浏览器操控工具。命令示例:page open <url>, click <id> <sel>, text <id>",
|
||||
func=visionl_tool,
|
||||
)
|
||||
```
|
||||
|
||||
## LLM Prompt 建议
|
||||
|
||||
在系统 prompt 中添加以下指引:
|
||||
|
||||
```
|
||||
你可以使用 visionl 命令操控浏览器:
|
||||
|
||||
1. visionl page open <url> [--alias <name>] — 打开页面
|
||||
2. visionl page list — 列出所有页面
|
||||
3. visionl text <id|alias> — 获取页面文本
|
||||
4. visionl screenshot <id|alias> — 截图(返回 base64)
|
||||
5. visionl click <id|alias> <selector> — 点击元素
|
||||
6. visionl type <id|alias> <selector> <text> — 输入文本
|
||||
7. visionl page kill <id|alias> — 关闭页面
|
||||
|
||||
所有命令返回 JSON。解析 ok 字段判断成功/失败。
|
||||
使用 --alias 给页面起别名方便后续引用。
|
||||
```
|
||||
|
||||
## 多页面管理
|
||||
|
||||
LLM 可以同时打开多个页面,通过别名区分:
|
||||
|
||||
```
|
||||
LLM: visionl page open https://docs.python.org --alias py
|
||||
LLM: visionl page open https://developer.mozilla.org --alias mdn
|
||||
LLM: visionl text py # 读 Python 文档
|
||||
LLM: visionl text mdn # 读 MDN 文档
|
||||
```
|
||||
|
||||
## 错误处理
|
||||
|
||||
LLM 应检查返回的 `ok` 字段:
|
||||
|
||||
```json
|
||||
// 失败示例
|
||||
{"ok":false,"error":{"code":"PAGE_NOT_FOUND","message":"页面 py 不存在"}}
|
||||
```
|
||||
|
||||
常见错误及处理:
|
||||
|
||||
| 错误码 | 处理建议 |
|
||||
|--------|---------|
|
||||
| `PAGE_NOT_FOUND` | 页面可能已被关闭,重新打开 |
|
||||
| `DAEMON_UNREACHABLE` | 等待几秒重试(自动拉起正在启动) |
|
||||
| `TIMEOUT` | 页面加载慢,重试或增加等待时间 |
|
||||
| `ALIAS_EXISTS` | 换一个别名或直接用 page ID |
|
||||
|
||||
## 安全注意事项
|
||||
|
||||
- VisionL daemon 仅监听 127.0.0.1,外部不可访问
|
||||
- 执行的 JS 代码在页面沙箱内运行,无法逃逸到宿主机
|
||||
- LLM 应避免在不可信页面执行敏感操作(自动填写密码等)
|
||||
@@ -0,0 +1,89 @@
|
||||
# VisionL 快速开始
|
||||
|
||||
## 安装
|
||||
|
||||
```bash
|
||||
# 1. 克隆仓库
|
||||
git clone ssh://git@git.yeij.top:2222/AskaEth/VisionL.git
|
||||
cd VisionL
|
||||
|
||||
# 2. 安装依赖
|
||||
npm install
|
||||
|
||||
# 3. 安装 Chromium 浏览器
|
||||
npx playwright install chromium
|
||||
|
||||
# 4. 构建
|
||||
npm run build
|
||||
|
||||
# 5. 全局安装 CLI(可选)
|
||||
cd packages/cli && npm link
|
||||
```
|
||||
|
||||
## 基本使用
|
||||
|
||||
### 启动 daemon
|
||||
|
||||
```bash
|
||||
visionl daemon start
|
||||
# ✓ Daemon 已启动 (端口 9527, PID 12345)
|
||||
```
|
||||
|
||||
### 打开一个页面
|
||||
|
||||
```bash
|
||||
visionl page open https://www.baidu.com --alias baidu
|
||||
# {"ok":true,"data":{"id":"p_a1b2c3d4","url":"https://www.baidu.com","alias":"baidu","title":"百度一下,你就知道","status":"active"}}
|
||||
```
|
||||
|
||||
### 获取页面文本
|
||||
|
||||
```bash
|
||||
visionl text baidu
|
||||
# {"ok":true,"data":{"text":"百度一下,你就知道\n..."}}
|
||||
```
|
||||
|
||||
### 搜索
|
||||
|
||||
```bash
|
||||
visionl type baidu "#kw" "VisionL"
|
||||
visionl click baidu "#su"
|
||||
```
|
||||
|
||||
### 截图
|
||||
|
||||
```bash
|
||||
visionl screenshot baidu -o result.png
|
||||
```
|
||||
|
||||
### 关闭页面
|
||||
|
||||
```bash
|
||||
visionl page kill baidu
|
||||
# {"ok":true,"data":null}
|
||||
```
|
||||
|
||||
### 停止 daemon
|
||||
|
||||
```bash
|
||||
visionl daemon stop
|
||||
```
|
||||
|
||||
## 无需手动启动 daemon
|
||||
|
||||
CLI 会自动检测 daemon 是否运行,未运行则自动启动:
|
||||
|
||||
```bash
|
||||
# 直接使用,CLI 自动拉起 daemon
|
||||
visionl page open https://example.com
|
||||
|
||||
# 关闭所有页面(daemon 继续运行)
|
||||
visionl page kill-all
|
||||
```
|
||||
|
||||
## 查看所有页面
|
||||
|
||||
```bash
|
||||
visionl page list
|
||||
# {"ok":true,"data":[{"id":"p_xxx","url":"...","alias":"...","title":"...","status":"active"}]}
|
||||
```
|
||||
Reference in New Issue
Block a user