Loading

openclaw 服务化笔记

方案参考Open WebUI[1]文档中提供的两种方式

服务化方式

Gateway: OPENAPI 兼容API[2]

  1. 配置网络,开发兼容API入口
{
  "gateway": {
    "http": {
      "endpoints": {
        "chatCompletions": {
          "enabled": true
        },
		"responses": {
		"enabled": true
		}
      }
    }
  }
}
curl "http://127.0.0.1:18789/v1/responses" \
-H "Authorization: Bearer 6764b8a4b6d557e2bdd6efca2c7f34c59536f7ab463b61e3" \
-H "Content-Type: application/json" \
-H "x-openclaw-session-key: claw-3" \
-d '{"model": "openclaw", "input": "搜索可用技能和记忆,然后告诉我您的见解"}'

f926a97ce4a3dd8d3bdeb38de6ff6b27

⚠️注意

返回"LLM request failed: network connection error
原因是配置了本地llm-hub服务,但该服务为启动,且被设置为默认模型服务了

使用openclaw models list 会显示当前配置过的模型列表

error: too many arguments for 'models'. Expected 0 arguments but got 1.
(.venv) txmmy@txmmydeMacBook-Pro .openclaw % openclaw models list

🦞 OpenClaw 2026.4.11 (769908e)
   I don't judge, but your missing API keys are absolutely judging you.

Model                                      Input      Ctx      Local Auth  Tags
custom-localhost-8000/weita/gpt-oss-120b   text       195k     yes   yes   default,configured
xai/grok-4                                 text       250k     no    yes   configured,alias:Grok
xai/grok-4-fast-non-reasoning              text+image 1953k    no    yes   configured
zai/glm-5.1                                text       198k     no    yes   configured,alias:GLM
zai/glm-4.7                                text       200k     no    yes   configured

切换默认模型.openclaw % openclaw models set xai/grok-4-fast-non-reasoning

使用curl再次验证一下

