1. 背景与体系对比 (Background & Architectural Positioning)

在评估端侧/边缘自主智能体 (Edge & On-Device Autonomous Agent) 的运行时设计时,OpenMinis 与 InPage Agent 处于高度互补且面对相同核心痛点的生态位:

维度OpenMinis (Native App 端侧 Agent)InPage Agent (纯前端 In-Browser Agent)
宿主环境iOS (Swift / SwiftUI) + Android (Kotlin / Compose)Web 浏览器 (Vite + TypeScript + 原生 Web API)
沙箱模型iSH (ARM64 Linux 用户态模拟器) / PRoot Alpine Linux无重型沙箱;依托 Web Worker 隔离线程与页面主 Realm 执行原生 JS
存储后端宿主本地沙盒文件系统 + SQLite (GRDB)虚拟文件系统 (Virtual File System, VFS) 运行于 IndexedDB (idb)
网关与网络直连模型 Provider / 远端代理轻量 Go 转发网关 (gateway/) 负责藏 Key、限流与请求体裁剪
共有核心约束极端受限的运行资源、电池/内存红线、脆弱的长上下文与严格的容错需求

OpenMinis 经过多次生产迭代,在 src/ios/Agent 与 NativeOffloads 中沉淀了极为严密且兼顾工程可靠性的 Agent Runtime 机制。本文提炼其核心设计,并给出 InPage Agent 落地改造的具体建议。


2. 核心借鉴要点 (Key Architectural Patterns to Adopt)

