乐于分享
好东西不私藏

OpenClaw 集成 Agnes AI 完整教程,一句话生成图片和视频

OpenClaw 集成 Agnes AI 完整教程,一句话生成图片和视频

前言养过虾(OpenClaw)的小伙伴应该都知道,OpenClaw本身能操控电脑、整理文件、自动发邮件,但让它画图做视频还得靠外部模型。Agnes AI 的生图生视频 API 免费开放,正好补这个缺口。这篇文章把集成过程完整走一遍,让你的虾不仅会干活,还会创作,生图,生视频。

一、先理清逻辑:虾负责调度,Agnes负责生成

小龙虾是桌面级 Agent,常驻后台,能听懂你的话去操控电脑。但它本身不自带生图生视频模型——这跟 ChatGPT、Claude 一样,核心能力是理解和调度,不是画图。

Agnes AI 提供的是模型即服务(MaaS),通过 REST API 暴露生图、生视频能力。两者结合的逻辑很简单:

你:"帮我画一张赛博朋克城市夜景"      ↓小龙虾(理解意图)→ 调用 Agnes 生图 Skill      ↓Agnes API 生成图片 → 返回 URL      ↓小龙虾下载图片 → 保存到桌面/打开预览

关键点:Skill 是小龙虾的插件,不是独立程序。它运行在 Agent 内部,通过 Agent 的上下文理解你的意图,再决定什么时候调 Agnes。


二、环境准备

2.1 安装小龙虾本体

这里默认你的电脑已经安装了小龙虾,如果不了解如何安装的,可以留言区私信我,我会提供安装包和使用指导。

2.2 确认 Skill 目录

小龙虾的 Skill 插件放在固定目录:

macOS/Linux: ~/.openclaw/skills/Windows:     C:\Users\<用户名>\.openclaw\skills\

后面写的 Agnes Skill 要丢到这个目录里才能被识别。

2.3 申请 Agnes AI API Key

  1. 打开 platform.agnes-ai.com,邮箱注册

  2. 进控制台 → API 管理 → 创建 Key

  3. 复制 Key,后面配置 Skill 时要用

Agnes 的免费计划没有用量限制,但高峰期可能排队。做生产环境的话建议关注付费方案。


三、写 Agnes 生图 Skill

3.1 Skill 目录结构

在 ~/.openclaw/skills/ 下创建:

agnes-image-gen/├── skill.json          # Skill 元数据,Agent 靠这个识别你├── main.py             # 核心逻辑└── requirements.txt    # 依赖

3.2 skill.json(元数据)

{  "name": "agnes-image-gen",  "version": "1.0.0",  "description": "调用 Agnes AI 生成图片",  "author": "你的名字",  "entry": "main.py",  "triggers": [    "画一张",    "生成图片",    "帮我画",    "画个",    "出一张图"  ],  "config": {    "api_key": "",    "default_size": "1024x1024",    "default_style": "realistic"  }}

triggers 是关键:当用户的话里出现这些关键词时,Agent 会自动把这个请求路由到你的 Skill。不需要用户记命令,说人话就行。

3.3 main.py(核心逻辑)

import osimport timeimport jsonfrom pathlib import Pathfrom urllib.request import urlopen, Request# 读取 Skill 配置CONFIG_PATH = Path(__file__).parent / "skill.json"with open(CONFIG_PATH, "r", encoding="utf-8"as f:    CONFIG = json.load(f)API_KEY = os.environ.get("AGNES_API_KEY"or CONFIG["config"]["api_key"]API_BASE = "https://apihub.agnes-ai.com/v1"def generate_image(prompt: str, size: str = None, style: str = None, output_dir: str = None) -> dict:    """调用 Agnes AI 生图 API,下载到本地"""    if not API_KEY:        return {"error""AGNES_API_KEY 未设置,请在环境变量或 skill.json 中配置"}    size = size or CONFIG["config"]["default_size"]    style = style or CONFIG["config"]["default_style"]    try:        width, height = map(int, size.split("x"))    except ValueError:        return {"error"f"尺寸格式错误: {size},请用 宽x高 如 1024x1024"}    # 默认保存到桌面    if not output_dir:        output_dir = os.path.expanduser("~/Desktop")    out_path = Path(output_dir) / f"agnes_img_{int(time.time())}.png"    # 调用 Agnes API    req = Request(        f"{API_BASE}/images/generations",        method="POST",        headers={            "Authorization"f"Bearer {API_KEY}",            "Content-Type""application/json",        },        data=json.dumps({            "model""agnes-image-2.1-flash",            "prompt": prompt,            "width": width,            "height": height,            "style": style,            "n"1,        }).encode("utf-8")    )    try:        with urlopen(req, timeout=120as resp:            data = json.loads(resp.read().decode())            img_url = data.get("data", [{}])[0].get("url""")        if not img_url:            return {"error""API 未返回图片链接"}        # 下载图片        with urlopen(img_url, timeout=60as img_resp:            out_path.write_bytes(img_resp.read())        return {            "success"True,            "file_path"str(out_path),            "dimensions"f"{width}x{height}",            "style": style,            "prompt": prompt,        }    except Exception as e:        return {"error"str(e)}# Skill 入口:Agent 会调用这个函数def run(agent_context: dict) -> dict:    """Agent 传入的 context 包含用户原始输入和解析后的参数"""    prompt = agent_context.get("prompt""")    size = agent_context.get("size")    style = agent_context.get("style")    output_dir = agent_context.get("output_dir")    result = generate_image(prompt, size, style, output_dir)    if result.get("success"):        return {            "message"f"图片已生成并保存到: {result['file_path']}",            "action""open_file",            "file_path": result["file_path"],            "details": result,        }    else:        return {"error": result.get("error""未知错误")}

