cliany-site 文档
cliany-site 基于 LLM 和 Chrome CDP 协议,将任意网页操作自动化为可重复调用的 CLI 命令。核心流程:explore(探索)→ generate(生成适配器)→ run(执行)。
安装
PyPI 安装(推荐)
pip install cliany-site
源码安装
git clone https://github.com/pearjelly/cliany.site.git
cd cliany.site
pip install -e .
依赖 Python ≥ 3.11 和 Chrome/Chromium 浏览器(工具会自动检测并启动)。
配置 LLM
支持 Anthropic(Claude)和 OpenAI(GPT-4o)两种 provider,二选一:
# Anthropic Claude(推荐)
export CLIANY_LLM_PROVIDER=anthropic
export CLIANY_ANTHROPIC_API_KEY="sk-ant-..."
# OpenAI GPT-4o
export CLIANY_LLM_PROVIDER=openai
export CLIANY_OPENAI_API_KEY="sk-..."
也可以写入 .env 文件,查找顺序:~/.config/cliany-site/.env → ~/.cliany-site/.env → 项目目录 .env → 系统环境变量。
explore --json 遇到 LLM 网关、限流或服务暂不可用时会返回 E_LLM_UNAVAILABLE,并在 details.retryable、details.status_code 和 details.phase 中给出可重试上下文;错误消息会清洗原始 HTML 网关页。
10 分钟成功路径
首次运行先确认 CLI 可用。运行 cliany-site cases --status active 可查看每个已发布 active case 的安全首跑顺序:固定 SHA-256 安装、verify --strict、仅案例声明的登录和只读命令;它只提供指引,不会替你安装、登录、执行或覆盖。已安装或占用的目标始终从严格校验开始。只有 commands.py 可加载后才执行只读案例;否则先查看维护中的公开案例。不需要先配置 LLM key。准备好生成自己的命令时,再进入 配置 LLM 和 explore。
# 1. 查看 human 摘要和下一步
cliany-site doctor
# 2. 复制上一步 human `doctor` 按顺序打印的命令
# 未安装时是固定 HTTPS + SHA-256 安装、verify --strict、只读案例;
# 已安装或占用时从 verify --strict 开始。普通输出不含 data.summary 字段。
# 3. 自动化脚本才运行 JSON 路径
cliany-site doctor --json
# 当 data.summary.ready_for_demo_adapters=true 时,按
# data.summary.demo_adapter_quickstart.recommended_commands 的顺序运行;candidate 不会进入该路径
# 4. 否则查看维护中的公开案例和各自的验证路径
cliany-site cases
# 5. 脚本使用机器可读案例目录
cliany-site cases --json
# 6. 准备好后再配置 LLM 并生成自己的命令
普通 doctor 只检查本地配置,不会真实调用 LLM provider。自动化读取 JSON 时,data.summary.ready_for_explore 与 generate_adapters.local_ready 只表示本地配置可用,local_blockers 只解释本地前提;只有 data.summary.ready_for_live_explore=true(或等价 capability 字段)才能放行真实 explore。provider 预检失败时,本地前提仍可保持 local_ready=true,同时整体 ready=false、live_blockers=["llm_live"];按 next_step 重跑严格命令:
cliany-site doctor --llm-live --require-capability generate_adapters --json
发布者也可以提供直接 HTTPS adapter 包;远程安装必须固定完成归档的 64 个字符小写十六进制 SHA-256,并会复用同一套包校验:
cliany-site market publish github.com --version 1.0.0 --json
发布成功 JSON 中的 data.package_sha256 是完成归档的 64 个字符小写十六进制 SHA-256 摘要;将该值填入发布者提供的通用 HTTPS 安装命令:
cliany-site market install https://publisher.example/releases/adapter.cliany-adapter.tar.gz --sha256 <64-hex-sha256> --dry-run --json
--dry-run 成功只说明分发包可用,不会安装 adapter;已安装同名 adapter 时,预检会返回 installed_version 与 incoming version,并以 requires_force=true 的只读计划表示仍需显式覆盖。若 installed_version=null,仍以 would_replace 判断 adapter 是否存在。运行 verify <domain> 前,请移除该选项完成安装。
维护中的公开 demo 已在案例目录中提供 release 固定 URL 和 SHA-256。先查看案例,再复制首条安装命令:
cliany-site cases --case-id suitecrm-accounts
doctor — 环境检查
检查 Chrome CDP 连通性、LLM Key 有效性、目录结构。
cliany-site doctor [--json] [--llm-live]
准备运行 explore 时,使用 cliany-site doctor --llm-live --require-capability generate_adapters --json 做一次真实 provider 预检;只有它成功,才继续生成新 adapter。
返回示例:
{"success": true, "data": {"cdp": true, "llm": true, "adapters_dir": true}}
login — 保存登录状态
打开目标 URL,等待用户在浏览器中完成登录,然后持久化 Cookie / LocalStorage。
cliany-site login "https://your-site.com" [--json]
explore — 探索工作流
核心命令。指定 URL 和任务描述,LLM 自动分析页面 AXTree,规划并执行操作路径,将结果生成为 Python/Click CLI 适配器。
cliany-site [ROOT OPTIONS] explore <url> <workflow> [OPTIONS]
Options:
--force 覆盖已有 adapter(无需确认)
--json JSON 输出
-i, --interactive 交互式探索,每步手动确认
--extend <domain> 增量扩展已有适配器
--record / --no-record 是否记录探索过程
--headless 和 --cdp-url 是根选项,必须放在 explore 前。前者让 cliany-site 启动无头 Chrome;后者连接已经运行的远程 CDP 浏览器。
示例:
# 基础探索
cliany-site explore "https://github.com" "搜索仓库并查看 README" --json
# 交互式(每步确认)
cliany-site explore "https://github.com" "管理 Issues" --interactive
# 增量扩展(不覆盖已有命令)
cliany-site explore "https://github.com" "创建 PR" --extend github.com
list — 查看适配器
cliany-site list [--json]
列出 ~/.cliany-site/adapters/ 目录下所有已生成的域名适配器及其命令。
执行适配器命令
生成适配器后,通过 cliany-site <domain> <command> 执行:
# 查看 github.com 适配器的所有命令
cliany-site github.com --help
# 执行搜索命令
cliany-site github.com search --query "browser automation" --json
# 从断点恢复
cliany-site github.com search --query "browser automation" --resume --json
数据命令的提取质量语义
生成的 list-、search-、read- 和 extract- 命令,以及包含 extract action 的任何命令,默认使用 expects_nonempty=true。零条数据、关键字段缺失和 partial 结果都会返回 E_EMPTY_RESULT,而不是只完成点击后报告成功。只有某个工作流的零匹配本来就是合法结果时,命令才可声明 expects_nonempty=false:零匹配仍返回 ok=true,同时继续提供 data.quality 作为行数和数据质量信号。失败的结构化对象行会额外在 data.quality.field_blank_rows 中按字段给出缺失或空白值的 1 起始结果行号,帮助定位字段映射或页面内容;成功结果不会增加该字段。重新 explore 某个命令会应用这条规则到新生成的代码,但不会静默改写已安装的旧 adapter;即使允许零匹配,关键字段缺失或 partial 结果仍然失败。
Python SDK
from cliany_site.sdk import ClanySite
import asyncio
async def main():
async with ClanySite() as cs:
result = await cs.verify("github.com")
if not result["success"]:
error = result["error"] or {}
raise RuntimeError(f"{error.get('code')}: {error.get('message')}")
print(result["data"]["results"][0])
asyncio.run(main())
SDK 方法统一返回 {success, data, error} 信封。verify(domain) 与 cliany-site verify <domain> --strict 使用相同的静态检查:安全目录名、metadata、生成模块安全、manifest 完整性,以及 commands.py 是否真正导出可加载的 Click group;它不会连接 Chrome 或 LLM。adapter 目录、metadata.json、commands.py、manifest 或 manifest 声明文件若为符号链接,会在读取内容或导入模块前以 security_issue 拒绝。根 CLI 直接执行 adapter 命令也会在导入 commands.py 前运行生成模块源码扫描:禁用模式和非 UTF-8 模块返回 E_VERIFY_STATIC / security_issue。存在 manifest 时,它还会校验每个声明文件的哈希;失配返回 E_VERIFY_STATIC / manifest_error。未安装 adapter 返回 ADAPTER_NOT_FOUND,静态校验失败返回带 results 诊断的 E_VERIFY_STATIC。execute 在启动浏览器前使用同一套本地静态契约。调用 explore 前仍需先通过严格的 live provider 预检;仅有配置过的凭据不代表 adapter 生成当前可用。
HTTP API
启动本地 REST API 服务:
# 默认 Chrome 连接
cliany-site serve --port 8080
# 让 cliany-site 为服务启动无头 Chrome
cliany-site --headless serve --port 8080
# 复用已运行的远程 CDP 浏览器
cliany-site --cdp-url "ws://chrome:9222" serve --port 8080
--headless 和 --cdp-url 都是根选项,必须写在 serve 之前。每次只选一条浏览器路径:前者为当前服务启动 Chrome,后者连接已有远程 Chrome。
| 端点 | 方法 | 说明 |
|---|---|---|
GET /health | GET | 确认服务可访问并返回已安装版本 |
GET /doctor | GET | 环境检查 |
GET /adapters | GET | 列出适配器 |
GET /verify?domain=<domain> | GET | 严格静态验证已安装 adapter,不连接 Chrome |
POST /explore | POST | 探索工作流 |
POST /execute | POST | 执行适配器命令 |
POST /login | POST | 捕获 Session |
curl -i http://localhost:8080/health
# {"status":"ok","service":"cliany-site","version":"<installed-version>"}
curl -i "http://localhost:8080/verify?domain=github.com"
curl -X POST http://localhost:8080/explore \
-H "Content-Type: application/json" \
-d '{"url": "https://github.com", "workflow": "搜索仓库"}'
GET /health 是 liveness probe:它确认 HTTP 服务可访问,并返回服务名和已安装版本;它不代表 Chrome/CDP 或 LLM provider 已就绪,请使用 GET /doctor 查看这些诊断。GET /verify 必须提供安全的 domain 查询参数,只运行静态 adapter 检查,不会连接 Chrome 或 LLM;无效目录名返回 E_INVALID_PARAM / 400,已安装但不可安全加载或核心文件为符号链接的 adapter 返回 E_VERIFY_STATIC / 422。POST /execute 在启动浏览器前使用同一套本地静态契约:它会在读取或导入前拒绝符号链接目录、metadata、命令模块或 manifest;若 manifest 存在,其声明文件必须是普通文件且哈希匹配,不会先启动浏览器。其他响应保留 SDK 信封:404 表示 adapter 或命令不存在,503 表示 Chrome 或 LLM 依赖暂不可用,500 表示意外服务端失败。写操作端点只接受 JSON 对象;params 必须是对象,force / dry_run 必须是布尔值。
YAML 工作流编排
# workflow.yaml
name: GitHub 搜索并查看详情
steps:
- name: 搜索仓库
adapter: github.com
command: search
params:
query: "cliany-site"
- name: 查看第一个结果
adapter: github.com
command: view
params:
repo: "$prev.data.results[0].name"
cliany-site workflow run workflow.yaml --json
cliany-site workflow validate workflow.yaml --json
批量执行
从 CSV/JSON 文件批量驱动适配器命令:
cliany-site workflow batch github.com search data.csv --concurrency 3 --json
环境变量参考
| 变量 | 默认值 | 说明 |
|---|---|---|
CLIANY_LLM_PROVIDER | — | anthropic 或 openai |
CLIANY_ANTHROPIC_API_KEY | — | Anthropic API Key |
CLIANY_OPENAI_API_KEY | — | OpenAI API Key |
CLIANY_OPENAI_BASE_URL | — | 自定义 OpenAI 兼容端点 |
CLIANY_CROSS_ORIGIN_IFRAMES | true | 是否递归采集跨域 iframe |
常见问题
Chrome 无法连接怎么办?
运行 cliany-site doctor --json 检查 CDP 状态。默认检查不会真实调用 LLM provider;在耗时较长的 explore 前,可以运行 cliany-site doctor --llm-live --require-capability generate_adapters --json 做一次严格 provider 门禁。若上游网关、限流、provider 连接或服务不可用,命令会以非零结果返回 E_LLM_UNAVAILABLE,完整检查数据保留在 error.details。Candidate 晋级时,如果 generate_adapters.ready=false,或 llm_live 返回 warning/error(例如 E_LLM_UNAVAILABLE provider connection failure),请停止本轮真实 explore,把 doctor JSON / 错误摘要作为 blocker 证据。工具会自动尝试启动 Chrome;如果失败,可手动启动:
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
--remote-debugging-port=9222 \
--user-data-dir=/tmp/chrome-debug
页面改版后命令失效?
小幅页面变化由 AXTree 模糊匹配和自愈机制自动处理。大幅改版时,用 --extend 增量重新探索即可:
cliany-site explore "https://your-site.com" "原有任务" --extend your-site.com
如何创建 candidate promotion issue?
推进 PyPI candidate 前,先按 Candidate Promotion Runbook(docs/candidate-promotion-runbook.md)跑 cliany-site doctor --llm-live --require-capability generate_adapters --json、adapter package、metadata validation 和 online smoke。PyPI 搜索案例的目标包名应保持 pypi.org-<version>.cliany-adapter.tar.gz,online smoke 使用 cliany-site pypi.org search-projects --query cliany-site --limit 5 --json。
先运行 cliany-site cases --status candidate --promotion-plan --json 读取 primary_issue_template_command 和 issue_template_json_command,再运行 cliany-site cases --case-id <id> --issue-template 生成带 Primary Runbook、Command SHA-256、Promotion Command Plan Summary、Promotion Command Plan command_sha256 子行、source / missing 子行、Doctor Preflight Evidence Fields 和 Doctor Preflight Evidence Template 的 issue body。随后先保留基础 cliany-site cases --case-id <id> --evidence-bundle --json 输出,再运行 cliany-site doctor --llm-live --require-capability generate_adapters --json > /tmp/cliany-doctor-preflight.json 和 cliany-site cases --case-id <id> --evidence-bundle --doctor-json /tmp/cliany-doctor-preflight.json --json,在 issue 摘要中引用 primary_next_task_runbook、llm_live_preflight_required、llm_live_preflight_command_sha256、promotion_command_plan[*].command_sha256、doctor_preflight_evidence_fields、doctor_preflight_evidence_values、doctor_preflight_evidence_ok、doctor_preflight_evidence_missing_count、doctor_preflight_state、doctor_preflight_state_fields、doctor_preflight_state_statuses 和 expected_adapter_package,确保贡献者先做 live LLM preflight、再执行当前 evidence task,并上传正确的 adapter release asset。doctor_preflight_state_fields 固定为 preflight_state.status、preflight_state.ready_for_adapter_package、preflight_state.primary_reason、preflight_state.reason_codes、preflight_state.next_action;doctor_preflight_state_statuses 只允许 ready、blocked、missing_fields。普通 cliany-site cases --status candidate 输出也会展示 preflight_required、preflight_blocker 和 runbook_first,方便非 JSON 交接。若 preflight 未通过,贴回 doctor JSON 中的 summary.llm_live_preflight 与 CDP blocker 字段作为证据;若 --doctor-json 已生成 evidence,则读取 doctor_preflight_state.status,只在 ready 且 preflight_state.ready_for_adapter_package=true 时继续 explore,blocked 或 missing_fields 时先贴证据。若使用 python scripts/plan_next_iteration.py --issues-dir /tmp/cliany-candidate-issues 生成 artifacts,先对比 candidate_promotions[*].issue_template_command、candidate_promotions[*].issue_template_json_command、issue-metadata.json、case_promotion_evidence_primary_llm_live_preflight_required、case_promotion_evidence_primary_llm_live_preflight_command_sha256、case_promotion_evidence_primary_llm_live_preflight_blocker_comment、case_promotion_evidence_primary_doctor_preflight_blocker_comment、case_promotion_evidence_primary_doctor_preflight_evidence_template_sha256、case_promotion_doctor_preflight_evidence_template_sha256、doctor_preflight_state_fields、doctor_preflight_state_statuses、required_labels、required_label_count、required_labels_sha256 与 case_promotion_evidence_primary_runbook_steps / hash 是否漂移,再创建 GitHub issue。
Doctor evidence 现在包含 summary.capabilities.generate_adapters.local_ready 和 summary.capabilities.generate_adapters.local_blockers,可在 live provider 被阻塞时单独说明本地前提是否健康;它们不能替代 candidate explore 所需的 summary.llm_live_preflight.ready=true。
普通 cliany-site cases --status candidate 会把未来的 adapter 命令标为“当前不可运行”;必须先完成包发布、安装并通过 verify --strict,它才会成为可执行命令,不能当作 active demo 快速命令。
如果已经保存 doctor JSON,可运行 python scripts/plan_next_iteration.py --doctor-json /tmp/cliany-doctor-preflight.json --issues-dir /tmp/cliany-candidate-issues。生成的 issue-metadata.json 和 candidate issue body 会直接带上当前 doctor_preflight_state、extracted values、source path,以及包含 --doctor-json 的 issue/evidence bundle commands,适合在 live LLM blocked 时生成 blocker-ready issue 草稿。
如果维护工具只读取 promotion queue,可直接比对 promotion_plan.primary_doctor_preflight_evidence_template_field_count、promotion_plan.primary_doctor_preflight_evidence_template_sha256、promotion_plan.primary_llm_live_preflight_command_sha256、candidate primary_doctor_preflight_evidence_template_sha256 和 task_queue[*].doctor_preflight_evidence_template_sha256 / task_queue[*].llm_live_preflight_command_sha256,无需展开完整 evidence bundle 也能发现 doctor 证据模板与 preflight 命令漂移。
如果维护工具只读取 case validation,可从 scripts/validate_cases.py --json 的 promotion_evidence_summary.primary_next_task.doctor_preflight_evidence_template_sha256、doctor_preflight_state_fields、doctor_preflight_state_statuses,scripts/validate_cases.py --report 的 primary_doctor_preflight_evidence_template_sha256,或纯文本 scripts/validate_cases.py --strict stdout 的 promotion_evidence_primary_doctor_preflight_evidence_template_sha256 / promotion_evidence_primary_llm_live_preflight_command_sha256 比对同一 doctor 模板、state contract 与 preflight 命令漂移。
公开 candidate issue 也应保持与当前 template 一致。先运行 python scripts/audit_candidate_issues.py --repo pearjelly/cliany.site --json 只读检查开放 case-proposal issue 的 title、body 与 SHA-256;不属于当前 manifest 的 title 会报告为 unexpected。不带 --json 的人工报告会直接显示 unexpected issue 的实际 title 和 URL,方便先定位 blocker。只有审阅 stale 并先解决 missing、duplicate、unexpected 后才运行 python scripts/audit_candidate_issues.py --repo pearjelly/cliany.site --apply --confirm-rewrite --json。工具不会创建、关闭 issue 或将 candidate 提前标记为 active。
如何在服务器/Docker 中使用?
选择一个浏览器管理路径;--headless 和 --cdp-url 都必须位于 explore 前,且远程 CDP 已存在时不需要 --headless。
# 让 cliany-site 启动无头 Chrome
cliany-site --headless explore "https://github.com" "搜索仓库" --json
# 连接已运行的远程 CDP 浏览器
cliany-site --cdp-url "ws://localhost:9222" explore "https://github.com" "搜索仓库" --json