LLM API使用
环境准备
API KEY
-
选择的是阿里家的API KEY,所以完全按照它的准备工作一步步操作就能得到一个API KEY,从这里(阿里云百炼)进去,需要登录一下,能得到下面这个画面,再按照图中标注的位置进去,就能到生成API KEY的位置,如图2
-
成功获取到API KEY之后回到上文图1中的准备工作-配置API Key到环境变量,在1代机环境中设置API Key
示例验证
代码
test.py:阿里云百炼提供的示例代码,代码中的API Key需要用上文中获取到的API Key
# import dashscope
# # 将你的 API Key 填入此处,或配置到环境变量
# dashscope.api_key = "sk-95d077b5eeed4da09cbbd75e7e07d27d"
# response = dashscope.Generation.call(
# model=dashscope.Generation.Models.qwen_turbo,
# prompt='你好,请介绍一下你自己'
# )
# if response.status_code == 200:
# print(response.output.text)
# else:
# print(f"调用失败: {response.message}")
# # 文本输出
# import os
# import dashscope
# messages = [
# {'role': 'system', 'content': 'You are a helpful assistant.'},
# {'role': 'user', 'content': '你是谁?'}
# ]
# response = dashscope.Generation.call(
# # 若没有配置环境变量,请用百炼API Key将下行替换为:api_key="sk-xxx"
# api_key=os.getenv('DASHSCOPE_API_KEY'),
# model="qwen-plus", # 此处以qwen-plus为例,可按需更换模型名称。模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models
# messages=messages,
# result_format='message'
# )
# print(response)
# # 流式输出
# import os
# import dashscope
# messages = [
# {'role':'system','content':'you are a helpful assistant'},
# {'role': 'user','content': '你是谁?'}
# ]
# responses = dashscope.Generation.call(
# # 若没有配置环境变量,请用百炼API Key将下行替换为:api_key="sk-xxx"
# api_key=os.getenv('DASHSCOPE_API_KEY'),
# model="qwen-plus", # 此处以qwen-plus为例,可按需更换模型名称。模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models
# messages=messages,
# result_format='message',
# stream=True,
# incremental_output=True
# )
# for response in responses:
# print(response)
# # 图像输入
# import os
# import dashscope
# messages = [
# {
# "role": "user",
# "content": [
# {"image": "https://dashscope.oss-cn-beijing.aliyuncs.com/images/dog_and_girl.jpeg"},
# {"image": "https://dashscope.oss-cn-beijing.aliyuncs.com/images/tiger.png"},
# {"image": "https://dashscope.oss-cn-beijing.aliyuncs.com/images/rabbit.png"},
# {"text": "这些是什么?"}
# ]
# }
# ]
# response = dashscope.MultiModalConversation.call(
# # 若没有配置环境变量,请用百炼API Key将下行替换为:api_key="sk-xxx"
# api_key=os.getenv('DASHSCOPE_API_KEY'),
# model='qwen-vl-max', # 此处以qwen-vl-max为例,可按需更换模型名称。模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models
# messages=messages
# )
# print(response)
# # 视频输入
# from http import HTTPStatus
# import os
# # dashscope版本需要不低于1.20.10
# import dashscope
# messages = [{"role": "user",
# "content": [上
# {"video":["https://img.alicdn.com/imgextra/i3/O1CN01K3SgGo1eqmlUgeE9b_!!6000000003923-0-tps-3840-2160.jpg",
# "https://img.alicdn.com/imgextra/i4/O1CN01BjZvwg1Y23CF5qIRB_!!6000000003000-0-tps-3840-2160.jpg",
# "https://img.alicdn.com/imgextra/i4/O1CN01Ib0clU27vTgBdbVLQ_!!6000000007859-0-tps-3840-2160.jpg",
# "https://img.alicdn.com/imgextra/i1/O1CN01aygPLW1s3EXCdSN4X_!!6000000005710-0-tps-3840-2160.jpg"]},
# {"text": "描述这个视频的具体过程"}]}]
# response = dashscope.MultiModalConversation.call(
# # 若没有配置环境变量,请用百炼API Key将下行替换为:api_key="sk-xxx"
# api_key=os.getenv("DASHSCOPE_API_KEY"),
# model='qwen-vl-max-latest', # 此处以qwen-vl-max-latest为例,可按需更换模型名称。模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models
# messages=messages
# )
# if response.status_code == HTTPStatus.OK:
# print(response)
# else:
# print(response.code)
# print(response.message)
# # 音频输入
# import os
# import dashscope
# messages = [
# {
# "role": "user",
# "content": [
# {"audio": "https://dashscope.oss-cn-beijing.aliyuncs.com/audios/welcome.mp3"},
# {"text": "这段音频在说什么?"}
# ]
# }
# ]
# response = dashscope.MultiModalConversation.call(
# # 若没有配置环境变量,请用百炼API Key将下行替换为:api_key="sk-xxx"
# api_key=os.getenv('DASHSCOPE_API_KEY'),
# model='qwen-audio-turbo', # 此处以qwen-audio-turbo为例,可按需更换模型名称。模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models
# messages=messages
# )
# print(response)
# 联网搜索
import os
import dashscope
messages = [
{'role': 'system', 'content': 'You are a helpful assistant.'},
{'role': 'user', 'content': '成都今天天气是什么?'}
]
response = dashscope.Generation.call(
# 若没有配置环境变量,请用百炼API Key将下行替换为:api_key="sk-xxx"
api_key=os.getenv('DASHSCOPE_API_KEY'),
model="qwen-plus", # 此处以qwen-plus为例,可按需更换模型名称。模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models
messages=messages,
enable_search=True,
result_format='message'
)
print(response)
llm_client.py:简单的客户端实现,直接调用API
# llm_client.py
from openai import OpenAI
class LLMClient:
def __init__(self, api_key: str, model: str = "qwen-plus", base_url: str = None):
"""
初始化LLM客户端
:param api_key: 阿里云百炼API Key
:param model: 模型名称,如 qwen-plus, qwen-max
:param base_url: API地址(可选,默认使用北京地域)
"""
self.api_key = api_key
self.model = model
# 默认使用北京地域的兼容模式接口
if base_url is None:
base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1"
self.client = OpenAI(
api_key=api_key,
base_url=base_url
)
def chat(self, user_message: str, system_prompt: str = None) -> str:
"""发送单条消息,返回AI回复"""
messages = []
if system_prompt:
messages.append({"role": "system", "content": system_prompt})
messages.append({"role": "user", "content": user_message})
response = self.client.chat.completions.create(
model=self.model,
messages=messages
)
return response.choices[0].message.content
# 测试代码
if __name__ == "__main__":
import os
api_key = os.environ.get("DASHSCOPE_API_KEY") # 从环境变量读取
if not api_key:
print("请先设置环境变量 DASHSCOPE_API_KEY")
else:
client = LLMClient(api_key=api_key)
response = client.chat("你好,请介绍一下成都名字的来源")
print(response)
openclaw部署
环境
# 确认环境中是否安装node.js,并且版本为 V22 以上
node -v
# 如果没有,执行下述命令安装
# 添加 NodeSource 仓库(以 v22 为例,如果需要v24,将 setup_22.x 改为 setup_24.x)
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
# 安装 Node.js 和 npm
sudo apt install -y nodejs
# 验证版本,应 ≥ v22.0.0
node -v
npm -v
安装openclaw
# 安装的指定版本 openclaw_v2026.3.13,如果遇到安装不了的问题,看下面的“遇到的问题-1”
npm install -g openclaw@2026.3.13
# 查看openclaw的已安装版本
openclaw --version
初始化openclaw配置
# 初始化配置(交互式)
openclaw onboard
剩下的配置,除了标记的2个,其他的可以先跳过
遇到的问题
1. 安装openclaw时提示“Error: EACCES: permission denied, mkdir ‘/usr/lib/node_modules/openclaw’”,没有权限安装全局包
解决:
# 1. 创建用户级全局目录
mkdir -p ~/.npm-global
# 2. 配置 npm 使用这个目录
npm config set prefix '~/.npm-global'
# 3. 将这个目录添加到 PATH(临时生效)
export PATH=~/.npm-global/bin:$PATH
# 4. 永久添加到 PATH(写入配置文件)
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
# 5. 现在重新安装,不需要 sudo
npm install -g openclaw@2026.3.13
2.初始化配置之后执行 `openclaw gateway` 命令,Windows不能访问http:://{ip/localhost/127.0.0.1}:18789
解决:
方法1(临时):使用 SSH 端口转发,如下图所示。此时再访问,可以访问 http:://{localhost/127.0.0.1}:18789,但还不能访问ip
方法2(推荐):修改openclaw.json
# 1. 将监听地址改为“局域网”模式,
openclaw config set gateway.bind lan
# 2. 允许外部访问(解除安全限制)
openclaw config set gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback true
openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth true
# 3. 设置允许访问的ip(可选,设置后的json如下图)
openclaw config set gateway.controlUi.allowedOrigins '["http://localhost:18789", "http://127.0.0.1:18789", "http://192.168.110.165:18789"]'
# 4. 重新加载配置
openclaw gateway restart
# 5. 启动
openclaw gateway
3.token太长记不住,可以修改的
解决:如下图所示,初始化配置时终端输出的token保存在配置文件openclaw.json中,改一个方便自己记的
openclaw+自定义API后端
调用流程,如图:
自定义API示例
# 安装 fastapi uvicorn库
pip install fastapi uvicorn
| CRUD API 示例代码 |
|---|
from typing import List, Optional
from pydantic import BaseModel
from fastapi import FastAPI, HTTPException
import uvicorn
app = FastAPI(title="CRUD Api for openclaw")
todos = []
nextId = 1
class TodoCreate(BaseModel):
title: str
description: Optional[str] = ""
class TodoUpdate(BaseModel):
title: Optional[str] = None
description: Optional[str] = None
completed: Optional[bool] = None
class TodoResponse(BaseModel):
id: int
title: str
description: str
completed: bool
# 新增
@app.post("/api/todos", response_model=TodoResponse)
def createTodo(todo: TodoCreate):
print(f"📝 [CRUD] createTodo called with title: {todo.title}")
global nextId
newTodo = {
"id": nextId,
"title": todo.title,
"description": todo.description,
"completed": False
}
todos.append(newTodo)
nextId += 1
return newTodo
# 查询列表
@app.get("/api/todos", response_model=List[TodoResponse])
def listTodos(completed: Optional[bool] = None):
if completed is None:
return todos
return [ t for t in todos if t["completed"] == completed]
# 查询某个
@app.get("/api/todos/{todoId}", response_model=TodoResponse)
def getTodo(todoId: int):
for todo in todos:
if todo["id"] == todoId:
return todo
raise HTTPException(status_code = 404, detail="Todo not found")
# 更新
@app.put("/api/todos/{todoId}", response_model=TodoResponse)
def updateTodo(todoId: int, update:TodoUpdate):
for todo in todos:
if todo["id"] == todoId:
if update.title is not None:
todo["title"] = update.title
if update.description is not None:
todo["description"] = update.description
if update.completed is not None:
todo["completed"] = update.completed
return todo
raise HTTPException(status_code=404, detail="Todo not found")
# 删除
@app.delete("/api/todos/{todoId}")
def deleteTodo(todoId: int):
global todos
for i, todo in enumerate(todos):
if todo["id"] == todoId:
todos.pop(i)
return {"message": "Todo deleted"}
raise HTTPException(status_code=404, detail="Todo not found")
# 查看api服务状态
@app.get("/ping")
def ping():
return {"status": "ok", "todoCount": len(todos)}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8888)
详可参考FastAPI教程
在openclaw配置skills
在 ~/.openclaw/workspace/skills/ 目录下创建 todo_crud 文件夹
# 创建自定义skills的目录
mkdir -p ~/.openclaw/workspace/skills/todo_crud
创建 SKILL.md 文件
!!!!注意:
文件名必须为 SKILL.md |
大小写敏感,不能是 skill.md 或其它 |
|---|---|
| 必须放在正确的目录下 | ~/.openclaw/workspace/skills/<技能名>/SKILL.md |
| undefined | ---- |
| 必须有 YAML frontmatter | 文件开头必须用 --- 包裹的元数据块 |
| undefined | ---- |
name 字段必填 |
唯一标识符,使用 snake_case(如 todo_crud) |
| undefined | ---- |
description 字段必填 |
一行描述,告诉 AI 这个 Skill 的用途和何时触发 |
| undefined | ---- |
技能 todo_crud 示例代码:
---
name: todo_crud
description: 管理待办事项的完整 CRUD 操作,包括创建、查看、更新、删除待办事项
---
# 待办事项管理 Skill
当用户想要管理待办事项时,使用本 Skill 调用本地 Todo API 服务。
## 可用操作
### 1. 创建待办事项
当用户说"创建待办"、"添加任务"、"记个事"或类似意图时:
- 使用 `bash` 工具执行 curl 命令调用 POST /api/todos
- 提取用户提供的标题(title)和可选描述(description)
命令模板:
```bash
curl -s http://localhost:8888/ping
```bash
curl -X POST http://localhost:8888/api/todos \
-H "Content-Type: application/json" \
-d '{"title": "<用户给的标题>", "description": "<用户给的描述>"}'
```bash
curl -s http://localhost:8888/api/todos
```bash
curl -s http://localhost:8888/api/todos/<todoId>
```bash
curl -X PUT http://localhost:8888/api/todos/<todoId> \
-H "Content-Type: application/json" \
-d '{"completed": true}'
```bash
curl -X DELETE http://localhost:8888/api/todos/<todoId>









