澄清点 1 的落地:底座不内置 Agent(架构不变量 I-6)。一切"思考"经 Cognition Port 委托给可插拔的 Agent 驱动(Cursor / Claude / Codex / openclaw / 自研)。底座是"手脚 + 记忆 + 治理",Agent 是"脑",两者可独立进程/独立机器。
| 若把 Agent 焊进底座(旧设计) | 底座无 Agent + 可插拔(本设计) |
|---|---|
| 绑定某家模型/框架,升级即重构 | 任何 Agent 带自己的脑来用,模型自由演进 |
| 本 AI(Cursor)想用还得"套娃" | Cursor 直接经 MCP 驱动,零套娃 |
| 无 LLM 密钥时完全不可用 | 无驱动时仍可 0 Token 确定性回放/批量(I-6) |
| 自愈只能用内置模型 | 自愈可回给"正在用的那个 Agent" |
一句话:底座对 Agent 的态度和对浏览器传输一样——它是接口,不是具体实现。
flowchart LR
subgraph AGENT["外部 Agent 驱动(可插拔)"]
A["Cursor / Claude / Codex / openclaw / 自研"]
end
subgraph BASE["Agent-RPA 底座(无内置 Agent)"]
MCP["MCP Server (inbound)"]
PORT["Cognition Port (outbound)"]
CORE["Orchestrator / Recorder / Interpreter / Self-Heal"]
end
A -->|inbound:驱动底座做探索/回放/批量| MCP --> CORE
CORE -->|outbound:需要思考时回调 Agent| PORT -.-> A
- inbound(Agent → 底座):Agent 主动调用底座的 MCP/API 工具(
explore_task/run_skill/observe/act/…,见 06)。主路径。 - outbound(底座 → Agent):底座在需要认知时经 Cognition Port 回调 Agent。用于无人值守自愈、无人值守探索、结晶辅助。
这两个方向刻意对称:同一个 Agent 既能"驱动底座",也能"被底座回调"。Cursor 这种以 MCP 为中心的 Agent 天然走 inbound;批量/定时这种无人在场的场景走 outbound。
自愈与探索的"谁来思考"取决于当前有没有 Agent 在场:
stateDiagram-v2
[*] --> Attached: Run 由某 Agent 经 inbound 发起且会话未结束
[*] --> Detached: 批量/定时/Webhook 触发,无 Agent 在场
Attached --> AskCaller: 需要认知(L2/L3/探索决策)
AskCaller --> Attached: 同一 Agent 带上下文修复/决策
Detached --> AskDefault: 需要认知
AskDefault --> Detached: 调用配置的默认 healer/explorer Agent 驱动
AskDefault --> Escalate: 未配置任何驱动
Escalate --> [*]: 升级人工
| 模式 | 触发场景 | 认知来源 | 备注 |
|---|---|---|---|
| Attached 在场 | Cursor/Claude 交互式驱动、会话未关 | 回给发起的那个 Agent | 带其任务上下文,修复质量最好 |
| Detached 脱离 | 批量回放、cron、Webhook | 配置的默认 healer/explorer 驱动 | 模型可配;子 Agent 指定 Fable 5 |
| 无驱动 | 未配置任何 Agent | 仅 L1 可用;L2/L3 → 升级人工 | 保证底座可独立运行(I-6) |
底座把"需要思考的事"抽象成少量、稳定、与厂商无关的认知请求;适配器负责翻译成各家 Agent 的调用形态。
classDiagram
class CognitionPort {
<<接口>>
+Plan(goal, page_ctx, constraints) SubTasks
+DecideStep(subtask, multimodal_ctx, candidates) ActionDecision
+Relocate(step_intent, multimodal_ctx, failed_locators) LocatorBundle
+RepairSubflow(subflow, multimodal_ctx, error) ActionGraphPatch
+Validate(goal_or_step, multimodal_ctx) VerdictWithReason
+AssistCrystallize(raw_trace) NamingAndAssertions
+Capabilities() AgentCaps
}
class CursorMCPAdapter
class ClaudeAdapter
class CodexAdapter
class OpenClawAdapter
class GenericOpenAIAdapter
class HumanEscalationAdapter
CognitionPort <|.. CursorMCPAdapter
CognitionPort <|.. ClaudeAdapter
CognitionPort <|.. CodexAdapter
CognitionPort <|.. OpenClawAdapter
CognitionPort <|.. GenericOpenAIAdapter
CognitionPort <|.. HumanEscalationAdapter
认知请求的公共信封(envelope)——所有适配器输入统一:
设计要点:
- 厂商无关:请求只描述"要什么答案 + 多模态上下文 + 约束",不含任何厂商私有字段。
- 底座负责多模态打包:Agent 收到的是已采集好的截图/AX/DOM/OCR/候选(12),Agent 不必自己再去驱动浏览器抓取(除非它选择 inbound 亲自驱动)。
- 预算与写权限护栏:每次认知请求带
budget_tokens与allow_write_actions;高风险写动作默认禁止,需经审批点(05 NeedsHuman)。 - 结构化返回:Agent 必须按
return_schema返回(如LocatorBundle),底座据此确定性回写技能(07),避免自由文本歧义。
按接入形态分三类,覆盖题述的主流 Agent:
flowchart TB
subgraph MCPCLASS["A. MCP 类(互为 MCP client/server)"]
C1["Cursor:底座作为 MCP server 被 Cursor 调用(inbound);<br/>outbound 时底座作为 MCP client 回调 Cursor 暴露的工具"]
C2["Codex:codex mcp-server 暴露 codex/codex-reply 工具,<br/>底座作为 MCP client 用 threadId 维持会话"]
end
subgraph APICLASS["B. API 类(HTTP 调用)"]
C3["Claude:Messages API"]
C4["通用:OpenAI 兼容 Chat Completions(含本地模型)"]
end
subgraph CLICLASS["C. CLI/进程类"]
C5["Claude Code CLI / openclaw:<br/>本地进程/守护,经其 SDK 或 stdio 交互"]
end
| Agent | 接入类型 | 关键机制 | inbound | outbound | 许可/备注 |
|---|---|---|---|---|---|
| Cursor | MCP | 本环境即 Cursor:底座作 MCP server 被其驱动;回调可复用其 MCP 工具面 | ✅主 | ✅(会话在场) | 交互式首选 |
| Codex | MCP(stdio) | codex mcp-server 暴露 codex/codex-reply;底座作 MCP client,保存 threadId 维持上下文;approval-policy/sandbox 受控 |
✅ | ✅ | 适合脱离模式自愈 |
| Claude / Claude Code | API 或 CLI | Messages API;或 Claude Code CLI 本地驱动 | ✅ | ✅ | 通用性强 |
| openclaw | CLI/守护 | 本地优先守护进程,模型无关(可接本地 Ollama/vLLM);经其 SDK/gateway 交互 | ✅ | ✅ | MIT;安全:曾有 WebSocket 劫持/沙箱逃逸类 CVE,须在隔离/非特权环境运行并做审计 |
| 通用 OpenAI 兼容 | API | Chat Completions(含本地模型/自研) | ✅ | ✅ | 兜底适配器 |
| Human | 人工 | 无驱动或硬挑战时升级人工 | — | ✅ | 责任使用底线 |
能力协商(Capabilities()):适配器声明该 Agent 是否支持视觉/工具调用/长上下文/结构化输出等;底座据此裁剪认知请求(如无视觉能力则不发截图、改发 AX+OCR 文本)。
// praxis.config.jsonc —— Agent 驱动是配置项,不是代码依赖
{
"cognition": {
"attached_prefer_caller": true, // 在场时优先回给发起者
"default_healer": { // 脱离模式默认 healer
"adapter": "codex-mcp",
"model": "fable-5", // 子 Agent 指定 Fable 5
"budget_tokens_per_step": 4000
},
"default_explorer": { // 无人值守探索
"adapter": "claude-api",
"model": "fable-5",
"budget_tokens_per_run": 200000
},
"adapters": {
"cursor-mcp": { "type": "mcp-server-inbound" },
"codex-mcp": { "type": "mcp-client", "command": "codex", "args": ["mcp-server"] },
"claude-api": { "type": "openai-compatible", "base_url": "…", "api_key": "%vault:llm.claude%" },
"openclaw": { "type": "cli", "endpoint": "http://127.0.0.1:xxxx", "sandbox": "isolated" }
},
"fallback": "human" // 未配置/失败 → 升级人工
}
}- 密钥进 Vault:LLM/Agent 凭据也走
%vault:...%(I-5),不落配置明文。 - 模型可换:
model字段可配置;你要求的子 Agent 一律 Fable 5 作为默认。
sequenceDiagram
autonumber
participant INTP as 回放解释器
participant HEAL as Self-Heal Coordinator
participant PORT as Cognition Port
participant ADP as Agent 适配器(默认 healer)
participant AGENT as Agent(Fable 5)
INTP->>HEAL: step2 定位失败(L1 已尝试并失败)
HEAL->>PORT: relocate 请求(多模态上下文+失败定位器+预算)
PORT->>ADP: 按适配器翻译(如 codex-reply threadId)
ADP->>AGENT: 结构化提问
AGENT-->>ADP: LocatorBundle(结构化)
ADP-->>PORT: 归一化返回
PORT-->>HEAL: 新定位器
HEAL->>INTP: 用新定位器重试
INTP-->>HEAL: 成功
HEAL->>HEAL: 回写技能升版 + 记录 skill diff
- 最小权限:认知请求默认
allow_write_actions=false;下单/支付等写动作必须经审批点(05)。 - 上下文脱敏:发给 Agent 的多模态上下文默认脱敏(遮罩输入框中的凭据、隐藏
%vault%值)。 - 驱动沙箱:openclaw 等具系统级权限的 Agent 须在隔离/非特权环境运行(其历史 CVE 要求,见 §5)。
- 审计:每次 outbound 认知请求/返回都留痕(模型、token、耗时、变更),纳入 Run 观测(05)。
- 底座无内置 Agent;认知全部经 Cognition Port 委托(I-6)。
- inbound/outbound 双向对称;Attached/Detached 两种在场性明确。
- 覆盖 Cursor/Codex/Claude/openclaw + 通用 + Human 适配器,含能力协商。
- 认知请求厂商无关、多模态上下文由底座打包、结构化返回。
- 默认 healer/explorer 子 Agent 指定 Fable 5,模型可配置。
- 无任何驱动时底座仍能 0 Token 回放/批量,L2/L3 优雅升级人工。
- 密钥进 Vault、上下文脱敏、写动作受审批、驱动沙箱、全程审计。
{ "request_type": "relocate | decide_step | plan | repair_subflow | validate | assist_crystallize", "run_id": "run_...", "skill_ref": "search-and-compare@ecom-x@1.0.0", "step": { "idx": 2, "intent": "在搜索框输入关键词" }, "multimodal_ctx": { // 见 12:底座负责采集与打包 "screenshot": "artifact://run_.../step2.png", "ax_tree": "…精简可交互子树…", "dom_excerpt": "…目标容器 outerHTML 截断…", "ocr": [{ "text": "搜索", "bbox": [x,y,w,h] }], "candidates": [{ "ref": 17, "role": "combobox", "name": "搜索" }] }, "constraints": { "budget_tokens": 4000, "allow_write_actions": false }, "return_schema": "LocatorBundle | ActionDecision | ActionGraphPatch | Verdict" }