# 基于外部站点适配器来源的引入方案 > 目标:在不引入后台浏览器自动化副作用的前提下,利用外部站点适配器来源扩充 Lime 的站点覆盖面,同时坚持 Lime 自己的标准。 ## 一、结论 外部站点适配器来源可以接,但只能作为来源层,不能成为 Lime 的第二套产品标准。 必须同时满足三条边界: - 只引入站点适配器定义,不引入浏览器运行时 - 只引入可编译的安全子集,不引入完整来源语义 - Lime 继续以 `managed_cdp / existing_session` 作为唯一浏览器执行事实源 如果目标是“更多站点适配器”,这是合理方向。 如果目标变成“更多浏览器自动化模式”或“多套浏览器控制系统”,这条路不适合 Lime。 ## 二、为什么不能原样接入 ### 2.1 外部来源的价值在站点覆盖,而不在浏览器控制 外部来源真正有价值的是: - 已沉淀的大量站点定义 - 声明式 YAML adapter 结构 - 可复用的 pipeline 表达方式 - 对站点字段抽取的经验 它解决的是“站点覆盖面”问题,不是 Lime 缺少的“浏览器内核抽象”问题。 ### 2.2 原生浏览器链路与 Lime 产品边界冲突 很多外部来源自带这些行为: - 后台拉起守护进程 - 自动连接浏览器扩展 - 连接失败时尝试唤醒 Chrome - 把 Chrome/Chromium 会话当成默认主链 这和 Lime 当前已经明确收紧的产品边界直接冲突: - 禁止无任务时后台自运行 - 禁止用户无感知地拉起浏览器 - 禁止常驻式浏览器自动化观感 - 禁止像“后门”一样持续消耗 CPU / 内存 因此,外部来源不能以“浏览器运行时方案”的身份进入 Lime。 ### 2.3 原样并入会把 Lime 做成两套系统 Lime 当前已经有自己的主链: - 浏览器来源:`system | playwright` - 上下文接入:`managed_cdp | existing_session` - 站点适配器注册表 - 站点适配器执行分发链 如果再把外部来源的 `daemon + extension + protocol + page bridge` 整套搬进来,结果就是: 1. Lime 自己的浏览器控制链 2. 外部来源自己的浏览器控制链 这会直接导致: - 事实源分裂 - 排障复杂度翻倍 - 用户心智混乱 - Windows / macOS 资源问题更难治理 这不符合 Lime 的产品判断,也不符合仓库治理原则。 ## 三、应该引入什么,不应该引入什么 ### 3.1 应该引入 建议只引入这些“来源材料”: - 外部来源中的 adapter 定义文件 - adapter 元数据结构 - `site` - `name` - `description` - `domain` - `args` - `columns` - `pipeline` - 表达式与步骤设计思路 - 已验证过的字段映射经验 ### 3.2 不应该引入 明确不引入这些运行时能力: - 浏览器桥接实现 - 守护进程生命周期 - 浏览器扩展连接模型 - 后台自动拉起浏览器 - 自动唤醒 Chrome - 常驻后台的浏览器控制进程 - 任何绕过 Lime 当前 browser runtime 的执行主链 ### 3.3 核心边界 一句话定义边界: > 外部来源是 Lime 的站点适配器来源,不是 Lime 的浏览器执行内核。 ## 四、Lime 当前切入点 Lime 现有站点适配器主链已经存在,关键边界如下: - 站点适配器注册:`src-tauri/src/services/site_adapter_registry.rs` - 站点适配器执行:`src-tauri/src/services/site_capability_service.rs` - 前端命令网关:`src/lib/webview-api.ts` - 浏览器执行路线: - `existing_session` - `managed_cdp` Lime 当前主格式本质上是: - manifest 元数据 - entry URL 规则 - script 脚本执行 - 通过 Lime 现有 runtime 执行 script 而外部来源通常是: - YAML 元数据 - pipeline 步骤 - 来源自己的运行时抽象 - 可选浏览器桥接 这两者不是直接兼容关系,因此正确切入点不是“并列保留两套格式”,而是增加一层导入编译边界。 ## 五、推荐落地方案 ### 5.1 三层结构 建议固定为三层: 1. 来源层 - 外部 adapter 定义文件 2. Lime 编译层 - 把来源 YAML 编译成 Lime 标准 3. Lime 执行层 - 继续使用 Lime 现有 `managed_cdp / existing_session` 这样可以同时保证: - 站点覆盖面扩展 - 浏览器执行事实源不分裂 - 不引入后台自动化副作用 - Lime 标准仍然是唯一事实源 ### 5.2 第一阶段只支持安全子集 第一阶段不要追求完整兼容来源 pipeline。 建议只支持以下安全子集: - `navigate` - `evaluate` - `map` - `filter` - `limit` - `sort` 第一阶段明确不支持: - `tap` - `intercept` - `Desktop` 模式 - 依赖扩展上下文的动作 - 依赖守护进程协议的动作 - 自动关闭、拉起、唤醒浏览器的动作 这能把复杂度和产品风险都压在可控范围内。 ### 5.3 编译层职责 建议通过独立导入服务承接,例如: - `src-tauri/src/services/site_adapter_import_service.rs` 职责只保留三件事: 1. 读取来源 YAML 2. 按 Lime 白名单规则校验 3. 编译为 Lime `SiteAdapterSpec` 所需结构 原则是: - 不污染现有站点执行链 - 不把来源原始模型散落到整个仓库 - 不让来源格式越过编译边界直达运行时 ## 六、接入路线对比 ### 方案 A:直接调用外部 CLI 实现方式: - Lime 在用户触发时调用外部命令 - 读取输出结果 - 回填到 Lime 的结果链路 优点: - 接入快 - 便于短期验证少量站点价值 缺点: - 仍可能间接触发来源自己的浏览器自动化模型 - 输出结构和错误语义受外部 CLI 限制 - 难以对齐 Lime 当前 `managed_cdp / existing_session` - 长期治理成本高 判断: - 只适合作为一次性实验 - 不适合作为 Lime 主方案 ### 方案 B:只导入来源定义,由 Lime 执行 实现方式: - Lime 只消费来源 adapter 定义 - 编译后交给 Lime 现有 runtime 执行 优点: - 浏览器控制事实源统一 - 产品边界一致 - 用户体验一致 - 可复用 Lime 当前审计、状态、结果链路 缺点: - 首轮需要实现编译层 - 需要维护 pipeline 子集映射规则 判断: - 这是 Lime 应采用的长期主方案 --- ## 七、推荐实施阶段 ### 阶段 0:只做静态评估 目标: - 建立 YAML 来源 adapter 能力盘点 - 标注哪些站点适合迁入 - 标注哪些步骤当前不支持 输出: - 站点白名单 - 不支持步骤清单 - 优先迁移顺序 建议优先挑选的站点特征: - 只依赖 `navigate + evaluate + map + limit` - 不依赖 Chrome extension - 不依赖桌面应用上下文 - 只读采集,不带写操作 ### 阶段 1:做 adapter importer PoC 目标: - 支持读取 YAML 来源 YAML - 转换为 Lime 内部适配器结构 - 跑通 3 到 5 个代表性站点 建议首批站点: - Reddit - Zhihu - Yahoo Finance - Hacker News - Xueqiu 中不依赖拦截链的只读项 阶段完成标准: - 站点可被 Lime 列出 - 可被搜索和推荐 - 可通过现有站点执行链跑出稳定结果 - 不引入任何后台自动拉起浏览器行为 ### 阶段 2:扩展步骤子集 目标: - 在验证稳定后,再考虑增加更多 pipeline 步骤 建议顺序: 1. `filter` 2. `sort` 3. 更复杂的 `map` 表达式 4. 更完整的参数类型支持 仍然不建议过早支持: - `intercept` - `tap` - 浏览器扩展相关上下文 ### 阶段 3:建立上游同步机制 目标: - 让 Lime 能稳定跟随 YAML 来源 adapter 增长 建议做法: - 明确一份允许导入的 adapter 白名单 - 通过脚本做同步与编译 - 同步时生成变更报告 不要做成: - 自动无审核拉取上游全部 adapter - 每次构建时动态扫描外部仓库 同步必须可审计、可回滚、可控。 --- ## 八、适配器编译规则建议 ### 8.1 名称映射 建议内部统一命名: - `site/name` 形式作为 adapter 唯一标识 - 例如: - `reddit/hot` - `zhihu/hot` - `xiaohongshu/feed` ### 8.2 参数映射 YAML 来源 常见参数类型先收敛到 Lime 已支持的简单类型: - `str` -> `string` - `int` -> `integer` 首轮不要扩展复杂参数系统。 ### 8.3 pipeline 到 script 的映射 推荐生成单一脚本执行体,而不是在 Lime 再实现一整套 YAML 来源 pipeline engine。 理由: - 当前 Lime 站点执行模型本来就是 script 型 - 可复用现有运行时 - 更容易与 `existing_session / managed_cdp` 对齐 建议做法: - `navigate` 映射为脚本前置导航意图 - `evaluate` 直接转为脚本主体 - `map/filter/limit/sort` 优先编译到脚本尾部的数据整形 也就是说: > 不把 YAML 来源 pipeline 原样搬进 Lime,而是把它编译成 Lime 现有 script 执行模型。 ### 8.4 不支持步骤的处理 对于当前不支持的步骤,必须在导入阶段就失败,并给出清晰原因。 例如: - `adapter uses intercept step` - `adapter requires extension runtime` - `adapter requires desktop mode` 不要进入运行时才失败。 --- ## 九、用户体验与产品边界 这是本方案最重要的非功能约束。 ### 9.1 明确禁止 - 无任务时后台自动运行站点适配器 - 自动启动 Chrome - 自动唤醒 Chrome - 自动挂接扩展 - 常驻 daemon - 用户未点击执行时预热站点运行时 ### 9.2 只允许的执行方式 只允许: - 用户显式点击运行某个适配器 - 或者用户明确发起某次站点采集任务 并且执行过程必须满足: - 可见 - 可中断 - 有状态反馈 - 有完成结果 - 结束即收口 ### 9.3 UX 文案要求 任何未来如果接入 YAML 来源 来源的适配器,都不应对用户暴露“YAML 来源 daemon”“extension reconnect”这类技术词。 用户只需要知道: - 这是一个站点适配器 - 需要哪个浏览器上下文 - 是否需要登录态 - 执行后会得到什么结果 --- ## 十、风险清单 ### 10.1 表达式兼容风险 YAML 来源 的表达式和 Lime 当前脚本模板体系不完全相同。 需要一个明确的受支持表达式子集。 ### 10.2 站点易碎性风险 很多站点适配器本质上依赖页面结构、接口字段、前端状态树。 即使成功导入,也需要接受它们会失效。 ### 10.3 维护成本风险 如果一次性导入过多站点,后续维护成本会很高。 必须建立白名单,不要全量照搬 55 个站点。 ### 10.4 写操作风险 带有发送、发布、点赞、交互类动作的适配器,不应在第一阶段导入。 首轮只应覆盖只读采集类适配器。 ### 10.5 协议漂移风险 如果 Lime 自己新做一套 pipeline,又试图兼容 YAML 来源 全量语义,最后会长成第三套事实源。 必须坚持“导入后编译到 Lime 当前 script 执行模型”。 --- ## 十一、推荐的首轮范围 首轮建议只做以下范围: - 只读适配器 - 无扩展依赖 - 无 daemon 依赖 - 无桌面应用依赖 - 无写操作 - 无登录强依赖,或登录态可复用现有 `existing_session` 不建议首轮纳入: - 小红书 `intercept / tap` 型复杂适配器 - ChatGPT / Chatwise / Discord-App 这类 Desktop 模式适配器 - 依赖扩展上下文或浏览器网络拦截的适配器 --- ## 十二、建议的下一步落地顺序 1. 建立 YAML 来源 adapter 能力审计脚本 2. 产出支持步骤白名单 3. 新增 `site_adapter_import_service` 4. 先导入 3 到 5 个只读 adapter 5. 接入现有 `site_list_adapters / site_search_adapters / site_run_adapter` 6. 补 smoke,证明不会触发后台自动化副作用 7. 再决定是否扩展更多步骤 --- ## 十三、最终决策 最终建议如下: - **决策一**:采纳 `外部适配器来源`,但仅作为站点适配器来源 - **决策二**:不采纳 `外部适配器来源` 的浏览器 runtime - **决策三**:Lime 继续保持浏览器 runtime 单一事实源 - **决策四**:先做 importer + 编译层,不做 runtime 并入 - **决策五**:首轮仅支持只读、安全、无后台副作用的 adapter 子集 这条路径同时满足: - 更多站点适配器 - 不引入第二套浏览器内核 - 不破坏当前产品边界 - 便于渐进式扩展 --- ## 附:一句话版本 > 要引的是 YAML 来源 的“站点适配器库”,不是它的“后台浏览器自动化模式”。