在线工具 fc小游戏开发管理

🦞 OpenClaw(龙虾)如何调用本地程序,并与大模型完美协作?

原创
admin 2小时前 阅读数 29 #AI速报

在智能自动化的世界里,有一个理想:让 AI 不仅会“思考”,还能在本地动手执行任务。OpenClaw(俗称“龙虾”)是一款开源的 Node.js/TypeScript 智能体,完美实现了这个目标。

它能接收自然语言指令,通过大模型生成计划,再调用本地程序执行任务,并将结果反馈给模型,形成闭环协作。本文将结合 OpenClaw 开源仓库的真实代码示例,深度解析它的工作机制、架构设计、工具注册方式、任务调度以及安全策略。


1️⃣ 为什么 OpenClaw 要调用本地程序?

AI 在云端生成文字内容固然强大,但在现实场景中,很多任务必须访问本地资源:

  • 📊 数据统计和分析:本地 JSON/CSV 文件

  • 🖼️ 图像视频处理:调用 Photoshop、ffmpeg 等工具

  • 🗂️ 自动化文件管理:整理、压缩、移动文件

OpenClaw 的核心理念是:

大模型负责理解和规划任务,本地程序负责执行,OpenClaw 连接二者,实现闭环自动化。


2️⃣ OpenClaw 架构概览

OpenClaw 主要由三层组成:

  1. LLM 层:解析用户指令、生成任务计划

  2. 工具层(Tool Layer):封装可调用的本地程序或脚本

  3. 任务调度层(Executor/Task Layer):管理任务队列、异步执行、状态与日志

整体流程如下:

用户输入指令 🗣️        
│        ▼LLM 层解析任务 🧠        
│        ▼OpenClaw 工具层调用本地程序 🖥️        
│        ▼任务调度层收集输出 📦        
│        ▼结果回传给 LLM,生成最终报告 ✨       
│        ▼输出给用户 🎯

关键代码片段解析:

1. 执行终端命令(bash/powershell)

文件:src/tools/system/bash.ts(核心)
import { exec } from 'execa';
import { Tool } from '../tool.interface';

export class BashTool implements Tool {
  name = 'bash';
  description = '执行本地终端命令(Linux/macOS)';

  async execute(params: { command: string }): Promise<any> {
    try {
      // 执行命令
      const { stdout, stderr } = await exec(params.command, {
        shell: true,
        timeout: 30000, // 30秒超时
      });
      return {
        success: true,
        stdout: stdout.trim(),
        stderr: stderr.trim(),
      };
    } catch (error: any) {
      return {
        success: false,
        error: error.message,
        code: error.exitCode,
      };
    }
  }

  // 参数校验
  async validate(params: any): Promise<boolean> {
    return typeof params.command === 'string' && params.command.length > 0;
  }
}

2. Windows 专用:执行 PowerShell/CMD

文件:src/tools/system/powershell.ts
import { exec } from 'execa';
import { Tool } from '../tool.interface';

export class PowerShellTool implements Tool {
  name = 'powershell';
  description = '执行Windows PowerShell命令';

  async execute(params: { command: string }): Promise<any> {
    try {
      const { stdout, stderr } = await exec(params.command, {
        shell: 'powershell.exe', // 指定Shell
        timeout: 30000,
      });
      return { success: true, stdout, stderr };
    } catch (err: any) {
      return { success: false, error: err.message };
    }
  }
}

3. 打开本地应用程序(通用)

文件:src/tools/system/open-app.ts
import { exec } from 'execa';
import { Tool } from '../tool.interface';

export class OpenAppTool implements Tool {
  name = 'open_app';
  description = '打开本地应用(如:notepad, chrome, finder, terminal)';

  async execute(params: { app: string }): Promise<any> {
    let cmd: string;

    // 跨平台命令
    switch (process.platform) {
      case 'win32':
        cmd = `start ${params.app}`; // Windows
        break;
      case 'darwin':
        cmd = `open -a ${params.app}`; // macOS
        break;
      case 'linux':
        cmd = `xdg-open ${params.app}`; // Linux
        break;
      default:
        throw new Error('不支持的系统');
    }

    await exec(cmd, { shell: true });
    return { success: true, message: `已打开: ${params.app}` };
  }
}

4. 工具注册与加载(核心入口)

文件:src/tools/tool-registry.ts
import { BashTool } from './system/bash';
import { PowerShellTool } from './system/powershell';
import { OpenAppTool } from './system/open-app';

// 全局工具注册表
export class ToolRegistry {
  private static tools = new Map<string, any>();

  // 注册所有内置工具
  static init() {
    this.register(new BashTool());
    this.register(new PowerShellTool());
    this.register(new OpenAppTool());
  }

  static register(tool: any) {
    this.tools.set(tool.name, tool);
  }

  static get(toolName: string) {
    return this.tools.get(toolName);
  }
}

5. 执行器:AI调用工具的中枢

文件:src/tools/tool-executor.ts
import { ToolRegistry } from './tool-registry';