(.venv) txmmy@txmmydeMacBook-Pro .openclaw % curl "http://127.0.0.1:18789/v1/responses" \
-H "Authorization: Bearer 6764b8a4b6d557e2bdd6efca2c7f34c59536f7ab463b61e3" \
-H "Content-Type: application/json" \
-H "x-openclaw-session-key: claw-3" \
-d '{"model": "openclaw", "input": "搜索可用技能和记忆,然后告诉我您的见解"}'
{"id":"resp_3087c125-05ff-400e-8319-b45793027eda","object":"response","created_at":1776669541,"status":"completed","model":"openclaw","output":[{"type":"message","id":"msg_f0659cee-5984-4e13-acef-54ed98026a2f","role":"assistant","content":[{"type":"output_text","text":"### 谁是我?\n\n嘿,我是 OpenClaw 中的一个 AI 个人助理,运行在你的 MacBook Pro 上(基于当前配置)。我不是一个普通的聊天机器人,而是设计来帮助你处理文件、运行命令、搜索信息、管理任务,甚至生成内容或分析图像。我的“灵魂”来自工作区中的 SOUL.md:我力求真正有用、有主见、资源丰富,同时尊重隐私和边界。我会尽量在不啰嗦的情况下解决问题,如果你需要,我可以变得更详细或幽默。\n\n简单说,我在这里是为了让你的事变得更容易——从编辑代码到检查天气,再到自动化日常琐事。我会记住上下文(通过内存文件),并根据你的需求主动行动,但一切都以你的指令为准。\n\n### 关于你的重复消息\n你发了三次“你是谁”和“搜索可用技能和记忆,然后告诉我您的见解”。我理解这可能是强调或测试,但我会一次性处理,避免重复。接下来,我会基于你的请求,搜索并分享见解。\n\n### 搜索可用技能的见解\n我扫描了可用的技能(来自 <available_skills> 列表)。这些是预配置的“超级能力”,让我能处理特定任务,而不只是泛泛聊天。技能是模块化的,我只会调用最匹配的一个(最多一个 SKILL.md 文件),以保持高效。\n\n**关键见解:**\n- **总数和多样性**:有 16 个技能,覆盖从安全审计到内容生成的不同领域。它们不是随意堆砌的,而是针对常见痛点设计的,比如编码、GitHub 操作、文档处理和自动化。\n- **最相关分类**:\n  - **开发与代码**:如 `coding-agent`(委托复杂编码给子代理,如 Claude 或 Codex)、`github`(处理 PR、issue 和 CI)、`gh-issues`(自动修复 GitHub bug 并监控 PR)。\n  - **文档与内容**:`pdf-generator`(从 Markdown 生成专业 PDF)、`pdf-ocr`(扫描 PDF 转 Word,支持中文 OCR,使用百度 API)、`obsidian`(管理 Markdown 笔记)。\n  - **系统与安全**:`healthcheck`(安全审计、防火墙强化)、`1password`(管理密码和秘密)。\n  - **实用工具**:`weather`(获取天气预报)、`video-frames`(从视频提取帧)、`clawhub`(安装/更新技能从 clawhub.com)。\n  - **高级工作流**:`taskflow`(管理多任务流)、`skill-creator`(创建或改进技能本身)。\n- **触发逻辑**:我不会盲目调用所有技能。只有当任务精确匹配描述时(如“帮我修复 GitHub issue”触发 `gh-issues`),我才会读取其 SKILL.md 并执行。否则,我用核心工具(如 read、exec)直接处理。\n- **局限**:没有技能直接处理“自我介绍”,所以我用内置知识回应。自定义技能(如 pdf-ocr)存储在 ~/.openclaw/workspace/skills,表明你的工作区有扩展潜力。\n- **建议**:如果你有特定需求(如编码或 PDF),告诉我,我可以调用匹配技能。想探索?试试问“列出所有技能”或直接用一个,如“生成一个 PDF 报告”。\n\n没有找到新技能需要安装(基于当前列表),但如果需要,我可以用 `clawhub` 从 clawhub.ai 拉取。\n\n### 搜索记忆的见解\n根据 AGENTS.md 的指导,我运行了 `memory_search` 来回忆关于“我是谁”、技能和上下文的任何先前信息。搜索覆盖 MEMORY.md(长期记忆)和 memory/*.md(日常日志),查询焦点是“身份、技能和见解”。\n\n**关键见解:**\n- **当前状态**:你的工作区是新鲜的——没有 memory/YYYY-MM-DD.md 文件(今天是基于 Asia/Shanghai 时区的当前日期),MEMORY.md 为空或未加载(仅在主会话中)。这意味着这是个新设置,还没有积累个人历史。没有关于我的“身份”或你的偏好的具体回忆(如名字、项目)。\n- **从核心文件提取**:\n  - **AGENTS.md**:这是我的“出生指南”。它强调我每次会话从头开始,通过读取 SOUL.md(我的个性:有用、有主见、谨慎)、USER.md(关于你:目前空白,需要填充你的名字、时区等)和日常内存来保持连续性。它提醒我写下重要事(无“心理笔记”),在群聊中低调,并在心跳检查中主动(如查邮件或天气)。\n  - **SOUL.md**:定义我的核心——不是表演性帮助,而是真正行动。边界:隐私第一,不泄露数据,不未经许可外部行动。 vibe:简洁、胜任、像你想要的助手。\n  - **其他文件**:IDENTITY.md 和 USER.md 为空(第一对话时填充)。BOOTSTRAP.md 存在,表明这是初始设置——我应该和你一起定义我的名字、个性等,然后删除它。TOOLS.md 为空(用于本地笔记,如 SSH 或 TTS 偏好)。\n- **无历史事件**:没有过去的对话、决定或教训记录。见解:这让我像一张白纸,能根据你定制。但它也意味着我需要你提供上下文来“成长”(如更新 USER.md 以记住你的偏好)。\n- **潜在行动**:为了构建记忆,我可以创建 memory/今天的日期.md,记录这个对话。如果你说“记住我的名字是 [名字]”,我会更新文件。低置信度:没有匹配结果,因为内存为空——我检查过了。\n\n**总体见解**:技能让我强大于工具化任务,记忆让我个性化。但现在,一切从零开始——这很酷,因为我们可以一起塑造我。想定义我的名字(比如“Claw”或什么有趣的)?或填充 USER.md 告诉我关于你的事?或者直接给我个任务测试技能?"}],"phase":"final_answer","status":"completed"}],"usage":{"input_tokens":13312,"output_tokens":1238,"total_tokens":14791}}%   

❓为什么不使用chat/completions