3.4 requirements.txt

# 标准库够用,不需要额外依赖# 如果后续需要异步,再加 aiohttp

3.5 配置 API Key

两种方式任选:

方式一:环境变量(推荐,更安全)

# 写进 ~/.zshrc 或 ~/.bashrcexport AGNES_API_KEY="你的Key"

方式二:skill.json 直接填

编辑 skill.json,把 config.api_key 填上。


四、写 Agnes 生视频 Skill

视频 Skill 跟图片几乎一样,区别是异步轮询。Agnes 视频生成慢,提交任务后要反复查状态,等到 completed 才能下载。

4.1 目录结构

~/.openclaw/skills/agnes-video-gen/├── skill.json├── main.py└── requirements.txt

4.2 skill.json

{  "name": "agnes-video-gen",  "version": "1.0.0",  "description": "调用 Agnes AI 生成视频",  "author": "你的名字",  "entry": "main.py",  "triggers": [    "生成视频",    "做一段视频",    "生成一段",    "帮我做视频",    "出一段视频"  ],  "config": {    "api_key": "",    "default_resolution": "720p",    "default_duration": 4,    "default_fps": 24  }}

4.3 main.py

import osimport timeimport jsonfrom pathlib import Pathfrom urllib.request import urlopen, RequestCONFIG_PATH = Path(__file__).parent / "skill.json"with open(CONFIG_PATH, "r", encoding="utf-8"as f:    CONFIG = json.load(f)API_KEY = os.environ.get("AGNES_API_KEY"or CONFIG["config"]["api_key"]API_BASE = "https://apihub.agnes-ai.com/v1"RESOLUTIONS = {    "480p": (854480),    "720p": (1280720),    "1080p": (19201080),}def generate_video(prompt: str, duration: int = None,                   resolution: str = None, fps: int = None,                   output_dir: str = None) -> dict:    """调用 Agnes AI 生视频 API,轮询等待完成后下载"""    if not API_KEY:        return {"error""AGNES_API_KEY 未设置"}    resolution = resolution or CONFIG["config"]["default_resolution"]    duration = duration or CONFIG["config"]["default_duration"]    fps = fps or CONFIG["config"]["default_fps"]    if resolution not in RESOLUTIONS:        return {"error"f"不支持的分辨率: {resolution}"}    width, height = RESOLUTIONS[resolution]    if not output_dir:        output_dir = os.path.expanduser("~/Desktop")    out_path = Path(output_dir) / f"agnes_vid_{int(time.time())}.mp4"    # 1. 创建视频任务    req = Request(        f"{API_BASE}/videos",        method="POST",        headers={            "Authorization"f"Bearer {API_KEY}",            "Content-Type""application/json",        },        data=json.dumps({            "model""agnes-video-v2.0",            "prompt": prompt,            "width": width,            "height": height,            "duration": duration,            "fps": fps,        }).encode("utf-8")    )    try:        with urlopen(req, timeout=30as resp:            data = json.loads(resp.read().decode())            task_id = data.get("task_id""")        if not task_id:            return {"error""API 未返回 task_id"}        # 2. 轮询等待完成        print(f"⏳ 视频生成中,任务ID: {task_id}")        video_url = _poll_task(task_id)        # 3. 下载视频        print(f"✅ 生成完成,正在下载...")        with urlopen(video_url, timeout=120as vid_resp:            out_path.write_bytes(vid_resp.read())        return {            "success"True,            "file_path"str(out_path),            "duration"f"{duration}s",            "resolution": resolution,            "fps": fps,            "prompt": prompt,        }    except Exception as e:        return {"error"str(e)}def _poll_task(task_id: str, max_wait: int = 600, interval: int = 5) -> str:    """轮询任务状态,最长等10分钟"""    elapsed = 0    while elapsed < max_wait:        req = Request(            f"{API_BASE}/videos/{task_id}",            headers={"Authorization"f"Bearer {API_KEY}"},        )        with urlopen(req, timeout=30as resp:            data = json.loads(resp.read().decode())            status = data.get("status""")            if status == "completed":                return data.get("output", {}).get("url""")            if status == "failed":                raise RuntimeError(f"任务失败: {data.get('error''未知错误')}")            progress = data.get("progress"0)            if progress > 0:                print(f"  进度: {progress}%")        time.sleep(interval)        elapsed += interval    raise TimeoutError(f"任务 {task_id} 超时")def run(agent_context: dict) -> dict:    prompt = agent_context.get("prompt""")    duration = agent_context.get("duration")    resolution = agent_context.get("resolution")    fps = agent_context.get("fps")    output_dir = agent_context.get("output_dir")    result = generate_video(prompt, duration, resolution, fps, output_dir)    if result.get("success"):        return {            "message"f"视频已生成: {result['file_path']}",            "action""open_file",            "file_path": result["file_path"],            "details": result,        }    else:        return {"error": result.get("error""未知错误")}

五、重启 Agent,测试效果

Skill 文件放好后,重启小龙虾让它加载新插件。右键托盘图标 → 退出,再重新启动。

打开对话窗口,试试这些:

你:帮我画一张日落时分的海边灯塔虾:正在生成图片...虾:图片已生成并保存到: /Users/你的名字/Desktop/agnes_img_1735123456.png     [自动打开图片预览]
你:做一段樱花飘落的视频,5秒,1080p虾: 视频生成中,任务ID: vid_abc123虾:  进度: 30%虾:  进度: 60%虾:  进度: 90%虾: 生成完成,正在下载...虾:视频已生成: /Users/你的名字/Desktop/agnes_vid_1735123789.mp4     [自动打开视频播放]

六、进阶玩法:让虾理解上下文

上面是基础版,Agent 每次只处理单轮请求。要让虾更聪明,可以结合它的上下文记忆多 Skill 协作

6.1 先出图,再出视频

你:帮我画一张赛博朋克城市的概念图虾:[生成图片并打开]你:基于这张图的主题,做一段4秒的视频虾:理解,基于"赛博朋克城市"主题生成视频...     [自动调用视频 Skill,无需重复描述]

实现方式:在 Skill 的 run() 函数里读取 agent_context["history"],提取上一轮的结果和关键词,作为视频生成的 prompt。

6.2 自动整理到文件夹

生成后让虾自动把图片/视频移到指定文件夹:

# 在 run() 返回前加一段from datetime import datetimetarget_dir = Path.home() / "Documents" / "Agnes生成" / datetime.now().strftime("%Y-%m")target_dir.mkdir(parents=True, exist_ok=True)out_path.rename(target_dir / out_path.name)return {"message"f"已保存到: {target_dir / out_path.name}"}

6.3 生成skill 方式有多种

一种是上面的通过编写和修改代码,这种方式适合有编码能力的人,增加和修改功能点比较方便,灵活。

另一种:可以直接在chat窗口,发送指令,让OpenClaw 给你生成一个你需要的skill。这种方式对没有编码经验的人比较友好,例如:“请帮我生成一个skill,名字叫generate-Image,调用Agnes AI 的生图模型xxxx, API Key 是xxxxxxx”。

七、踩坑记录

坑 1:Skill 放了但 Agent 没识别

检查目录层级。小龙虾只认 ~/.openclaw/skills/<skill-name>/skill.json 这个结构,多一层或少一层都读不到。

坑 2:API Key 设了但报 401

环境变量和 Agent 进程不在同一个 shell session。建议:

  • 写进 ~/.zshrc 后 source ~/.zshrc

  • 或者直接在 skill.json 的 config.api_key 里填(方便但别提交到 Git)

坑 3:视频生成超时

Agnes 视频高峰期排队严重。如果 10 分钟还不够:

  • 调大 _poll_task 的 max_wait 参数

  • 或者改成非阻塞模式:提交任务后返回 task_id,让用户过几分钟再查

坑 4:中文提示词效果差

Agnes 模型对英文提示词更友好。可以在 Skill 里加一层自动翻译(调 Google Translate API 或本地模型),或者提示用户用英文描述。

坑 5:Agent 调错 Skill

triggers 关键词冲突时,Agent 可能路由错。比如”画一张视频”同时命中生图和生视频。解决:

  • 把 triggers 设计得更精确(如”画一张”只给图片,”做一段”只给视频)

  • 在 Skill 内部加二次校验,不匹配时返回”这不是我该处理的”让 Agent 重试


八、写在最后

小龙虾(OpenClaw)的价值在于把 AI 能力落地到桌面操作,Agnes AI 的价值在于提供高质量的生图生视频模型。两者结合,相当于给你的电脑配了一个既能干活又能创作的智能助手。

这套方案的核心优势:

  • 本地运行:Agent 和文件都在本地,数据不上云

  • 自然语言交互:不用记命令,说人话就行

  • 免费试错:Agnes API 免费,Skill 开发零成本

  • 可扩展:会写 Python 就能加新能力,不限于 Agnes

#AI创作#漫剧#AI生图生视频