export class ToolExecutor {
  async execute(toolName: string, params: any): Promise<any> {
    // 1. 查找工具
    const tool = ToolRegistry.get(toolName);
    if (!tool) throw new Error(`工具不存在: ${toolName}`);

    // 2. 权限校验(安全核心)
    if (!this.checkPermission(toolName)) {
      throw new Error(`无权限执行: ${toolName}`);
    }

    // 3. 参数校验
    const valid = await tool.validate(params);
    if (!valid) throw new Error('参数无效');

    // 4. 执行本地命令/程序
    return await tool.execute(params);
  }

  // 简化权限:白名单
  private checkPermission(toolName: string): boolean {
    const allowed = ['bash', 'open_app', 'powershell'];
    return allowed.includes(toolName);
  }
}

3️⃣ 注册和调用本地工具(真实代码示例)

OpenClaw 的本地工具是 Node.js/TypeScript 的模块,可以通过 claw.registerTool() 注册。以下是开源示例改写:

import { createClaw } from "@open-claw/core";
import { runLocalCommand } from "@open-claw/tools";

const claw = createClaw({
 name: "小助手",
 model: "qwen-7b",
});

// 注册压缩工具
claw.registerTool({
 name: "compressFolder",
 description: "压缩指定文件夹为 zip 文件",
 run: async ({ folderPath }: { folderPath: string }) => {
   const zipPath = `${folderPath}.zip`;
   const result = await runLocalCommand("zip", ["-r", zipPath, folderPath]);
   return { message: `压缩完成: ${zipPath}`, output: result };
 },
});

🔹 解释:

  • runLocalCommand 是 OpenClaw 核心工具,用于执行本地命令

  • 工具注册后可以被大模型在计划中直接调用

  • 输出结果会被捕获并传回 LLM 层


4️⃣ 大模型生成任务计划

大模型不仅解析指令,还会将任务拆解为可执行步骤:

const task = "帮我压缩 report 文件夹,并生成汇总报告";
const plan = await claw.plan(task);

console.log(plan.steps);
/* 输出示例:
[
 { tool: "compressFolder", args: { folderPath: "report" } },
 { tool: "generateSummary", args: { input: "report.zip" } }
]
*/

这里的 plan.steps 就是大模型生成的任务执行序列,每个步骤会对应一个本地工具调用。


5️⃣ 执行任务计划

执行计划时,OpenClaw 使用异步任务队列,同时捕获输出与错误:

for (const step of plan.steps) {
 try {
   const result = await claw.executeStep(step);
   console.log(`步骤 ${step.tool} 执行成功:`, result);
 } catch (err) {
   console.error(`步骤 ${step.tool} 执行失败:`, err);
 }
}

特点:

  • 异步执行,支持并发任务

  • 每一步都记录状态、日志和输出

  • 可捕获错误并触发重试机制


6️⃣ 回传结果给大模型

任务执行完成后,本地工具输出会被回传给大模型:

const summary = await claw.getResult("generateSummary");
console.log("AI 生成报告:\n", summary);

这样,用户看到的最终结果是大模型分析 + 本地程序执行的闭环输出。


7️⃣ 高级特性

  1. 异步任务与并发

await Promise.all([
 claw.executeTool("compressFolder", { folderPath: "report1" }),
 claw.executeTool("compressFolder", { folderPath: "report2" }),
]);
  1. 工具组合:将多个工具组合成高级任务,大模型可以自由调用

  2. 流式输出:任务执行中可以实时回传进度给大模型

  3. 安全机制

    • 白名单工具

    • 沙箱执行

    • 权限控制

    • 日志追溯

  4. 任务调度优化:支持队列、优先级调度和重试机制,提高大规模任务处理效率


8️⃣ 实战案例:统计数据并生成报告

假设 report 文件夹里有大量 JSON 文件,你希望统计数据并生成自然语言报告:

const taskPlan = [
 { tool: "compressFolder", args: { folderPath: "report" } },
 { tool: "processData", args: { inputFile: "report.zip" } },
 { tool: "generateSummary", args: { inputFile: "summary.json" } },
];

async function executeTaskPlan(plan) {
 for (const step of plan) {
   try {
     const output = await claw.executeStep(step);
     console.log(`${step.tool} 执行成功:`, output);
   } catch (err) {
     console.error(`${step.tool} 执行失败:`, err);
   }
 }
}

executeTaskPlan(taskPlan);

流程解析:

  1. 压缩文件夹

  2. 调用本地 Node.js 脚本处理数据

  3. 回传数据给大模型生成自然语言报告


9️⃣ 总结

OpenClaw(龙虾)的核心价值在于:

  • 闭环自动化:自然语言指令 → 大模型规划 → 本地工具执行 → 结果回传

  • Node.js/TypeScript 全栈:工具注册、任务调度、输出捕获

  • 安全与可扩展性:白名单、沙箱、权限控制、日志追溯

通过 OpenClaw,你可以让 AI 不只是“告诉你该怎么做”,而是直接帮你动手完成任务


手机扫描二维码访问

微信扫一扫支付
微信logo微信扫一扫,打赏作者吧~
版权声明

如有错误或侵权,请联系我修改或删除,QQ374060。

热门