5.5 KiB
5.5 KiB
在 LLM 智能体中集成 VisionL
让 LLM 通过 HTTP API 工具调用操控 VisionL 浏览器。
原理
VisionL daemon 提供完整的 REST API。LLM 将 API 调用注册为工具/函数(Function Calling), 在需要浏览网页时生成对应的 HTTP 请求。所有接口返回结构化 JSON,LLM 直接解析。
API 总览
| 方法 | 端点 | 功能 |
|---|---|---|
| POST | /pages |
打开页面 |
| GET | /pages |
列出所有页面 |
| GET | /pages/:id |
页面详情 |
| DELETE | /pages/:id |
关闭页面 |
| POST | /pages/:id/navigate |
跳转 |
| POST | /pages/:id/click |
点击元素 |
| POST | /pages/:id/type |
输入文本 |
| POST | /pages/:id/scroll |
滚动 |
| POST | /pages/:id/eval |
执行 JS |
| POST | /pages/:id/wait |
等待 |
| GET | /pages/:id/screenshot |
截图(base64) |
| GET | /pages/:id/text |
纯文本 |
| GET | /pages/:id/html |
HTML 源码 |
| GET | /pages/:id/cookies |
Cookie 列表 |
| POST | /pages/:id/cookies |
设置 Cookie |
| DELETE | /pages/:id/cookies/:name |
删除 Cookie |
| GET | /pages/:id/console |
控制台日志 |
| GET | /pages/:id/network |
网络请求日志 |
| GET | /profiles |
指纹配置列表 |
完整文档见 API 文档。
集成方式
方式一:Function Calling(推荐)
注册 visionl_api 工具,LLM 直接生成 HTTP 请求:
{
"type": "function",
"function": {
"name": "visionl_api",
"description": "通过 VisionL 浏览器操控网页。支持打开页面、点击、输入、截图、提取文本、执行JS、管理Cookie、查看网络请求等。",
"parameters": {
"type": "object",
"properties": {
"method": {
"type": "string",
"enum": ["GET", "POST", "DELETE"],
"description": "HTTP 方法"
},
"path": {
"type": "string",
"description": "API 路径,如 /pages、/pages/baidu/text"
},
"body": {
"type": "object",
"description": "请求体(仅 POST 需要)"
}
},
"required": ["method", "path"]
}
}
}
使用流程
- LLM 决策需要访问网页
- LLM 调用
visionl_api:POST /pages打开 baidu.com - 宿主程序执行 HTTP 请求,将 JSON 结果返回 LLM
- LLM 解析结果,获得页面 ID
p_xxx - LLM 继续:
GET /pages/p_xxx/text读取内容 - 或:
POST /pages/p_xxx/click点击搜索
方式二:多工具注册
将每个操作注册为独立工具(更细粒度):
[
{
"name": "visionl_open",
"description": "打开网页",
"parameters": {
"url": { "type": "string" },
"alias": { "type": "string" }
}
},
{
"name": "visionl_text",
"description": "获取页面文本内容",
"parameters": {
"page_id": { "type": "string" }
}
},
{
"name": "visionl_click",
"description": "点击页面元素",
"parameters": {
"page_id": { "type": "string" },
"selector": { "type": "string" }
}
}
]
方式三:LangChain 集成
from langchain.tools import BaseTool
import requests
class VisionLTool(BaseTool):
name = "visionl"
description = "浏览器操控工具。API 基础 URL: http://127.0.0.1:9527"
def _run(self, method: str, path: str, body: dict = None) -> str:
url = f"http://127.0.0.1:9527{path}"
resp = requests.request(method, url, json=body)
return resp.text
LLM 系统提示词建议
你可以使用 visionl_api 工具操控浏览器:
打开页面: POST /pages {"url":"...","alias":"..."}
页面文本: GET /pages/{id}/text
页面截图: GET /pages/{id}/screenshot (返回 base64)
点击元素: POST /pages/{id}/click {"selector":"#id"}
输入文本: POST /pages/{id}/type {"selector":"#id","text":"..."}
执行 JS: POST /pages/{id}/eval {"code":"..."}
滚动页面: POST /pages/{id}/scroll {"deltaY":300}
等待加载: POST /pages/{id}/wait {"ms":2000}
查看Cookie: GET /pages/{id}/cookies
网络日志: GET /pages/{id}/network
关闭页面: DELETE /pages/{id}
所有接口返回 {"ok":true,"data":{...}} 或 {"ok":false,"error":{...}}。
打开页面后记录返回的 page_id,后续操作使用该 id。
页面在被显式 kill 之前永远存活,可跨多轮对话复用。
多页面并行管理
LLM 同时打开多个页面,通过别名区分:
LLM: POST /pages {"url":"https://docs.python.org","alias":"py"}
→ {"ok":true,"data":{"id":"p_aaa",...}}
LLM: POST /pages {"url":"https://developer.mozilla.org","alias":"mdn"}
→ {"ok":true,"data":{"id":"p_bbb",...}}
LLM: GET /pages/py/text # 读 Python 文档
LLM: GET /pages/mdn/text # 读 MDN 文档
错误处理
// 失败示例
{"ok":false,"error":{"code":"PAGE_NOT_FOUND","message":"页面 py 不存在"}}
常见错误码及处理:
| 错误码 | HTTP | 处理建议 |
|---|---|---|
PAGE_NOT_FOUND |
404 | 页面已关闭,重新打开 |
DAEMON_UNREACHABLE |
502 | 启动 daemon 或稍后重试 |
TIMEOUT |
408 | 页面加载慢,重试或增加等待 |
ALIAS_EXISTS |
409 | 换别名或直接用 page_id |
反检测能力
VisionL 内置多层反检测,使自动化访问尽可能不被简单人机验证拦截:
navigator.webdriver→false- 真实 Chrome User-Agent 和请求头
- Canvas/WebGL/Audio 指纹加噪
- 屏幕分辨率和视口合理性
- 权限状态模拟
- 3 套指纹模版可切换
详见 反检测设计文档。