UFO³ 设备代理(Device Agent)开发完全指南:从三层架构到创建第一个设备代理
本指南系统讲解如何在 UFO³ 多设备编排体系中创建全新的设备代理(Device Agent),以仓库中的 LinuxAgent 为参考实现,覆盖设备代理与第三方代理的区别、统一三层架构、服务端-客户端分离模型、六大核心组件(Agent Class / Processor / State / Strategy / Prompter / MCP Server)以及从 third_party.yaml 配置到 devices.yaml 设备注册的完整落地流程。读完本文,你将掌握设备代理的架构原理、源码级调用链路,并能够照抄快速上手清单实现自己的 MobileAgent 或任意新平台代理。
1. 什么是设备代理(Device Agent)
Device Agent 是一类专门控制并自动化特定类型设备或平台的 AI 代理。与"扩展某项具体功能的第三方代理"不同,设备代理代表的是一整个计算平台,它拥有自己的:
- 执行环境(Execution Environment):设备专属的操作系统、运行时与 API;
- 控制机制(Control Mechanism):UI 自动化、CLI 命令或平台 API;
- 通信协议(Communication Protocol):基于 WebSocket 的客户端-服务端架构;
- MCP 集成(MCP Integration):用于命令执行的设备专属 MCP 服务器。
1.1 设备代理 vs 第三方代理
| 维度 | 设备代理(Device Agent) | 第三方代理(Third-Party Agent) |
|---|---|---|
| 作用范围 | 完整平台控制(Windows、Linux、移动端) | 特定功能扩展(硬件、Web) |
| 架构形态 | 客户端-服务端分离 | 运行在编排服务器(orchestrator)上 |
| 通信方式 | WebSocket + AIP 协议 | 直接方法调用 |
| MCP 服务器 | 平台专属 MCP 服务器 | 共享 MCP 服务器 |
| 典型例子 | WindowsAgent、LinuxAgent、MobileAgent | HardwareAgent、WebAgent |
| 部署方式 | 设备上的独立客户端进程 | 编排器的一部分 |
在仓库源码中,这一区分体现得非常直接:设备代理统一继承自 CustomizedAgent(ufo/agents/agent/customized_agent.py),通过 @AgentRegistry.register 装饰器注册,并显式声明 third_party=True 与对应的 processor_cls:
@AgentRegistry.register(
agent_name="LinuxAgent", third_party=True, processor_cls=LinuxAgentProcessor
)
class LinuxAgent(CustomizedAgent):
...
@AgentRegistry.register(
agent_name="MobileAgent", third_party=True, processor_cls=MobileAgentProcessor
)
class MobileAgent(CustomizedAgent):
...
同一文件中也保留了最基础的 CustomizedAgent 与 HardwareAgent 注册示例,可作为新代理的注册模板。
1.2 何时需要创建设备代理
当出现以下需求时,应创建设备代理:
- 控制一个全新的平台(移动端、IoT、嵌入式);
- 在远程或分布式设备上执行任务;
- 接入 Galaxy 多设备编排体系;
- 出于安全或可扩展性考虑需要隔离执行环境。
而如果只是为已有平台扩展能力、添加专用工具或 API,则应选择创建第三方代理(参考 创建第三方代理教程)。
2. 前置条件
2.1 知识要求
- ✅ Python 3.10+:具备中级 Python 编程能力;
- ✅ 异步编程:理解
async/await模式; - ✅ UFO³ 基础:熟悉 Agent 架构;
- ✅ MCP 协议:理解 Model Context Protocol;
- ✅ WebSocket:了解 WebSocket 通信基本原理。
2.2 推荐阅读
| 优先级 | 主题 | 链接 | 预计耗时 |
|---|---|---|---|
| 🥇 | Agent 架构概览 | Infrastructure/Agents | 20 min |
| 🥇 | LinuxAgent 快速上手 | Quick Start: Linux | 15 min |
| 🥈 | 服务端-客户端架构 | Server Overview、Client Overview | 30 min |
| 🥈 | MCP 集成 | MCP Overview | 20 min |
| 🥉 | AIP 协议 | AIP Protocol | 15 min |
2.3 开发环境
# 克隆 UFO³ 仓库
git clone https://gitcode.com/GitHub_Trending/uf/UFO.git
cd UFO
# 安装依赖
pip install -r requirements.txt
# 验证安装
python -c "import ufo; print('UFO³ installed successfully')"
3. 统一三层架构:State / Strategy / Command
UFO³ 中所有设备代理都遵循统一的三层架构,这是理解设备代理源码组织方式的钥匙:
graph TB
subgraph "Device Agent Architecture"
subgraph "Level-1: State Layer (FSM)"
S1[AgentState]
S2[State Machine]
S3[State Transitions]
S1 --> S2 --> S3
end
subgraph "Level-2: Strategy Layer (Execution Logic)"
P1[ProcessorTemplate]
P2[DATA_COLLECTION]
P3[LLM_INTERACTION]
P4[ACTION_EXECUTION]
P5[MEMORY_UPDATE]
P1 --> P2 --> P3 --> P4 --> P5
end
subgraph "Level-3: Command Layer (System Interface)"
C1[CommandDispatcher]
C2[MCP Tools]
C3[Device Commands]
C1 --> C2 --> C3
end
S3 -->|delegates to| P1
P5 -->|executes via| C1
end
- Level-1 状态层(State Layer):用有限状态机(FSM)控制代理生命周期;
- Level-2 策略层(Strategy Layer):以模块化策略构成的处理流水线;
- Level-3 命令层(Command Layer):通过 MCP 执行的原子系统操作。
详细架构说明见 Agent 架构文档。
3.1 状态层的源码印证
以 LinuxAgent 为例,状态机定义在 ufo/agents/states/linux_agent_state.py:
LinuxAgentStatus枚举定义四种状态:FINISH、CONTINUE、FAIL以及空状态None;LinuxAgentStateManager维护_state_mapping状态注册表;ContinueLinuxAgentState.handle()调用await agent.process(context)驱动处理流水线,并在is_round_end()返回False时持续执行;FinishLinuxAgentState的is_subtask_end()与is_round_end()均返回True,标志任务结束;FailLinuxAgentState.next_state()会把代理转移到FinishLinuxAgentState(),实现失败后的收尾。
状态通过 next_state(agent) 依据 agent.status 动态切换,这是整个 FSM 生命周期控制的机制核心。
4. 服务端-客户端分离架构
设备代理采用服务端-客户端分离架构,以换取安全性与可扩展性:
graph LR
subgraph "Server Side (Orchestrator)"
Server[Device Agent Server]
State[State Machine]
Processor[Strategy Processor]
LLM[LLM Service]
Server --> State
Server --> Processor
Processor -.-> LLM
end
subgraph "Communication"
AIP[AIP Protocol<br/>WebSocket]
end
subgraph "Client Side (Device)"
Client[Device Client]
MCP[MCP Server Manager]
Tools[Platform Tools]
OS[Device OS]
Client --> MCP
MCP --> Tools
Tools --> OS
end
Server <-->|Commands/Results| AIP
AIP <-->|Commands/Results| Client
| 组件 | 位置 | 职责 | 安全性 |
|---|---|---|---|
| Agent Server | 编排器 | 推理、规划、状态管理 | 不可信(LLM 驱动) |
| Device Client | 目标设备 | 命令执行、资源访问 | 可信(经过校验的操作) |
| AIP Protocol | 网络 | 消息传输、序列化 | 加密通道 |
分离带来的收益:
- 安全:将 LLM 推理与系统级执行隔离;
- 可扩展:单个编排器管理多台设备;
- 灵活:客户端可运行在资源受限设备(移动端、IoT)上;
- 安全兜底:客户端在执行前校验所有命令。
这一设计在 Linux MCP 服务器中体现得尤为明显(见第 6.3 节):LLM 只负责产出结构化命令意图,真正的系统操作由受信任、受校验的 MCP 工具完成。
5. LinuxAgent:参考实现
LinuxAgent 是创建新设备代理的理想参考,因为它具备:
- ✅ 架构简单:单层代理(无 HostAgent 委托);
- ✅ 边界清晰:服务端-客户端职责干净分离;
- ✅ 文档完备:代码与文档配套齐全;
- ✅ 生产可用:经过真实部署验证;
- ✅ 复杂度最小:聚焦设备代理的核心模式。
5.1 LinuxAgent 组件与文件定位
graph TB
subgraph "Server Side (ufo/agents/)"
LA[LinuxAgent Class<br/>customized_agent.py]
LAP[LinuxAgentProcessor<br/>customized_agent_processor.py]
LAS[LinuxAgent Strategies<br/>linux_agent_strategy.py]
LAST[LinuxAgent States<br/>linux_agent_state.py]
LA --> LAP
LAP --> LAS
LA --> LAST
end
subgraph "Client Side (ufo/client/)"
Client[UFO Client<br/>client.py]
MCP[MCP Server Manager<br/>mcp_server_manager.py]
LinuxMCP[Linux MCP Server<br/>linux_mcp_server.py]
Client --> MCP
MCP --> LinuxMCP
end
subgraph "Configuration"
Config[third_party.yaml]
Devices[devices.yaml]
Prompts[Prompt Templates]
end
LA -.reads.-> Config
Client -.reads.-> Devices
LA -.uses.-> Prompts
| 组件 | 文件路径 | 用途 |
|---|---|---|
| Agent 类 | ufo/agents/agent/customized_agent.py | LinuxAgent 定义 |
| Processor | ufo/agents/processors/customized/customized_agent_processor.py | LinuxAgentProcessor |
| 策略 | ufo/agents/processors/strategies/linux_agent_strategy.py | LLM 与动作策略 |
| 状态 | ufo/agents/states/linux_agent_state.py | 状态机状态 |
| Prompter | ufo/prompter/customized/linux_agent_prompter.py | Prompt 构造 |
| 客户端 | ufo/client/client.py | 设备客户端入口 |
| MCP 服务器 | ufo/client/mcp/http_servers/linux_mcp_server.py | 命令执行 |
5.2 处理器与策略的源码级剖析
LinuxAgentProcessor 继承自 CustomizedProcessor(其基类为 AppAgentProcessor),在 _setup_strategies() 中按 ProcessingPhase 装配策略,并对 fail_fast 语义做了明确取舍(ufo/agents/processors/customized/customized_agent_processor.py):
class LinuxAgentProcessor(CustomizedProcessor):
def _setup_strategies(self) -> None:
# LLM 交互失败应触发恢复,因此 fail_fast=True
self.strategies[ProcessingPhase.LLM_INTERACTION] = LinuxLLMInteractionStrategy(
fail_fast=True
)
# 动作执行失败可优雅处理,因此 fail_fast=False
self.strategies[ProcessingPhase.ACTION_EXECUTION] = (
LinuxActionExecutionStrategy(fail_fast=False)
)
self.strategies[ProcessingPhase.MEMORY_UPDATE] = AppMemoryUpdateStrategy(
fail_fast=False
)
def _setup_middleware(self) -> None:
# 中间件顺序敏感:日志中间件用于请求展示
self.middleware_chain = [LinuxLoggingMiddleware()]
def _finalize_processing_context(self, processing_context: ProcessingContext) -> None:
super()._finalize_processing_context(processing_context)
try:
result = processing_context.get_local("result")
if result:
self.global_context.set(ContextNames.ROUND_RESULT, result)
except Exception as e:
self.logger.warning(f"Failed to update ContextNames from results: {e}")
对比同文件中的 MobileAgentProcessor(同文件 #L142-L195),可以看到移动端在 DATA_COLLECTION 阶段使用 ComposedStrategy 组合三个子策略(截图、应用列表、控件列表),并挂载 MobileLoggingMiddleware——这正是"平台差异化策略"的典型写法,新建代理时可直接仿照。
策略类则定义在 ufo/agents/processors/strategies/linux_agent_strategy.py:
LinuxLLMInteractionStrategy用@depends_on("request")与@provides("parsed_response", "response_text", "llm_cost", "prompt_message", "action", "thought", "comment")声明依赖与产出,构造 Prompt 时合并 blackboard 上下文、上轮成功动作(last_success_actions)与计划(plan);LinuxActionExecutionStrategy从context.get_local("parsed_response")取出 LLM 解析结果,通过context.global_context.command_dispatcher执行动作,并用_create_action_info将执行结果回填到动作信息中供记忆使用;LinuxLoggingMiddleware定制起始日志:"Completing the user request: [request] on Linux."。
@depends_on / @provides 声明式依赖来自 ufo/agents/processors/core/strategy_dependency.py,新策略务必遵循这一数据流约定。
5.3 一次完整执行时序
以"列出 /tmp 下的文件"为例,整个调用链如下:
sequenceDiagram
participant User
participant Server as LinuxAgent Server
participant AIP as AIP Protocol
participant Client as Linux Client
participant MCP as Linux MCP Server
participant Shell as Bash Shell
User->>Server: User Request: "List files in /tmp"
Server->>Server: State: ContinueLinuxAgentState
Server->>Server: Processor: LinuxAgentProcessor
Server->>Server: Strategy: LLM_INTERACTION
Note over Server: Construct prompt, call LLM
Server->>Server: LLM Response: execute_command("ls -la /tmp")
Server->>Server: Strategy: ACTION_EXECUTION
Server->>AIP: COMMAND: execute_command
AIP->>Client: WebSocket: COMMAND
Client->>MCP: Call MCP Tool: execute_command
MCP->>Shell: Execute: ls -la /tmp
Shell-->>MCP: stdout, stderr, exit_code
MCP-->>Client: Result
Client->>AIP: WebSocket: RESULT
AIP->>Server: RESULT
Server->>Server: Strategy: MEMORY_UPDATE
Server->>Server: Update memory & blackboard
Server->>Server: State Transition: FINISH
Server->>User: Task Complete
关键执行步骤:
- 用户请求 → LinuxAgent Server 接收请求;
- 状态机 → 激活
ContinueLinuxAgentState(其handle()调用agent.process(context)); - 处理器 → 执行
LinuxAgentProcessor的策略流水线; - LLM 交互 → 生成 shell 命令(经
LinuxLLMInteractionStrategy构造 Prompt 并解析AppAgentResponse); - 动作执行 → 通过 AIP 协议将命令下发到客户端;
- MCP 执行 → 客户端经 Linux MCP Server 执行命令;
- 结果处理 → 服务端接收结果并更新记忆与 blackboard;
- 状态迁移 → 依据
agent.status迁移至FINISH状态。
6. 新设备代理(如 MobileAgent)的完整架构
创建一个新设备代理(例如 MobileAgent)时,需要实现以下组件:
graph TB
subgraph "1. Agent Definition"
A1[Agent Class<br/>MobileAgent]
A2[Processor<br/>MobileAgentProcessor]
A3[State Manager<br/>MobileAgentStateManager]
end
subgraph "2. Processing Strategies"
S1[DATA_COLLECTION<br/>Screenshot, UI Tree]
S2[LLM_INTERACTION<br/>Prompt Construction]
S3[ACTION_EXECUTION<br/>Command Dispatch]
S4[MEMORY_UPDATE<br/>Context Update]
end
subgraph "3. MCP Server"
M1[MCP Server<br/>mobile_mcp_server.py]
M2[MCP Tools<br/>tap, swipe, type, etc.]
end
subgraph "4. Configuration"
C1[third_party.yaml<br/>Agent Config]
C2[devices.yaml<br/>Device Registry]
C3[Prompt Templates<br/>LLM Prompts]
end
subgraph "5. Client"
CL1[Device Client<br/>client.py]
CL2[MCP Manager<br/>mcp_server_manager.py]
end
A1 --> A2
A2 --> S1 & S2 & S3 & S4
S3 --> M1
M1 --> M2
A1 -.reads.-> C1
CL1 --> CL2
CL2 --> M1
CL1 -.reads.-> C2
A2 -.uses.-> C3
6.1 实现清单
- [ ] Agent 类:定义继承自
CustomizedAgent的MobileAgent; - [ ] 处理器:创建带自定义策略的
MobileAgentProcessor; - [ ] 状态管理:实现
MobileAgentStateManager及各状态类; - [ ] 策略:构建平台专属的 LLM 与动作策略;
- [ ] MCP 服务器:开发带平台工具的 MCP 服务器;
- [ ] Prompter:为移动端上下文创建自定义 prompter;
- [ ] 客户端配置:配置运行在移动设备上的客户端;
- [ ] 代理配置:在
third_party.yaml添加代理配置; - [ ] 设备注册:在
devices.yaml注册设备; - [ ] Prompt 模板:编写 LLM Prompt 模板。
6.2 平台 MCP 服务器的参考实现
移动端 MCP 服务器(ufo/client/mcp/http_servers/mobile_mcp_server.py)拆分为两个服务器:
- 数据采集服务器(默认端口
8020):提供capture_screenshot、get_ui_tree、get_device_info、get_mobile_app_target_info、get_app_window_controls_target_info等只读工具; - 动作服务器(默认端口
8021):提供tap、swipe、type_text、launch_app、press_key、click_control等控制工具。
两者通过单例 MobileServerState 共享缓存(应用列表缓存 5 分钟、屏幕控件缓存 5 秒、UI 树缓存 5 秒、设备信息缓存 1 分钟),避免高频 ADB 查询。动作执行成功后会自动调用 invalidate_controls() 使控件缓存失效,保证下一次数据采集反映最新屏幕状态——这是移动端自动化非常关键的一致性设计。
6.3 安全基线:Linux MCP 服务器的纵深防御
新设备代理的 MCP 服务器可参考 Linux MCP 服务器(ufo/client/mcp/http_servers/linux_mcp_server.py)的四层安全模型:
- 命令白名单(Allowlist):
ALLOWED_SHELL_COMMANDS仅放行只读命令(ls、cat、grep、find、df、ps等约 40 个); - 危险模式扫描(Dangerous-pattern scan):拦截 shell 元字符(
;|&`` )、命令替换({)、find -exec、反向 shell 指示符(/dev/tcp/`)、I/O 重定向与换行/NULL 注入; - shell=False 执行:使用
asyncio.create_subprocess_exec直接执行 token 列表,shell 元字符永远不会被解释; - API Key 认证:每个工具调用都必须携带与
UFO_MCP_API_KEY环境变量匹配的密钥,采用hmac.compare_digest常量时间比较,未配置密钥时默认拒绝(fail-closed)。
此外还内置了 LocalhostGuardMiddleware,从传输层校验 Host/Origin/Sec-Fetch-Site 头,抵御 DNS-rebinding(CWE-346)攻击;_check_python_args 与 _check_find_args 则针对解释器与 find 做了参数级策略,防止"只读入口"被利用为任意代码执行。
启动 Linux MCP 服务器前必须设置环境变量:
export UFO_MCP_API_KEY='<your-secret-key>'
python -m ufo.client.mcp.http_servers.linux_mcp_server --port 8010
7. 六部分教程路线图
本教程拆分为 6 篇详细指南:
📘 第 1 部分:核心组件
实现服务端组件:Agent 类定义、Processor 与策略、State Manager 与状态、面向 LLM 交互的 Prompter。 预计耗时:45 分钟 难度:⭐⭐⭐
📘 第 2 部分:MCP 服务器开发
创建平台专属 MCP 服务器:MCP 服务器架构、MCP 工具定义、命令执行逻辑、错误处理与校验。 预计耗时:30 分钟 难度:⭐⭐
📘 第 3 部分:客户端配置
配置设备客户端:客户端初始化、MCP Server Manager 集成、WebSocket 连接搭建、平台检测。 预计耗时:20 分钟 难度:⭐⭐
📘 第 4 部分:配置与部署
配置并部署代理:third_party.yaml 配置、devices.yaml 设备注册、Prompt 模板创建、Galaxy 集成。
预计耗时:25 分钟 难度:⭐⭐
📘 第 5 部分:测试与调试
测试并调试实现:单元测试策略、集成测试、调试技巧、常见问题与解决方案。 预计耗时:30 分钟 难度:⭐⭐⭐
📘 第 6 部分:完整示例:MobileAgent
动手实操创建 MobileAgent:逐步实现、Android/iOS 平台特性、UI Automator 集成、完整可运行示例。
预计耗时:60 分钟 难度:⭐⭐⭐⭐
8. 快速上手:最小实现清单
以下是给有经验开发者的六步最小实现清单,代码均与仓库真实结构对齐。
第 1 步:创建 Agent 类
# ufo/agents/agent/customized_agent.py
@AgentRegistry.register(
agent_name="MobileAgent",
third_party=True,
processor_cls=MobileAgentProcessor
)
class MobileAgent(CustomizedAgent):
def __init__(self, name, main_prompt, example_prompt):
super().__init__(name, main_prompt, example_prompt,
process_name=None, app_root_name=None, is_visual=None)
self._blackboard = Blackboard()
self.set_state(self.default_state)
self._context_provision_executed = False
@property
def default_state(self):
return ContinueMobileAgentState()
仓库中 MobileAgent 的实现还覆盖了 get_prompter()(返回 MobileAgentPrompter)、message_constructor()(组装系统提示与用户内容,支持截图 URL、已安装应用、当前控件、blackboard 等上下文)与 blackboard 属性,新代理可按需覆写。
第 2 步:创建 Processor
# ufo/agents/processors/customized/customized_agent_processor.py
class MobileAgentProcessor(CustomizedProcessor):
def _setup_strategies(self):
# 组合多个数据采集策略
self.strategies[ProcessingPhase.DATA_COLLECTION] = ComposedStrategy(
strategies=[
MobileScreenshotCaptureStrategy(fail_fast=True),
MobileAppsCollectionStrategy(fail_fast=False),
MobileControlsCollectionStrategy(fail_fast=False),
],
name="MobileDataCollectionStrategy",
fail_fast=True,
)
self.strategies[ProcessingPhase.LLM_INTERACTION] = (
MobileLLMInteractionStrategy(fail_fast=True)
)
self.strategies[ProcessingPhase.ACTION_EXECUTION] = (
MobileActionExecutionStrategy(fail_fast=False)
)
self.strategies[ProcessingPhase.MEMORY_UPDATE] = (
AppMemoryUpdateStrategy(fail_fast=False)
)
注意 fail_fast 的语义:数据采集与 LLM 交互失败必须立即暴露(fail_fast=True),因为后续动作依赖其产物;动作执行与记忆更新失败则可优雅处理(fail_fast=False)。移动端还通过 _setup_middleware() 挂载 MobileLoggingMiddleware 保证请求展示格式正确。
第 3 步:创建 MCP 服务器
# ufo/client/mcp/http_servers/mobile_mcp_server.py
def create_mobile_mcp_server(host="localhost", port=8020):
mcp = FastMCP("Mobile MCP Server", stateless_http=False,
json_response=True, host=host, port=port)
@mcp.tool()
async def tap_element(x: int, y: int) -> dict:
# 通过 ADB 或平台 API 执行点击
pass
mcp.run(transport="streamable-http")
实际实现中请参考 mobile_mcp_server.py:数据采集与动作分别拆为两个服务器(端口 8020 / 8021),均通过 _create_auth_provider() 接入 UFO_MCP_API_KEY 的 Bearer Token 校验。
第 4 步:配置代理(third_party.yaml)
仓库真实的 config/ufo/third_party.yaml 已启用 HardwareAgent、LinuxAgent、MobileAgent 三个代理:
# config/ufo/third_party.yaml
ENABLED_THIRD_PARTY_AGENTS: ["HardwareAgent", "LinuxAgent", "MobileAgent"]
THIRD_PARTY_AGENT_CONFIG:
LinuxAgent:
AGENT_NAME: "LinuxAgent"
APPAGENT_PROMPT: "ufo/prompts/third_party/linux_agent.yaml"
APPAGENT_EXAMPLE_PROMPT: "ufo/prompts/third_party/linux_agent_example.yaml"
INTRODUCTION: "For Linux Use Only."
MobileAgent:
AGENT_NAME: "MobileAgent"
APPAGENT_PROMPT: "ufo/prompts/third_party/mobile_agent.yaml"
APPAGENT_EXAMPLE_PROMPT: "ufo/prompts/third_party/mobile_agent_example.yaml"
INTRODUCTION: "For Android Mobile Device Control. Enables remote control and automation of Android devices via ADB and UI interactions."
配置要点:
ENABLED_THIRD_PARTY_AGENTS:以列表形式声明启用的第三方/设备代理,未列入的代理不会被加载;THIRD_PARTY_AGENT_CONFIG.<AgentName>:每个代理一段配置。APPAGENT_PROMPT/APPAGENT_EXAMPLE_PROMPT指向 Prompt 模板(位于 ufo/prompts/third_party/),有视觉能力的代理(如 HardwareAgent)可额外设置VISUAL_MODE: True与API_PROMPT;- 新建代理时,将上述
MobileAgent段落替换为你的代理名与 Prompt 路径即可。
第 5 步:注册设备(devices.yaml)
仓库真实的 config/galaxy/devices.yaml 注册了三台 Linux 设备:
# config/galaxy/devices.yaml
devices:
- device_id: "linux_agent_1"
server_url: "ws://localhost:5001/ws"
os: "linux"
capabilities:
- "server"
metadata:
os: "linux"
performance: "medium"
logs_file_path: "/root/log/log1.txt"
dev_path: "/root/dev1/"
warning_log_pattern: "WARN"
error_log_pattern: "ERROR or FATAL"
auto_connect: true
max_retries: 5
字段说明(供新设备参考):
device_id:设备唯一标识,客户端启动时以--client-id与之对应;server_url:设备客户端连接的 WebSocket 地址(形如ws://localhost:5010/ws);os:设备操作系统类型;capabilities:能力列表,供编排器进行任务-设备匹配;metadata:自由扩展的设备描述(日志路径、性能档位、日志模式等);auto_connect:是否自动连接;max_retries:连接/任务重试上限。
第 6 步:启动服务端与客户端
# 终端 1:启动 Agent 服务端
python -m ufo.server.app --port 5010
# 终端 2:启动设备客户端
python -m ufo.client.client \
--ws --ws-server ws://localhost:5010/ws \
--client-id mobile_agent_1 \
--platform android
# 终端 3:启动 MCP 服务器(设备上或可访问的端点)
python -m ufo.client.mcp.http_servers.mobile_mcp_server --port 8020
启动顺序与依赖关系:MCP 服务器提供平台能力 → 设备客户端通过 AIP/WebSocket 连向服务端 → 服务端编排并下发命令。若设备侧 MCP 启用了 API Key 校验,请确保客户端侧同步配置 UFO_MCP_API_KEY。
9. 相关文档
- Agent 架构 —— 三层架构深度解析
- LinuxAgent 快速上手 —— LinuxAgent 部署指南
- Server 概览 —— 服务端编排
- Client 概览 —— 客户端执行
- MCP 概览 —— Model Context Protocol
- AIP 协议 —— Agent 交互协议
- 创建第三方代理教程 —— 第三方代理开发指南
10. 总结
- 设备代理控制完整平台(Windows、Linux、移动端),与仅扩展特定功能的第三方代理有本质区别;
- 服务端-客户端分离将 LLM 推理与系统执行隔离,是安全与可扩展性的基础;
- 三层设计(状态层 → 策略层 → 命令层)提供了模块化、可扩展的框架,
@depends_on/@provides声明式数据流贯穿策略执行; - LinuxAgent 是最佳参考实现:源码与文档完备,安全模型(白名单 + 危险模式扫描 + shell=False + API Key)值得所有新代理复用;
- 6 部分教程覆盖设备代理创建的全部环节,从核心组件、MCP 服务器、客户端配置到 Galaxy 集成;
- MCP 集成实现了平台专属的命令执行,移动端还通过双服务器 + 缓存失效机制保证数据一致。
现在,从 核心组件 开始,动手创建你的第一个设备代理吧。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust4.26 K641- DDeepSeek-V4.1-FlashDeepSeek-V4.1-Flash 是一个多模态混合专家(MoE)模型,拥有 5520 亿骨干参数,并支持最多一百万 token 的上下文长度。该模型原生支持图像和文本输入,并以自回归方式生成文本Python860
SlideSCIPPT插件,支持素材库、AI助手、一键添加图片标题,复制粘贴位置、一键图片对齐、一键插入Markdown(加粗、超链接等行内样式、代码块、LaTeX等块级样式)、便捷导出图片!C#611
Agent-Reach给你的 AI Agent 一键装上互联网能力。13 个平台(网页/GitHub/YouTube/小红书/B站/Twitter/Reddit 等)多后端路由,当下最稳的接入方式替你选好、装好、体检好。GitHub 主仓库同步镜像。Python1294
new-apiAI模型聚合管理中转分发系统,一个应用管理您的所有AI模型,支持将多种大模型转为统一格式调用,支持OpenAI、Claude、Gemini等格式,可供个人或者企业内部管理与分发渠道使用。🍥 A Unified AI Model Management & Distribution System. Aggregate all your LLMs into one app and access them via an OpenAI-compatible API, with native support for Claude (Messages) and Gemini formats.Go23346
JeecgBoot🔥企业级低代码平台集成了AI应用平台,帮助企业快速实现低代码开发和构建AI应用!前后端分离架构 SpringBoot,SpringCloud、Mybatis,Ant Design4、 Vue3.0、TS+vite!强大的代码生成器让前后端代码一键生成,无需写任何代码! 引领AI低代码开发模式: AI生成->OnlineCoding-> 代码生成-> 手工MERGE,显著的提高效率,又不失灵活~Java37451