2.1 截断写入保护 (Truncated Write Protection)

  • OpenMinis 实现:位于 AIChatViewModel+ConcurrentTools.swift:186-240。

    • 痛点:在流式生成(SSE)工具参数(JSON)过程中,一旦达到模型单次输出 Token 上限或网络突发中断,JSON 修复逻辑(如补齐 " 或 })能使 JSON 变为合法对象,但其实际参数(如 content)已被腰斩。若继续执行 file_write 或 file_edit,会将残缺的代码写入文件,造成静默破坏(Silent Corruption)。
    • 防御方案:OpenMinis 在参数修复层标记 truncationRepairTag。当针对写操作类工具 (file_write / file_edit) 检测到该标记时,直接拒绝落盘写入,并向模型反馈结构化拦截提示:

      "Error: This call was NOT executed. Its argument stream was truncated in transit... Nothing was written to disk — the target file is unchanged. Re-issue this write in smaller pieces."
  • InPage Agent 落地建议:

    • 在 app/src/agent/runtime.ts 的 runLoop 中,对 file_ops(write)、write_file、edit_file 加入流完整性校验。如果流解析在字符串未闭合前强制中断结束,严禁调用 VFS 写入,并回填截断警告。

2.2 工具死循环检测与断路器 (Tool Loop Detection & Circuit Breaker)

  • OpenMinis 实现:位于 ToolLoopDetector.swift。

    • 建立四层环形检测策略(Sliding Window History):

      1. unknown_tool_repeat:检测模型反复幻觉调用未声明的工具,达到阈值直接切断。
      2. global_circuit_breaker:连续产生无进展输出(No-progress outcomes)达到上限,全局熔断。
      3. known_poll_no_progress:针对轮询类工具设定双阈值(警告阈值与硬中断阈值)。
      4. generic_repeat:基于 (toolName, argsHash, resultHash) 的哈希比对,拦截完全重复的参数请求。
  • InPage Agent 落地建议:

    • InPage Agent 目前仅依靠 maxTurns = 8 硬上限兜底。当模型在 browser_use(如不断重复点击失效的选择器)或 file_ops(反复读取不存在的文件)中打转时,会迅速烧完所有步数。
    • 引入轻量级 ToolLoopDetector 类,记录最近 10 次调用的参数 SHA-256,出现连续 3 次相同调用与报错时,主动注入引导性拦截信息([LOOP BLOCKED]),迫使模型更换解决思路。

2.3 上下文分层策略与动态压缩 (Tiered Context Policy & Compaction)

  • OpenMinis 实现:位于 ContextPolicy.swift 与 AIChatViewModel+Compaction.swift。

    • 按模型的上下文窗口尺寸划分等级(<32K、32K-64K、64K-128K、≥128K)。
    • 发送前执行 checkContextBeforeSend:评估当前已消耗 Token,当逼近阈值时触发自动压缩。
    • 核心保序与锚点机制:压缩不会简单截断,而是调用小模型生成上下文摘要生成 CompactMarker,同时严格保留最近 N 轮用户对话(compactKeepRecentUserTurns = 3) 作为推理锚点(Verbatim Anchors),使模型仍可获取最近精准的代码片段与指令。
  • InPage Agent 落地建议:

    • InPage Agent 包含大体积的 DOM 骨干树提取(browser_use: get_backbone)与长代码读写,直接透传全量 messages 极易突破 Go 网关的 2MB 请求上限 (GATEWAY_MAX_BYTES) 或模型窗口。
    • 需引入上下文预算检测:超过阈值时,自动将前半段历史折叠为 <compact_summary>,仅保留系统提示词、工作区文件列表与最近 2-3 轮交互。

2.4 请求预算与超限转存机制 (Request Budget & Spillover Offloading)

  • OpenMinis 实现:位于 AIChatViewModel+RequestBudget.swift。

    • 规定单次请求的最大媒体/文本预算(如 25MB)。当图像或工具输出超限时,优先剔除较早的项,并将原始数据写入磁盘持久化路径(如 /attachments/spillover/<sha1>),在消息历史中替换为占位符:

      [image elided to fit request budget. Original at /var/minis/... — re-fetch with read_image if needed]
  • InPage Agent 落地建议:

    • 当 browser_use 抓取超大页面 DOM、或者用户在文件树中打开大文件时,无需将上万行文本直接存进对话上下文。
    • 将大文本存入 IndexedDB 临时缓存(/.cache/spillover/),上下文仅保留简要摘要与路径引用。

2.5 保序并发工具调度 (Order-Preserving Concurrent Tool Execution)

  • OpenMinis 实现:位于 AIChatViewModel+ConcurrentTools.swift。

    • 当模型在单轮回复中吐出多个 tool_use 时(例如并发读取 3 个文件),使用 TaskGroup 启动并发执行,最大并发度限制为 10。
    • 严格保序:收集结果后,按模型原始下发的工具调用索引重新排序装配,完全符合 OpenAI / Anthropic 规范对 tool_result 顺序与 tool_use 严格一致的强要求。
  • InPage Agent 落地建议:

    • 目前 InPage Agent 使用 for (const item of assistantMsg.toolDetails) 串行 await。
    • 对于只读工具(read_file, list_files, DOM 信息感知),可通过 Promise.all 并行加速,显著降低移动端首字等待时间。

2.6 多模型分组降级与容错重试 (Model Group Fallback & Auto-Retry)

  • OpenMinis 实现:位于 AIChatViewModel+Fallback.swift 与 ModelGroupRouter.swift。

    • streamWithAutoRetry:遇到网络抖动或 5xx 错误时,按照 [3, 5, 10, 15, 30] 秒退避重试,界面展示倒计时,允许用户手动跳过或中止。
    • streamWithGroupFallback:在遇到 429 速率限制、余额耗尽或不可恢复的鉴权错误时,自动平滑降级至同组备选模型(例如 DeepSeek 故障时自动转接到备用 Provider)。
  • InPage Agent 落地建议:

    • 目前 InPage Agent 一旦出错直接终止并呈现红字。增加轻量重试机制及 Provider 故障自动降级切换(如 Primary -> Backup),能极大提高可用性。

2.7 技能按需激活与元数据驻留 (On-Demand Skill Loading)

  • OpenMinis 实现:位于 SkillStore.swift。

    • 上下文中仅保留技能的元数据(名称、触发条件、摘要),当判定需要该技能时,再按需载入 SKILL.md 正文及绑定的脚本资源。
  • InPage Agent 落地建议:

    • 目前 InPage Agent 将所有启用的技能正文全量拼接到 developerPrompt 中,随着用户自定义技能增加,开销急剧上升。应改为只在 System Prompt 注入技能清单,模型通过调用内部动作或命中意图时才展开正文。

2.8 浏览器生命周期与运行防冻 (Host Lifecycle Awareness)

  • OpenMinis 实现:调用 iOS 系统后台任务接口 beginBackgroundTask,防止应用切到后台瞬间网络与进程被杀。
  • InPage Agent 落地建议:

    • 针对移动端 Web 浏览器,利用 Screen Wake Lock API (navigator.wakeLock.request('screen')) 在 Agent 执行任务流期间阻止手机休眠息屏。
    • 监听 document.addEventListener('visibilitychange'),在切回前台时校验 SSE 流连接状态并进行断点续接。

3. InPage Agent 改造实施路线图 (Implementation Roadmap)

  1. 第一优先级(防御性鲁棒性):

    • 移植 ToolLoopDetector:拦截重复工具调用与不存在路径死循环。
    • 增加截断写入拦截:防止流式异常造成 VFS 源码损坏。
  2. 第二优先级(性能与吞吐):

    • 并发工具调用(Promise.all 保序派发)。
    • 上下文滑动窗口与超限压缩(Token Budgeting & Compaction)。
  3. 第三优先级(多模型与移动端体验):

    • 网络错误指数退避重试(带倒计时 UI)。
    • Provider 故障降级链。
    • Screen Wake Lock 屏幕常亮保护。

本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/AI apps