ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

CLI-Anything:用命令行外壳让Agent稳定操控桌面软件

CLI-Anything:用命令行外壳让Agent稳定操控桌面软件 从去年开始我一直在琢磨一件事让 Agent 写代码、调 API、处理文本这些已经非常成熟了但要让 Agent 去碰电脑上那些正经桌面软件——比如 Excel、用友、金蝶或者某个没有 API 的绘图工具——就立刻变得非常拧巴。很多人第一反应是用截图加视觉模型让 Agent看着屏幕点鼠标。这条路我试了很长时间成本高、不稳定后来转到 CLI-Anything 这个思路上突然就顺了。CLI-Anything 的核心思路非常朴素与其教 Agent 看懂像素不如给每个桌面软件套上一层命令行外壳让 Agent 像调用 Linux 命令一样去操作软件。它的价值在于把图形界面里那些不可控的按钮、菜单、弹窗翻译成一堆稳定的、可审计的、可重试的指令。这套思路特别适合那些没有 API、没有数据库权限、又不得不自动化的老旧桌面软件也适合想要让 Agent 真正干活而不是聊天的开发者。我在实际项目中用这套方案做了不少事也踩了不少坑。这篇文章就围绕五个玩法展开从原理到配置再到排错把能直接复用的经验都写出来。1. 让 Agent看屏幕点按钮为什么天然不靠谱先说一个我反复验证过的结论只要 Agent 的操作路径里有识别像素坐标这一步这条链路就注定是脆的。1.1 三种主流方案的共同软肋目前让 Agent 操作桌面软件的常见做法大体有三种我用过一个遍截图 视觉大模型把屏幕截下来丢给模型让它输出点击坐标 (x, y)。看起来很美但模型对像素坐标的判断本来就有误差再加上分辨率缩放、窗口拖动、弹窗遮挡坐标随时漂移。我实测在 4K 屏上同一个按钮窗口位置稍微挪一点坐标就差出三四十个像素模型还浑然不觉。图像模板匹配预先截好按钮图片让程序在屏幕上找相似区域。这套路在固定环境下勉强能用但按钮的 hover 状态、暗色模式、字体渲染差异都会让匹配率暴跌。而且匹配到相似却不相同的东西时比找不到更可怕。传统 UI 自动化框架比如 pywinauto、uiautomation直接调用 Windows 的 UI Automation 接口按控件的名字和类型去定位。这个其实已经比截图靠谱很多但它的调用方式零散Agent 没有一个统一、稳定的操作协议可以用。问题不在于底层技术不行而在于 Agent 面对一个图形软件时缺乏一套结构化、可编程、可回滚的操作接口。你让 Agent 点鼠标就像让一个实习生对着屏幕找按钮他能找到但每次都可能找偏。1.2 CLI 思路的本质把看屏幕变成发命令CLI-Anything 的思路是反过来的。它不要求 Agent 理解坐标和像素而是要求我们把软件的常用操作预先抽象成命令。Agent 要做的事情从找到那个按钮并点击变成了发送一条命令保存当前文档。这个转变非常重要因为 LLM 最擅长的事情之一就是生成结构化的、符合格式的命令文本。生成save --path /tmp/a.pdf的可靠程度远远高于判断一个按钮在屏幕上的像素位置。用生活类比来说你不会教一个外国朋友找到那个绿色圆形按钮按下去而是会直接告诉他按保存键。CLI-Anything 做的就是把这句按保存键变成 Agent 也能听懂的标准口令。1.3 CLI-Anything 到底解决了什么问题我理解 CLI-Anything 这个名字的含义是Anything 的 CLI——给任意桌面软件一个命令行接口。它解决的三个核心问题稳定性命令是确定的只要软件界面结构没变命令就不会失效而坐标是随时会变的。可审计Agent 每次执行了什么操作全部以文本命令的形式记录下来出了问题能回放、能定位。可组合命令可以串联、嵌套、加参数Agent 可以在一条流程里反复调用而每次调用都是一次函数调用。它本质上做了一层翻译层把 Agent 发来的文本命令翻译成底层 UI 自动化库能执行的动作序列。这层翻译工作由人来配置一次之后 Agent 就能稳定复用。2. CLI-Anything 的工作原理把图形界面翻译成命令要真正用好它得先搞清楚它内部是怎么工作的。这里以我在 Windows 上的实践为例macOS 的原理大同小异。2.1 三个核心组件一个完整的 CLI-Anything 实现通常由三部分构成组件职责类比命令定义层用 YAML/JSON 描述某个软件支持哪些命令每个命令对应什么 UI 操作序列岗位说明书执行器解析命令调用系统 UI 自动化接口去实际点击、输入、读文本干活的员工对接层把命令以标准输入输出、HTTP 接口或 MCP 协议暴露给 Agent对外发布的通知渠道2.2 命令定义的基本原则绑控件不绑坐标这是 CLI-Anything 的灵魂。为软件定义命令时我强烈建议优先绑定控件的可访问性属性控件名称、类型、窗口标题而不是绑定坐标。Windows 下有两条技术路线按优先级使用UI AutomationUIA系统级的无障碍接口能拿到窗口的完整控件树。每个按钮、输入框都有 Name、AutomationId、ControlType 等信息。执行器通过控件名称就能准确定位。坐标模拟兜底对于实在没有可访问性信息的自绘控件比如某些游戏引擎做的界面只能退化成坐标点击。但这类命令要额外加截图校验并且要容忍它偶尔失败。我在定义命令时遵循一条铁律能用 UIA 的就绝不碰坐标。坐标方案可能一次成功五次失败UIA 方案虽然配置时麻烦一点但一旦配好就非常稳定。2.3 最小的可执行示例让 Agent 操作记事本以 Windows 自带的记事本为例一个最简单的新建并输入文字命令配置大概长这样app: 记事本 commands: - name: new_file description: 新建一个记事本文档 steps: - action: launch target: notepad.exe - action: wait_window target: 无标题 - 记事本 timeout: 5000 - name: type_text description: 在当前文档输入文本 params: - name: content type: string steps: - action: set_focus target: 记事本 - action: type target: Edit value: {{content}}当 Agent 需要操作时它只需要发出cli-anything run 记事本.new_file cli-anything run 记事本.type_text --content 你好世界执行器拿到命令后会按 steps 逐条执行启动程序、等待窗口出现、聚焦窗口、找到 Edit 控件、输入内容。整个过程 Agent 从头到尾不需要知道记事本窗口长什么样。2.4 执行器怎么保证点对了这是 CLI-Anything 相对裸用 pyautogui 最大的区别。它会在每一步执行后主动验证控件状态。比如点击保存按钮前先确认窗口里存在名为保存的按钮且处于可用状态输入文字后再读取一次输入框内容做比对。这些验证逻辑都写在步骤定义里例如可以给每个 action 加一个verify字段- action: click target: 保存 verify: type: button_enabled expect: false # 点击后按钮变灰说明已经触发保存这一步验证让 Agent 的操作从执行完就完事变成了执行完确认结果这一点在后面讲长链路流程时非常重要。3. 玩法一批量报表导出最值得先试的甜点场景如果你刚接触 CLI-Anything我建议第一个尝试的场景就是批量报表导出。这类任务重复、枯燥、操作路径固定而且几乎没有例外分支非常适合练手。3.1 场景还原我接过的实际需求是这样财务同学每天要把一张 CSV 表格里的数据填进一个 Excel 模板调整好格式后另存为 PDF文件名要按日期和单号命名。一天大概二十多份每份手动操作三分钟中间还容易填错行。这类任务用 Python 直接用 pandas 处理当然可以但如果模板里有很多格式、宏、特殊样式代码复现的成本非常高而且一旦模板更新就要改代码。CLI-Anything 的价值在于软件还是那个软件模板也还是那个模板只是操作者从人变成了 Agent。3.2 给 Excel 定义一套可复用的命令我定义了下面这几条命令一条管启动一条管打开文件一条管另存为 PDFapp: Excel commands: - name: open_file params: - name: path steps: - action: launch target: C:\\Program Files\\Microsoft Office\\root\\Office16\\EXCEL.EXE - action: send_keys modifiers: [ctrl, o] - action: input target: 文件名 value: {{path}} - action: click target: 打开 - name: fill_cell params: - name: cell - name: value steps: - action: input target: 单元格 value: {{cell}} - action: type target: 单元格 value: {{value}} - action: send_keys keys: [enter] - name: save_as_pdf params: - name: output_path steps: - action: menu path: [文件, 另存为] - action: input target: 文件名 value: {{output_path}} - action: select target: 保存类型 value: PDF (*.pdf) - action: click target: 保存注意几个细节open_file里我用了快捷键 CtrlO 而不是点菜单因为用快捷键打开文件对话框在 UIA 树里更稳定fill_cell里填写完单元格后必须回车确认否则数据不会真正写入save_as_pdf里保存类型下拉框的值在不同语言版本的 Office 里不一样配置时要按本机实际显示的文字来写。3.3 Agent 调度循环命令定义好后Agent 做的工作就是一个循环cli-anything run Excel.open_file --path /data/template.xlsx cli-anything run Excel.fill_cell --cell B2 --value 20250115 cli-anything run Excel.fill_cell --cell C2 --value 合同A-001 cli-anything run Excel.save_as_pdf --output_path /data/out/20250115_合同A-001.pdf二十多份文件跑下来成功率能做到九成以上剩下失败的通常是模板偶发的弹窗或者系统级对话框。踩过一次坑之后我在执行器里给每个动作加了五秒超时和两次重试基本就稳了。3.4 一个重要的判断不是所有软件都该用 CLI-Anything做这个场景前先想清楚如果软件本身有内置脚本能力比如 Excel 的 VBA、设计软件内的插件脚本优先用内置方案性能好、可控性强。CLI-Anything 更适合那些没有脚本接口、没有 API 的软件或者脚本能力太弱、维护成本高于 UI 操作的场景。这是我做完报表任务后的最大体会方案选型比方案实现更关键。4. 玩法二老客户端数据录入没有 API 的系统的 Agent 入口第二个玩法我认为是 CLI-Anything 最有价值的战场老旧的 C/S 架构客户端。这类软件往往是公司核心业务系统但没有 API没有数据库直连权限甚至没有自动化测试接口唯一的操作方式就是人工在表单里录入。4.1 场景还原典型的场景是业务员每天把邮件里的订单信息逐条录入到公司的订单管理系统里。订单系统是一个十年前的 Delphi 写的客户端界面倒是很清楚但没有任何接口。之前有人尝试用 RPA 产品成本高、维护还要单独养一个人。用 CLI-Anything 的方式实现分三步第一步把订单系统的表单操作变成命令。包括打开新增订单窗口、填入客户名称、填入金额、选择业务类型、点击保存、读取保存结果。第二步让 Agent 从邮件里提取字段。邮件读取可以直接走 IMAP或用 CLI-Anything 控制 Outlook关键是把非结构化的邮件正文转成结构化的 JSON 字段。第三步Agent 串联两个系统。先从邮件提取字段再逐条调用订单系统的命令完成录入。4.2 这个场景里最关键的难点结果验证录入数据不像导出报表输错了是要出问题的。在这个场景里我踩过一个很深的坑命令执行完了但数据没有真正保存成功。起因是保存按钮点击后系统弹了一个是否确认保存的对话框但我的命令序列里没有处理这个弹窗导致保存动作实际没有完成。后来我总结了这类场景下必须做的三件事读取结果文本保存后通过 UIA 读取当前窗口内是否出现保存成功的提示。这一步是底线。处理异步弹窗命令配置里必须包含等待窗口出现的动作。比如点保存后等待最多三秒窗口树里出现确认按钮。保留截图证据每次命令执行完都让执行器截一张图便于事后人工复核。下面是我为保存订单命令加的验证逻辑- name: save_order steps: - action: click target: 保存 - action: wait_window target: 确认 timeout: 3000 - action: click target: 确定 - action: read_window_text target: 提示 output_var: last_msg - action: assert_contains source: {{last_msg}} expect: 保存成功assert_contains这一步是关键只要断言失败执行器就立刻停止后续命令并返回错误信息Agent 看到错误后会尝试截图、判断原因必要时放弃这条记录并继续下一条。这样整批数据即使有一两条失败Agent 也能自己隔离异常不会把错误一路带下去。4.3 为什么不用现成的 RPA 产品可能有人会说这不是 RPA 干的事情吗区别在于思路传统 RPA 是把流程写死每一步都是预先录好的脚本CLI-Anything 配合 Agent相当于让 Agent 在命令字典的约束下灵活编排。邮件里来了一个特殊格式的订单Agent 会当场调整命令参数甚至临时组合出新的命令序列而不是让运维去改脚本重新发布。在灵活性和可控性之间CLI-Anything 这个方案站在了中间位置命令字典是人为控制的命令组合是 Agent 自由发挥的。我用下来感觉这是非常舒服的一个平衡点。5. 玩法三桌面软件冒烟测试把 UI 操作变成可回归的用例第三个玩法有点出人意料用 CLI-Anything 做桌面软件的冒烟测试。我是在一次给自研客户端做回归测试时偶然发现这个用法很顺手。5.1 为什么不用现成的测试框架桌面端的 UI 自动化测试框架其实不少比如 WinAppDriver、Appium但我个人维护起来很痛苦用例写起来繁琐控件定位经常要写一堆长长的 XPath而且跑挂一次要调试半天。最核心的问题是这些框架的用例是死的不会根据界面变化自己去调整。CLI-Anything 则不同。开发者只需要把软件的关键路径定义成命令真正的测试用例交给 Agent 自然语言描述Agent 再翻译成命令序列。这样命令定义是一次性的后续复用到所有用例用例内容是 Agent 根据当前需求动态生成的覆盖到的分支远多于手写用例失败时能自动截图、收集窗口文本排查效率高。5.2 把测试用例转成命令执行我给自己开发的一个 CAD 工具客户端做了冒烟测试。规划了这几个命令打开工程、导出 DXF、导出 PDF、读取导出文件是否存在、窗口文本断言。测试流程通过一个 pipeline 文件来描述tests: - name: 导出DXF冒烟 steps: - app: CADTool command: open_project params: { path: ./samples/123.prj } - app: CADTool command: export_dxf params: { path: ./out/123.dxf } - app: Shell command: check_file params: { path: ./out/123.dxf, expect: exists }Shell是一个内置的应用提供check_file、run_script这样的命令方便在流程里做文件系统校验和脚本调用。这样测试覆盖就不局限于 UI 操作还能校验操作结果落在文件系统上的形态。我把这套 pipeline 接到了 CI 上。每天早上自动跑一轮跑挂了就把 Agent 的截图和命令日志发给开发群。效果比我预想的好原来每周要花半天人工冒烟现在只需要处理 Agent 报出来的异常。5.3 这个玩法的边界和坑桌面自动化测试最容易翻车的一点窗口焦点和会话状态。如果测试机器锁屏了UIA 虽然还能读但模拟点击经常失效。如果同时开着多个软件实例控件名称会冲突执行器可能点错窗口。如果软件启动很慢必须配足超时不能上来就点按钮。我的建议是给测试单独准备一台机或者一个虚拟机保持桌面不锁屏、分辨率固定、没有其他软件抢占屏幕。这些都是血泪教训有一次测试跑挂了半小时最后发现是远程桌面的断线导致焦点窗口变了跟被测软件一点关系都没有。另外测试脚本里的断言一定要独立于 UI 之外再加一层。就算 UI 上显示导出成功我也要求 Shell 命令再检查一次文件是否存在、大小是否非零。UI 显示的状态可能骗人文件系统不会。6. 玩法四长链路流程编排Agent 当流程管理员而不是操作员前三个玩法本质都是Agent 执行单条命令第四个玩法玩的是编排一个任务涉及多个软件、多个步骤、还可能中途失败需要人工介入。6.1 场景还原每日销售日报一个很常见的场景每天早上十点要生成前一天的销售日报然后发给业务群。链路是这样的从销售系统导出昨天的原始数据销售系统有 API这一步是脚本用 Excel 打开数据、刷新透视表用 BI 工具打开报表模板并刷新BI 工具没有开放 API只能操作界面把生成的 PDF 发给钉钉群。在这个链路里CLI-Anything 管理第 2 和第 3 步其他步骤由 Agent 直接调用 API 完成。关键在于整个流程要能被中断、被恢复、被追踪。6.2 引入 checkpoint 机制长任务跟短任务最大的区别是短任务失败了大不了重跑长任务失败了从零开始就是灾难。比如前面二十页报表已经跑完了第十九页因为网络断了一下失败重跑意味着前面全部白做。所以我在 CLI-Anything 的执行器上层加了一个 checkpoint 机制把每个大任务拆成若干小任务每个小任务成功后就记录一个进度标记。比如用本地 JSON 文件记录{ current_step: excel_refresh, finished: [export_sales_data, excel_open], last_output: /data/out/sales.csv }Agent 在启动任务时先读取 checkpoint发现excel_open已经完成就直接从excel_refresh开始不需要重新打开文件。这个机制配合 Agent 非常自然因为 Agent 本来就擅长分支判断。它只需要先看进度文件再决定下一步执行什么命令。而传统 RPA 要自己维护一套进度状态机复杂度高得多。6.3 重试、降级和人工介入长链路跑起来遇到不可控情况是常态。我设定了三级处理策略自动重试命令执行失败如果是窗口没找到、焦点丢失这类瞬时问题自动重试两到三次。智能降级重试仍失败Agent 尝试换一条路径。比如 Excel 的另存为按钮找不到就改用快捷键 CtrlShiftS。人工介入如果降级也失败Agent 停止任务并把当前截图、错误信息、已执行的命令日志发到人工群等人处理。这套三级策略让整个日报任务的失败率大幅下降而且就算失败也不会造成半小时的返工。核心经验是不要把重试做成无脑循环一定要让 Agent 先看懂失败原因再决定下一步。无脑重试只会把一次失败放大成十次失败。6.4 编排层的下一步多 Agent 协作到了这一步自然就开始往多 Agent 的方向走。我在实际项目里会让三个 Agent 分工协作数据提取 Agent负责连接各类 API拉取和清洗数据UI 操作 Agent专职调用 CLI-Anything 命令操作桌面软件编排主 Agent负责调度上面两个管理流程状态处理中断和汇总结果。UI 操作 Agent 固定在沙箱环境里运行拿到的权限最小连网络都不通只能操作 CLI-Anything 暴露出来的命令接口。这样即便它操作出了问题影响范围也被限制在桌面软件这一层不会波及主流程和其它系统。7. 玩法五把命令集封装成 Tool/Skill开放给其他 Agent 框架最后一个玩法相对高阶一点把 CLI-Anything 定义好的命令集封装成标准的 Tool 或 Skill供 LangChain、Dify、CrewAI 这些 Agent 框架统一调用。这样一来你前面给每个软件配的命令字典就变成了团队里所有 Agent 都可以复用的数字员工生产力工具包。7.1 为什么值得做这一层封装很多 Agent 项目跑不起来卡在了一个很尴尬的地方Agent 只会对话和调用 API但公司里真正有价值的操作都在那些古老的桌面软件里。封装之后桌面软件的能力就能像 API 一样被任意 Agent 消费。举个例子。一个做合同审核的 Agent它需要做到读取合同 PDF在合同管理系统老客户端里查询合同编号对比费用条款在审批窗口里填上审核结论。第 2 和第 4 步如果没有 CLI-AnythingAgent 就完全无计可施。封装后这个 Agent 可以像这样调用from cli_anything import DesktopApp contract_sys DesktopApp(合同管理系统) # 在系统里按合同编号查询 result contract_sys.run( query_contract, params{contract_no: HT-2025-0032} ) # 读取查询结果窗口里的文本 contract_info contract_sys.run(read_result_text) # 把审核结论填进去 contract_sys.run( fill_approval, params{decision: 通过, comment: 费用条款一致} )对上层 Agent 而言DesktopApp就是一个普通工具对象和调用一个 HTTP API 没有任何区别。7.2 两个关键设计Schema 和权限审批封装成 Tool 时有两个设计点决定了这个方案能不能落地一是给每个命令生成标准的 JSON Schema。这样上层 Agent 框架能自动知道命令支持哪些参数、参数类型是什么从而正确生成调用。我的做法是为每个命令生成一个参数描述{ name: query_contract, description: 按合同编号查询合同信息, parameters: { type: object, properties: { contract_no: { type: string, description: 合同编号 } }, required: [contract_no] } }二是加一层人工审批队列。这是安全上的底线。Agent 生成的命令在执行之前先进入一个审批队列对于只读类命令比如查询、读取窗口文本直接放行对于写操作比如填表、保存、删除则必须有人工点击确认后才真正执行。我最初没有加审批队列结果 Agent 有一次在测试环境里把一个窗口反复打开了十几遍。虽然没造成损失但这件事让我意识到给 Agent 太大的 GUI 操作自由度就像给一个实习生一把图章但没人盖章审核迟早会出事。7.3 Skill 化从功能到能力包再往上可以把一组命令打包成一个 Skill。这跟现在 Agent 社区里说的Agent Skills是一个思路——比如导出月度报表这个 Skill内部包含了打开 Excel、填充参数、另存 PDF、发邮件四个子任务。Skill 的好处是上层 Agent 不需要知道具体细节只需要说帮我导出 2 月份的报表就能自动加载这个 Skill 并把参数填好。我在实际使用中把常用的十几种操作都做成了 Skill 包团队里其他项目可以直接引用省掉了重复配置的时间。8. 实操中我踩过的坑稳定性、安全与性能前面几个玩法写得很顺利但真实过程里到处是坑。这一章把我觉得最值得分享的教训集中讲一下。8.1 稳定性UI 元素定位要坚守可访问性优先CLI-Anything 的稳定性九成取决于命令定义时用的定位方式。我总结了一条优先级链AutomationId最稳定是开发者在代码里定义的唯一标识轻易不变控件 Name次之但受语言版本、界面文案调整影响控件类型 窗口层级关系适用于没有 ID 的控件坐标最后手段能不用就不用。我见过太多人图省事直接写坐标当时能用等分辨率一变全部报废。用可访问性树定位配置时多花十分钟后面能省几天的排查时间。另外凡是涉及异步弹窗的步骤必须显式声明等待窗口出现。很多命令失败不是动作错了而是点击前弹窗还没出来或者点击后弹窗还没消失后续步骤就像在空房间里找墙上的东西。8.2 安全给 Agent 的操作划定边界这个主题必须单独拿出来讲。给 Agent 开放桌面软件操作权限本质上是给了一个能按键、能输入、能点一切的隐形手权限边界不划清楚会出事。我的安全底线包括命令白名单Agent 只能调用已经定义过的命令不允许它随便生成任意 UI 操作工作目录隔离所有文件读写都限制在指定目录禁止访问系统目录和用户文档目录危险操作拦截封禁 AltF4、CtrlW、Win 键等快捷键组合防止 Agent 误关窗口或触发系统功能全量日志留痕每条命令执行前后都记录日志和截图保留至少三十天。特别是沙箱这块条件允许的话建议把 Agent 放到一个隔离环境里跑哪怕只有一个虚拟机也比直接在本机跑稳妥得多。我自己的 UI 操作 Agent 就是跑在一个独立虚拟机里虚拟机里只装必须的软件和数据文件。8.3 性能并行不是免费的午餐多个 Agent 同时操作同一个桌面软件会遇到严重的竞争问题——窗口焦点争抢、按钮状态竞争、数据文件锁冲突。我实测下来两个 Agent 同时操作同一个 Excel 实例出错率翻倍都不止。解决思路有几个按推荐程度排一软件一实例每个 Agent 进程各开一个软件实例互不干扰串行队列多个 Agent 共用一个执行器指令排队执行桌面会话隔离用多用户会话或虚拟机实现真正的桌面隔离代价是资源开销大。命令行工具的并行度天然比 GUI 操作高CLI-Anything 无论怎么优化最终瓶颈都在你只有一块屏、一个前台窗口焦点这个物理限制上。所以在设计流程时尽量把可并行的任务放在命令行和 API 层做GUI 操作层保持串行这个原则能让整体吞吐提升很多。8.4 调试技巧日志要能回放最后分享一个调试技巧。CLI-Anything 命令执行失败时只看报错信息往往不够尤其是 UI 操作这种强上下文依赖的任务必须能回放整个执行过程。我的执行器里为每条命令记录了执行前的界面状态摘要当前活动窗口标题、按钮可点击状态每一步动作的结果关键节点的截图最终的窗口文本内容。排错时打开日志基本上五分钟内能定位问题是窗口没等到是控件名变了还是焦点被切走这套日志设计让我排查自动化任务的效率提升了不止一倍。只要你做桌面自动化日志里不放截图就是给自己埋雷。反正在经历过这些坑之后我所有需要操作桌面软件的任务都优先走 CLI-Anything 这条路而不是再去教 Agent 认坐标、看像素。这套方案不一定适合所有软件但对那些没有 API 的老桌面系统来说它确实是最让 Agent长出手脚的高性价比路径。
返回列表