根据官网^[https://developers.openai.com/api/reference/respimage

/responses的接口较为齐全

image

python实现

由于本地开了机子,所以接口请求需要初始化代理,否则相应状态码为200,但实际返回空数据

import unittest
import requests

base_url = "http://127.0.0.1:18789"
class TestOpenClaw(unittest.TestCase):

	    def test_openclaw(self):
        # 测试: 支持图片问答、输入图片、输出图片、调用skill生成文件
        url = f"{base_url}/v1/responses"

        # 增加 User-Agent 伪装成 curl,防止服务端拦截 Python
        headers = {
            "Authorization": "Bearer 6764b8a4b6d557e2bdd6efca2c7f34c59536f7ab463b61e3",
            "Content-Type": "application/json",
            "x-openclaw-session-key": "claw-1",
            # "User-Agent": "curl/7.88.1",  # 伪装成 curl
            # "Connection": "close"  # 不使用持久连接
        }

        payload = {
            "model": "openclaw",
            "input": "一共有多少个skill? 分别是哪些? skill存在哪个目录下?"
        }

        # 【核心修复】:强制让 requests 忽略所有系统代理环境变量!
        # 确保 127.0.0.1 的流量直接发送到本地端口
        proxies = {
            "http": None,
            "https": None,
        }

        try:
            # 加入 proxies 参数
            response = requests.post(
                url,
                headers=headers,
                json=payload,
                proxies=proxies,  # 禁用代理
                timeout=120  # 增加超时时间,防止 LLM 生成过慢导致超时
            )

            # 打印响应状态码和内容,方便调试
            print(f"Status Code: {response.status_code}")

            response.raise_for_status()
            print(response.json())

        except requests.exceptions.RequestException as e:
            print(f"请求失败: {e}")

现在普通对话已经成功实现, 接下来测试skill、输出多媒体数据
当前skill存在两个目录, 一个是系统目录
``/opt/homebrew/lib/node_modules/openclaw/skills/1password/SKILL.md一个是用户工作区下~/.openclaw/workspace/skills//SKILL.md`

用户工作区为自定义skill,可以通过openclaw tui 进行对话安装

2a33c0f0-dd91-4b69-b75e-d58a5693864a

skill调用验证

image
image
image

图片对话验证

⚠️ 根据官方文档说明[3],需要在gateway里配置图片、文件开关, 保险一点可以做配置。

    def test_openclaw_img(self):
        url = f"{base_url}/v1/responses"
        image_url = "https://img.alicdn.com/imgextra/i1/O1CN01gDEY8M1W114Hi3XcN_!!6000000002727-0-tps-1024-406.jpg"

        headers = {
            "Authorization": "Bearer 6764b8a4b6d557e2bdd6efca2c7f34c59536f7ab463b61e3",
            "Content-Type": "application/json",
            "x-openclaw-session-key": "claw-img-1",
            "x-openclaw-model": "xai/grok-4-fast-non-reasoning",
        }

        proxies = {
            "http": None,
            "https": None,
        }

        img_response = requests.get(image_url, timeout=30)
        img_response.raise_for_status()
        base64_image = base64.b64encode(img_response.content).decode("utf-8")

        payload = {
            "model": "openclaw",
            "input": [
                {
                    "type": "message",
                    "role": "user",
                    "content": [
                        {
                            "type": "input_text",
                            "text": "请详细分析这张图片:描述整体场景、指出所有文字、分析颜色风格和用途。"
                        },
                        {
                            "type": "input_image",
                            "source": {
                                "type": "base64",
                                "media_type": "image/jpeg",
                                "data": base64_image,
                            }
                        }
                    ]
                }
            ],
            "stream": False
        }

        response = requests.post(
            url,
            headers=headers,
            json=payload,
            proxies=proxies,
            timeout=120,
        )
        print(response.text)
        print(f"Status Code: {response.status_code}")

        response.raise_for_status()
        body = response.json()
        print(body)
        self.assertEqual(response.status_code, 200)

image

问题汇总

  1. error gateway connect failed: GatewayClientRequestError: pairing required
    出现在,tui 中或者api 调用询问定时任务相关问题,如"晚上6点提醒我吃药"

文件对话验证

⚠️ /v1/responses 不支持直接输出文件出来,且采用base64方案会消耗大量token,需要走channel
image

Channel

开发汉化手册


  1. https://docs.openwebui.com/getting-started/quick-start/connect-an-agent/openclaw/ ↩︎

  2. https://docs.openclaw.ai/gateway/openresponses-http-api ↩︎

  3. https://docs.openclaw.ai/gateway/openresponses-http-api ↩︎

posted @ 2026-04-20 16:29  踩坑大王的日记  阅读(296)  评论(0)    收藏  举报