Claude Code 的 Computer Use 功能让 AI 直接操控桌面环境:点击按钮、输入文字、截图分析界面状态。AI 能看见屏幕并操作鼠标键盘,带来的安全风险同样真实:误删文件、点错按钮、泄露敏感信息。为此,Claude Code 设计了一套九层安全关卡系统,每一层都可以独立拦截危险操作。底层通过 Python Bridge 实现跨语言通信,TypeScript 代理驱动 Python 执行器完成实际的桌面交互。
整体架构与 Python 选型 Computer Use 的整体架构是一个典型的跨语言代理模式。Claude Code(TypeScript)负责策略决策和权限控制,Python 进程负责执行实际的桌面操作,两者通过 JSON-RPC over stdio 进行通信。这个分层设计的好处是职责清晰:TypeScript 层处理安全逻辑和模型交互,Python 层专注平台 API 调用。
1 2 3 4 5 Claude Code (TypeScript) ↓ JSON-RPC over stdio Python Bridge (computer_controller.py) ↓ Platform Abstraction Desktop Environment
选择 Python 而非 TypeScript 原生实现桌面操作,核心原因是生态成熟度。pyautogui、PyObjC、xdotool 这些库已经稳定运行多年,跨平台接口一致。如果在 TypeScript 中通过 native addon 调用系统 API,维护成本会显著增加。
选型因素
Python 方案
TypeScript 原生方案
库生态
pyautogui/PyObjC 成熟稳定
需要 native addon,生态碎片化
跨平台一致性
三平台接口统一
每个平台需单独封装
开发迭代速度
纯 Python 快速修改
编译 native 代码,迭代慢
维护成本
社区维护,更新频繁
需自行适配各系统 API 变更
24 个桌面操作工具 Computer Use 提供了 24 个工具,覆盖输入、显示、文件、进程四个类别。输入类工具处理鼠标点击、双击、拖拽、滚轮滚动、键盘组合键、单键按压、文字输入和剪贴板粘贴。显示类工具负责屏幕截图、获取屏幕尺寸、窗口列表查询、窗口激活、窗口位置和尺寸获取。文件类工具包括读写删除列目录移动复制和查看文件信息。进程类工具提供进程列表查询、启动新进程和终止进程三个操作。
类别
工具数
核心能力
输入(Input)
9
鼠标点击/拖拽/滚动、键盘输入/组合键、剪贴板粘贴
显示(Display)
6
截图、屏幕尺寸、窗口列表/激活/位置/尺寸
文件(File)
7
读写删除列目录移动复制、文件信息查询
进程(Process)
3
进程列表、启动进程、终止进程
以鼠标点击工具为例,工具定义通过 JSON Schema 描述参数结构,包括坐标、按钮类型、点击次数。Claude Code 将这些定义注册为可调用的 tool,模型在需要操作桌面时通过 tool_use 发起调用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 const computer_mouse_click = { name: 'computer_mouse_click' , inputSchema: { type : 'object' , properties: { x: { type : 'number' , description: 'X coordinate' }, y: { type : 'number' , description: 'Y coordinate' }, button: { type : 'string' , enum : ['left' , 'right' , 'middle' ], default : 'left' }, clicks: { type : 'number' , default : 1 }, }, required: ['x' , 'y' ], }, description: 'Click at the specified coordinates' , }
九层安全关卡 安全设计是 Computer Use 系统的核心。九层关卡从外到内层层递进,每一层都可以独立拦截操作。这不是理论设计,而是实际代码中的检查链:操作必须通过所有关卡才能执行,任何一层返回 deny 都会立即终止。
关卡
名称
拦截规则
Gate 1
功能门控
tengu_computer_use Feature Flag 必须开启
Gate 2
用户确认
首次使用弹出确认对话框,用户必须授权
Gate 3
操作类型检查
写操作需要额外的写权限确认
Gate 4
路径约束
文件操作限制在白名单目录,禁止访问 .git、.claude、系统目录
Gate 5
危险命令过滤
拦截 rm -rf、killall 等命令,禁止访问密码管理器和银行应用
Gate 6
屏幕边界检查
鼠标坐标必须在屏幕分辨率范围内,窗口操作必须针对可见窗口
Gate 7
操作频率限制
每秒最多 10 次操作,连续失败 3 次自动暂停
Gate 8
截图内容分析
检测密码框、私人信息等敏感内容,检测错误弹窗
Gate 9
实时监控
用户随时 Ctrl+C 中断,操作日志实时输出
代码实现上,gateComputerUseAction 函数按顺序执行所有检查,返回 allow、deny 或 ask 三种结果。前七层在操作执行前完成检查,Gate 8 在截图后进行内容分析,Gate 9 贯穿整个操作生命周期。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 function gateComputerUseAction ( action: ComputerUseAction, context: ToolUseContext, ): GateResult { if (!feature('tengu_computer_use' )) { return { action: 'deny' , reason: 'Feature not enabled' } } if (!context.computerUseConsent) { return { action: 'ask' , reason: 'First-time use requires consent' } } if (isWriteAction(action) && !context.computerUseWriteConsent) { return { action: 'ask' , reason: 'Write operation requires confirmation' } } if (action.type === 'file' ) { if (!isInAllowedDirectory(action.path, context.allowedDirectories)) { return { action: 'deny' , reason: 'Path not in allowed directories' } } } if (isDangerousCommand(action)) { return { action: 'deny' , reason: 'Dangerous command blocked' } } if (action.type === 'mouse' ) { const screenSize = getScreenSize() if (action.x < 0 || action.x > screenSize.width || action.y < 0 || action.y > screenSize.height) { return { action: 'deny' , reason: 'Coordinates out of screen bounds' } } } if (isRateLimited(context.computerUseHistory)) { return { action: 'wait' , reason: 'Rate limit exceeded' , waitTime: 1000 } } return { action: 'allow' } }
跨语言通信桥梁 TypeScript 和 Python 之间的通信基于 JSON-RPC 2.0 协议,传输层使用 stdio。TypeScript 端构造标准 JSON-RPC 请求(包含 method、params、id),写入 Python 进程的 stdin,然后从 stdout 读取响应。这种设计避免了 HTTP 开销,同时保持了协议的标准化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 interface BridgeMessage { jsonrpc: '2.0' id: number method: string params: Record<string , unknown> } interface BridgeResponse { jsonrpc: '2.0' id: number result?: unknown error?: { code: number ; message: string } } async function callBridge (method: string , params: unknown ): Promise <unknown > { const message: BridgeMessage = { jsonrpc: '2.0' , id: nextId++, method, params, } bridgeProcess.stdin.write(JSON .stringify(message) + '\n' ) const response = await readBridgeResponse() if (response.error) { throw new BridgeError(response.error.code, response.error.message) } return response.result }
Python 端的 ComputerController 维护一个方法名到处理函数的映射表,循环读取 stdin 中的 JSON-RPC 请求,分发到对应的处理器执行,将结果或错误写回 stdout。每个请求独立处理,异常不会中断整个进程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 import jsonimport sysfrom typing import Anyclass ComputerController : def __init__ (self) : self.handlers = { 'computer_mouse_click' : self.mouse_click, 'computer_keyboard_type' : self.keyboard_type, 'computer_screen_capture' : self.screen_capture, } def run (self) : while True : line = sys.stdin.readline() if not line: break request = json.loads(line) method = request['method' ] params = request['params' ] id = request['id' ] try : handler = self.handlers[method] result = handler(**params) response = { 'jsonrpc' : '2.0' , 'id' : id, 'result' : result } except Exception as e: response = { 'jsonrpc' : '2.0' , 'id' : id, 'error' : {'code' : 1 , 'message' : str(e)} } sys.stdout.write(json.dumps(response) + '\n' ) sys.stdout.flush() def mouse_click (self, x: int, y: int, button: str = 'left' ) : import pyautogui pyautogui.click(x, y, button=button) def screen_capture (self) -> str: import pyautogui import base64 screenshot = pyautogui.screenshot() return base64.b64encode(screenshot).decode('utf-8' )
截图分析与窗口管理 截图是 Computer Use 感知环境的主要手段。模型决定截图后,computer_screen_capture 工具通过 Python Bridge 调用 pyautogui.screenshot(),将 PNG 编码为 Base64 返回给 Claude Code,作为 image block 注入当前对话上下文,模型通过多模态能力分析截图内容。在截图注入之前,系统会通过本地 OCR 检测敏感关键词(password、secret、api key、token 等),如果命中则对敏感区域进行模糊处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 async function filterScreenshot ( base64Image: string , ): Promise <FilterResult > { const detectedText = await localOcrDetect(base64Image) const sensitiveKeywords = ['password' , 'secret' , 'api key' , 'token' ] const foundSensitive = sensitiveKeywords.some(k => detectedText.toLowerCase().includes(k) ) if (foundSensitive) { return { action: 'blur' , regions: findSensitiveRegions(detectedText), reason: 'Sensitive content detected' , } } return { action: 'allow' } }
窗口管理涉及三个平台各自的窗口 API 差异。系统定义了统一的 WindowInfo 接口(包含 id、title、process、position、size、visible 字段),各平台适配层负责将系统原生窗口信息转换为这个统一格式。激活窗口前会检查目标是否属于敏感应用(密码管理器、银行应用等),如果是则拒绝激活。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 interface WindowInfo { id: number title: string process: string position: { x: number ; y: number } size: { width: number ; height: number } visible: boolean } async function activateWindow (windowId: number ): Promise <void > { const window = await getWindowInfo(windowId) if (!window ) { throw new Error ('Window not found' ) } const sensitiveApps = ['Keychain Access' , '1Password' , 'Banking App' ] if (sensitiveApps.some(app => window .title.includes(app))) { throw new Error ('Cannot activate sensitive application' ) } await callBridge('computer_window_activate' , { window_id: windowId }) }
审计日志与中断机制 所有 Computer Use 操作都会记录审计日志,包括时间戳、操作类型、参数、执行结果(success/deny/error)、拒绝原因和执行耗时,可选附加操作后的截图。日志以 JSONL 格式持久化到 .claude/computer_use_history.jsonl,便于事后追溯和问题排查。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 interface ComputerUseLogEntry { timestamp: number action: string params: Record<string , unknown> result: 'success' | 'deny' | 'error' reason?: string duration: number screenshot?: string } const LOG_PATH = '.claude/computer_use_history.jsonl' async function appendLog (entry: ComputerUseLogEntry ): Promise <void > { const logLine = JSON .stringify(entry) + '\n' await fs.appendFile(LOG_PATH, logLine) }
中断机制是安全体系的最后一道防线。用户按下 Ctrl+C 后,TypeScript 进程通知 Python Bridge 停止执行,将鼠标移到安全位置,记录中断事件到审计日志。Python 端维护一个 emergency_stop 标志,收到停止信号后退出主循环并将鼠标恢复到预设的安全坐标。这个设计确保即使在极端情况下,用户也能立即夺回控制权。
1 2 3 4 5 6 7 8 9 10 11 12 13 class ComputerController : def __init__ (self) : self.emergency_stop = False def run (self) : while not self.emergency_stop: def stop (self) : self.emergency_stop = True pyautogui.moveTo(self.safe_x, self.safe_y)
三平台适配 三个平台的窗口操作 API 差异显著。Windows 通过 ctypes 调用 Win32 API(GetForegroundWindow、GetWindowTextW),macOS 通过 PyObjC 访问 NSWorkspace,Linux 依赖 xdotool 命令行工具。每个平台适配层都需要实现窗口获取、激活、位置查询、尺寸查询等完整接口。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import pyautoguiimport ctypesfrom ctypes import wintypesdef get_active_window () : """获取活动窗口""" hwnd = ctypes.windll.user32.GetForegroundWindow() return hwnd def get_window_title (hwnd) : """获取窗口标题""" length = ctypes.windll.user32.GetWindowTextLengthW(hwnd) title = ctypes.create_unicode_buffer(length + 1 ) ctypes.windll.user32.GetWindowTextW(hwnd, title, length + 1 ) return title.value
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import pyautoguifrom AppKit import NSWorkspace, NSRunningApplicationdef get_active_window () : """获取活动窗口""" workspace = NSWorkspace.sharedWorkspace() app = workspace.activeApplication() return app.localizedName() def activate_window (title) : """激活窗口""" workspace = NSWorkspace.sharedWorkspace() apps = workspace.runningApplications() for app in apps: if app.localizedName() == title: app.activateWithOptions_(NSApplicationActivateIgnoringOtherApps) break
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import pyautoguiimport subprocessdef get_active_window () : """获取活动窗口""" result = subprocess.run( ['xdotool' , 'getactivewindow' ], capture_output=True , text=True ) return int(result.stdout.strip()) def get_window_title (window_id) : """获取窗口标题""" result = subprocess.run( ['xdotool' , 'getwindowname' , str(window_id)], capture_output=True , text=True ) return result.stdout.strip()
关键源文件索引
文件
职责
src/tools/ComputerUseTool/ComputerUseTool.ts
工具定义、权限检查、安全关卡
src/tools/ComputerUseTool/bridge.ts
Python Bridge 通信
src/tools/ComputerUseTool/security.ts
九层安全关卡实现
src/tools/ComputerUseTool/tools.ts
24 个工具定义
src/tools/ComputerUseTool/screenshotFilter.ts
截图内容过滤
computer_controller.py
Python 执行器主入口
platform/windows.py
Windows 平台适配
platform/macos.py
macOS 平台适配
platform/linux.py
Linux 平台适配
系列文章导航: