最近在折腾 OpenClaw 的自定义模型配置,顺手用它搭了一个命令行笔记助手练手。全程用 AI 辅助写代码,从环境配置到项目跑通大概 30 分钟,记录一下过程。

一、目标

做一个命令行 Markdown 笔记助手,功能很简单:输入一段文字自动整理成结构化笔记、对已有 .md 文件做摘要、根据关键词扩写段落。

重点是——全程用 OpenClaw 辅助写代码,并且通过自定义 Provider 配置接入不同的模型,方便开发时随时切换。

二、配置 OpenClaw 自定义 Provider

OpenClaw 默认用的是官方模型,但它支持添加任何 OpenAI 兼容的 API 端点作为自定义 Provider。我这里用 ai.tikhub.io 作为统一入口,一个 Key 就能调 GPT、Gemini 等多个模型。

方法一:命令行引导

openclaw onboard
? Select a model provider: Custom provider
? Provider ID: tikhub
? Base URL: https://ai.tikhub.io/v1
? Model ID: gpt-4o
? API Key: 你的API-Key
? API compatibility: openai-completions

方法二:直接改配置文件

编辑 ~/.openclaw/openclaw.json

{
  "models": {
    "providers": {
      "tikhub": {
        "baseUrl": "https://ai.tikhub.io/v1",
        "api": "openai-completions",
        "apiKey": "你的API-Key",
        "models": [
          { "id": "gpt-4o", "name": "GPT-4o", "contextWindow": 128000, "maxTokens": 16384 },
          { "id": "gemini-2.5-flash", "name": "Gemini 2.5 Flash", "contextWindow": 1048576, "maxTokens": 8192 },
          { "id": "gemini-2.5-pro", "name": "Gemini 2.5 Pro", "reasoning": true, "contextWindow": 1048576, "maxTokens": 8192 }
        ]
      }
    },
    "defaults": { "model": { "primary": "tikhub/gpt-4o" } }
  }
}

注意点:baseUrl 一定要以 /v1 结尾;reasoning: true 是给推理模型的标记;改完配置需要重启 OpenClaw。

验证:启动 OpenClaw,随便问一句话,能正常回复就说明配好了。

三、让 OpenClaw 生成项目代码

新建项目目录,启动 OpenClaw:

mkdir markdown-note-assistant && cd markdown-note-assistant
openclaw

在 OpenClaw 里描述需求:

> 帮我初始化一个 Python CLI 项目,功能:
> 1. 输入文字 → 调 LLM → 输出结构化 Markdown 笔记
> 2. 读取 .md 文件 → 生成摘要
> 3. 根据关键词扩写笔记段落
> 用 requests 直接调 OpenAI 兼容 API,用 click 做 CLI,
> API 地址和 Key 从环境变量读取

大概 2 分钟,OpenClaw 生成了完整的项目结构。以下是核心代码(做了一些微调):

LLM 调用封装 note_assistant/llm.py

import os
import requests

def call_llm(prompt: str, system_prompt: str = "", model: str = "gpt-4o") -> str:
    base_url = os.getenv("AI_BASE_URL", "https://ai.tikhub.io/v1")
    api_key = os.getenv("AI_API_KEY")
    if not api_key:
        raise ValueError("请设置环境变量 AI_API_KEY")

    messages = []
    if system_prompt:
        messages.append({"role": "system", "content": system_prompt})
    messages.append({"role": "user", "content": prompt})

    resp = requests.post(
        f"{base_url}/chat/completions",
        headers={
            "Content-Type": "application/json",
            "Authorization": f"Bearer {api_key}"
        },
        json={"model": model, "messages": messages, "temperature": 0.7, "max_tokens": 2048},
        timeout=60
    )

    if resp.status_code != 200:
        raise RuntimeError(f"API 调用失败: {resp.status_code} - {resp.text}")
    return resp.json()["choices"][0]["message"]["content"]

CLI 命令 note_assistant/commands.py

import click
from .llm import call_llm

@click.group()
def cli():
    """Markdown 笔记助手"""
    pass

@cli.command()
@click.argument("text")
@click.option("--model", default="gpt-4o", help="模型名,如 gpt-4o / gemini-2.5-flash")
def organize(text, model):
    """将文字整理成结构化 Markdown 笔记"""
    system_prompt = """你是一个笔记整理助手。请将输入内容整理成结构化 Markdown:
1. 用合适的标题层级组织要点
2. 重要概念加粗
3. 末尾添加 3-5 个关键词标签"""
    click.echo(f"正在使用 {model} 整理...\n")
    click.echo(call_llm(text, system_prompt=system_prompt, model=model))

@cli.command()
@click.argument("filepath", type=click.Path(exists=True))
@click.option("--model", default="gpt-4o")
def summarize(filepath, model):
    """读取 .md 文件并生成摘要"""
    with open(filepath, "r", encoding="utf-8") as f:
        content = f.read()
    system_prompt = """请生成简洁的中文摘要:一句话总结 + 3-5 条核心要点"""
    click.echo(call_llm(content, system_prompt=system_prompt, model=model))

@cli.command()
@click.argument("filepath", type=click.Path(exists=True))
@click.argument("keyword")
@click.option("--model", default="gpt-4o")
def expand(filepath, keyword, model):
    """根据关键词扩写笔记段落"""
    with open(filepath, "r", encoding="utf-8") as f:
        content = f.read()
    system_prompt = f"""找到与 "{keyword}" 最相关的段落并扩写,保持 Markdown 格式,返回完整文档"""
    click.echo(call_llm(content, system_prompt=system_prompt, model=model))

四、跑起来

export AI_BASE_URL="https://ai.tikhub.io/v1"
export AI_API_KEY="你的API-Key"
pip install -e .

测试一下:

note-ai organize "今天开会讨论了Q3的OKR,产品要用户增长20%,技术要完成微服务拆分,运营做三次大促,招聘预算批了后端3人前端2人"

输出:

## Q3 OKR 会议纪要

### 产品目标
- **用户增长 20%**(Q3核心指标)

### 技术目标
- 完成**微服务架构拆分**

### 运营计划
- 计划执行 **3 次大促活动**

### 团队扩招
- 后端:**3 人** / 前端:**2 人**(预算已批准)

---
**关键词:** `Q3 OKR` `用户增长` `微服务` `大促` `招聘`

切模型只需要改 --model 参数:

note-ai organize "..." --model gemini-2.5-flash   # 用 Gemini 2.5 Flash
note-ai organize "..." --model gemini-2.5-pro     # 用 Gemini 2.5 Pro

五、迭代开发:继续用 OpenClaw 加功能

项目跑通之后,在 OpenClaw 里用自然语言继续迭代:

加对比模式: “帮我加一个 compare 命令,同时调用两个模型处理同一段文字,把结果并排输出方便对比。” —— OpenClaw 自动用 concurrent.futures 实现了并发调用。

加文件输出: “给所有命令加 --output 参数,把结果写到 .md 文件。” —— 大概 30 秒就改完了。

Prompt 调优: 发现处理英文内容效果一般,让 OpenClaw 帮我改 system prompt 加了多语言支持。

每轮改动都是:自然语言描述 → OpenClaw 修改代码 → review 后 accept。因为 OpenClaw 本身和项目的 LLM 调用走的同一个 Provider,一个 Key 管理所有模型调用。

六、模型选择体会

实际对比了几个模型:

GPT-4o: Markdown 格式最规范,排版舒服,适合做最终输出。

Gemini 2.5 Flash: 响应速度快,支持超长上下文(1M tokens),适合开发调试和处理大文件摘要,token 费用也比较低。

Gemini 2.5 Pro: 推理能力强,复杂技术内容的结构化梳理表现更好,但响应速度慢一些。

我的策略:调试阶段用 Gemini 2.5 Flash(快且便宜),正式输出用 GPT-4o(格式好),复杂内容用 Gemini 2.5 Pro。同一个接口,切换只需要改参数。

七、踩坑记录

baseUrl 忘加 /v1 导致请求路径拼错,这是最常见的配置问题。

配置不会热更新。 改了 openclaw.json 必须重启 OpenClaw。

超长文件导致超时。 大 Markdown 文件做摘要时要把 timeout 调大,或者先做分段。

模型名要和接口实际名称一致。 比如 Gemini 的 ID 是 gemini-2.5-flash 不是 gemini-flash,以接口的模型列表页为准。

八、小结

整个过程就是:配置自定义 Provider(5 分钟)→ 用 OpenClaw 生成项目代码(10 分钟)→ 测试调优(15 分钟)。核心思路是通过环境变量解耦 API 配置,代码里不硬编码地址,这样不管后端用什么模型服务都不用改业务代码。

项目结构很简单,感兴趣的可以自己照着搭一个:

markdown-note-assistant/
├── note_assistant/
│   ├── __init__.py
│   ├── llm.py          # LLM 调用封装
│   └── commands.py     # CLI 命令
├── setup.py
└── README.md

参考资源:

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