获取 API Key 获取 API
文档

Claude 消息接口

- 完全兼容 Anthropic Claude Messages 原生协议(`POST /v1/messages`)

  • 支持多轮对话、流式 SSE、工具调用、extended thinking
  • 支持文本、图像等多模态内容
  • 响应为上游原样透传,无 {code, data} 外层包装
警告

两套 API 不要混用:/v1/* 为推理 API(本文档,上游原样透传、无包装);/api/* 为管理 API(查余额/日志等,响应为 {success, message, data})。若看到某处写 /v1/messages 返回 {code, data},以本文档为准。

请求示例

curl https://api.openveer.com/v1/messages \
  -H "x-api-key: $API_KEY" \
  -H "anthropic-version: 2025-10-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-sonnet-4-6",
    "max_tokens": 1024,
    "messages": [
      {"role": "user", "content": "你好,世界"}
    ]
  }'

响应示例

{
  "model": "claude-sonnet-4-6",
  "id": "msg_011CdfeHuC728oxqaLrRNbcB",
  "type": "message",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "你好!我是Claude。很高兴见到你。"
    }
  ],
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "stop_details": null,
  "usage": {
    "input_tokens": 12,
    "cache_creation_input_tokens": 0,
    "cache_read_input_tokens": 0,
    "cache_creation": {
      "ephemeral_5m_input_tokens": 0,
      "ephemeral_1h_input_tokens": 0
    },
    "output_tokens": 18,
    "service_tier": "standard",
    "inference_geo": "global"
  }
}

Authorizations

鉴权支持两种方式,任选其一:

x-api-key string

Anthropic 风格鉴权头

访问 API Key 管理页面 获取您的 API Key

x-api-key: YOUR_API_KEY
Authorization string

Bearer Token 鉴权(与 x-api-key 二选一)

Authorization: Bearer YOUR_API_KEY
anthropic-version string

API 版本号(可选,不传也能正常返回)

为便于日后迁移到 Anthropic 官方端点,建议照常带上:

示例:2025-10-01

Body

model string

模型名称

  • claude-opus-4-8 - Claude Opus 4.8 旗舰模型
  • claude-opus-4-7 - Claude Opus 4.7 旗舰模型
  • claude-opus-4-6 - Claude Opus 4.6 旗舰模型
  • claude-sonnet-4-6 - Claude Sonnet 4.6 平衡版本
  • claude-opus-4-5-20251101 - Claude Opus 4.5 模型
messages array
消息列表 消息数组,模型会基于这些消息生成下一条回复。每条消息包含 role 和 content 两个字段。 **💡 快速填写(Try it 区域):** 1. 点击 "+ Add an item" 添加一条消息 2. role 输入:user(用户消息)或 assistant(AI回复,用于多轮对话) 3. content 输入:你想说的话
role string

角色类型

  可选值:user(用户消息)、assistant(AI回复,用于多轮对话和预填充)

  注:Claude API 的 system 提示词使用单独的 system 参数,不在 messages 中
content string

消息内容

  填写消息的文本内容
**单条用户消息示例:**
[{"role": "user", "content": "你好,Claude"}]
**多轮对话示例:**
[
  {"role": "user", "content": "你好"},
  {"role": "assistant", "content": "你好!我是Claude。"},
  {"role": "user", "content": "能解释一下AI吗?"}
]
**预填充助手回复:**
[
  {"role": "user", "content": "太阳的希腊名称是?(A) Sol (B) Helios (C) Sun"},
  {"role": "assistant", "content": "答案是 ("}
]
max_tokens integer

最大生成 token 数(必填,与 Anthropic 官方一致)

生成停止前的最大 token 数量。模型可能会在达到此限制前停止。

不同模型有不同的最大值,请参考模型文档。最小值:1

thinking object

Extended thinking 配置

开启后响应 content 中可能包含 thinking 块。推荐使用标准模型名 + 本参数,而不是依赖平台侧的 -thinking 模型别名,便于无改代码迁移到官方端点。

多轮对话若需回传 thinking 块,必须原样带回 signature,否则上游会拒绝。

system string | array

系统提示词

系统提示词用于设置Claude的角色、个性、目标和指令。

字符串格式:

{
  "system": "你是一位专业的Python编程导师"
}

结构化格式:

{
  "system": [
    {
      "type": "text",
      "text": "你是一位专业的Python编程导师"
    }
  ]
}
temperature number

温度参数,范围 0-1

控制输出的随机性:

  • 低值(如0.2):更确定、更保守
  • 高值(如0.8):更随机、更有创意

默认值:1.0

top_p number

核采样参数,范围 0-1

使用nucleus sampling。建议使用 temperature 或 top_p 其中之一,不要同时使用。

默认值:1.0

top_k integer

Top-K采样

只从概率最高的K个选项中采样,用于移除"长尾"低概率响应。

建议仅在高级用例中使用。

stream boolean

是否启用流式输出

设置为 true 时,使用服务器发送事件(SSE)流式返回响应。

默认值:false

stop_sequences array

停止序列

自定义文本序列,遇到这些序列时模型将停止生成。

最多4个序列。

示例:["\n\nHuman:", "\n\nAssistant:"]

metadata object

元数据

用于请求的元数据对象。

包含:

  • user_id: 用户标识符
tools array

工具定义

工具列表,模型可以调用这些工具来完成任务。

函数工具示例:

{
  "tools": [
    {
      "name": "get_weather",
      "description": "获取指定位置的当前天气",
      "input_schema": {
        "type": "object",
        "properties": {
          "location": {
            "type": "string",
            "description": "城市和省份,例如:北京"
          },
          "unit": {
            "type": "string",
            "enum": ["celsius", "fahrenheit"],
            "description": "温度单位"
          }
        },
        "required": ["location"]
      }
    }
  ]
}

支持的工具类型:

  • 自定义函数工具
  • 计算机使用工具(computer_20241022)
  • 文本编辑器工具(text_editor_20241022)
  • Bash工具(bash_20241022)
tool_choice object

工具选择策略

控制模型如何使用工具:

  • {"type": "auto"}: 自动决定(默认)
  • {"type": "any"}: 必须使用工具
  • {"type": "tool", "name": "tool_name"}: 使用指定工具

Response

id string

唯一消息标识符

示例:"msg_013Zva2CMHLNnXjNJJKqJ2EF"

type string

对象类型

固定为 "message"

role string

角色

固定为 "assistant"

content array

内容块数组

content 按 type 区分块类型。一次响应可能包含多个块(例如开启 thinking 时是 thinking + text 两块)。

text 块:

{ "type": "text", "text": "OK" }

tool_use 块:

{
  "type": "tool_use",
  "id": "toolu_01QgsazxKXSfQVj9Q1XxjYXo",
  "name": "get_weather",
  "input": { "city": "Beijing" },
  "caller": { "type": "direct" }
}

注意



caller 是上游新增字段,官方文档尚未收录,解析时忽略即可。

thinking 块(请求体带 thinking 参数时出现):

{
  "type": "thinking",
  "thinking": "推理过程文本...",
  "signature": "<约 500+ 字符的签名串>"
}

警告



多轮对话回传 thinking 块时,必须原样带回 signature,否则上游会拒绝。

警告



不要假设 content[0] 就是文本。 开启 thinking 时 content[0] 可能是 thinking 块。应遍历筛选:

text = "".join(b.text for b in resp.content if b.type == "text")

model string

处理请求的模型

示例:"claude-sonnet-4-6"

stop_reason string

停止原因

可能的值:

  • end_turn: 自然结束
  • max_tokens: 达到最大 token 数
  • stop_sequence: 遇到停止序列
  • tool_use: 调用了工具
stop_sequence string | null

触发的停止序列

如果因停止序列而停止,则为该序列内容;否则为 null

stop_details object | null

Anthropic 较新字段,常规请求为 null

usage object
Token 使用统计(非流式完整结构)
input_tokens integer

输入 token 数

output_tokens integer

输出 token 数(已包含 thinking tokens,计费勿重复累加)

cache_creation_input_tokens integer

缓存写入 token

cache_read_input_tokens integer

缓存命中 token

cache_creation object

{ ephemeral_5m_input_tokens, ephemeral_1h_input_tokens }

service_tier string

如 "standard"

inference_geo string

如 "global"

output_tokens_details object

开启 thinking 时可能出现:{ thinking_tokens: int }

使用示例

基础对话

import anthropic

client = anthropic.Anthropic(
    api_key="YOUR_API_KEY",
    base_url="https://api.openveer.com"
)

message = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=[
        {"role": "user", "content": "解释量子计算的基本原理"}
    ]
)

print(message.content[0].text)

多轮对话

messages = [
    {"role": "user", "content": "什么是机器学习?"},
    {"role": "assistant", "content": "机器学习是人工智能的一个分支..."},
    {"role": "user", "content": "能举个实际应用的例子吗?"}
]

message = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=messages
)

使用系统提示词

message = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    system="你是一位资深的Python开发专家,擅长代码审查和优化建议。",
    messages=[
        {"role": "user", "content": "如何优化这段代码?\n\n[代码]"}
    ]
)

流式响应

with client.messages.stream(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=[
        {"role": "user", "content": "写一篇关于AI的短文"}
    ]
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)

工具使用

tools = [
    {
        "name": "get_stock_price",
        "description": "获取股票的实时价格",
        "input_schema": {
            "type": "object",
            "properties": {
                "ticker": {
                    "type": "string",
                    "description": "股票代码,例如:AAPL"
                }
            },
            "required": ["ticker"]
        }
    }
]

message = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    tools=tools,
    messages=[
        {"role": "user", "content": "特斯拉的股价是多少?"}
    ]
)

# 处理工具调用
if message.stop_reason == "tool_use":
    tool_use = next(block for block in message.content if block.type == "tool_use")
    print(f"调用工具: {tool_use.name}")
    print(f"参数: {tool_use.input}")

视觉理解

message = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image",
                    "source": {
                        "type": "url",
                        "url": "https://example.com/image.jpg"
                    }
                },
                {
                    "type": "text",
                    "text": "描述这张图片"
                }
            ]
        }
    ]
)

Base64图像

import base64

with open("image.jpg", "rb") as image_file:
    image_data = base64.b64encode(image_file.read()).decode("utf-8")

message = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image",
                    "source": {
                        "type": "base64",
                        "media_type": "image/jpeg",
                        "data": image_data
                    }
                },
                {
                    "type": "text",
                    "text": "分析这张图片"
                }
            ]
        }
    ]
)

最佳实践

1. 提示词工程

清晰的角色定义:

system = """你是一位经验丰富的数据科学家,专长包括:
- 统计分析和数据可视化
- 机器学习模型开发
- Python和R编程
请提供专业、准确的建议。"""

结构化输出:

message = "请以JSON格式返回分析结果,包含summary、key_findings和recommendations字段。"

2. 错误处理

from anthropic import APIError, RateLimitError

try:
    message = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=1024,
        messages=[{"role": "user", "content": "你好"}]
    )
except RateLimitError:
    print("速率限制,请稍后重试")
except APIError as e:
    print(f"API错误: {e}")

3. Token优化

# 使用更短的提示词
messages = [
    {"role": "user", "content": "总结要点:\n\n[长文本]"}
]

# 限制输出长度
message = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=500,  # 限制输出
    messages=messages
)

4. 预填充响应

# 引导模型以特定格式回复
messages = [
    {"role": "user", "content": "列出5个Python最佳实践"},
    {"role": "assistant", "content": "以下是5个Python最佳实践:\n\n1."}
]

message = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=messages
)

流式响应处理

Python流式示例

import anthropic

client = anthropic.Anthropic(
    api_key="YOUR_API_KEY",
    base_url="https://api.openveer.com"
)

with client.messages.stream(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=[
        {"role": "user", "content": "写一个Python装饰器示例"}
    ]
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)

JavaScript流式示例

import Anthropic from '@anthropic-ai/sdk';

const client = new Anthropic({
  apiKey: process.env.API_KEY,
  baseURL: 'https://api.openveer.com'
});

const stream = await client.messages.stream({
  model: 'claude-sonnet-4-6',
  max_tokens: 1024,
  messages: [
    { role: 'user', content: '写一个React组件示例' }
  ]
});

for await (const chunk of stream) {
  if (chunk.type === 'content_block_delta' && 
      chunk.delta.type === 'text_delta') {
    process.stdout.write(chunk.delta.text);
  }
}

平台差异与对接注意

响应无包装

POST /v1/messages 成功时直接返回 Anthropic message 对象,没有 {code, data} 外层。官方 SDK、Claude Code、Cline 等才能 1:1 兼容。

错误格式(与官方唯一实质差异)

{
  "error": {
    "code": "model_not_found",
    "message": "... (request id: ...)",
    "param": "",
    "type": "openveer_error"
  }
}

相对 Anthropic 官方:顶层缺少 "type": "error";error.type 固定为 openveer_error,而非 invalid_request_error 等语义化类型。

对接建议:不要依赖 error.type 做重试分支,改用 HTTP 状态码 + error.code:

状态码 含义 建议动作
400 请求参数错误 不重试,检查请求体
401 Key 无效 不重试
402 余额不足 不重试,提示充值
429 限流 退避后重试
5xx 上游/网关异常 指数退避重试

报障请提供:error.message 末尾的 request id,以及响应头 x-oneapi-request-id。

流式 SSE

请求加 "stream": true。事件序列与官方一致:

message_start → content_block_start → ping → content_block_delta(多次)→ content_block_stop → message_delta → message_stop

⚠️ 流式与非流式的 usage 结构不同:message_delta.usage 通常只有 4 个 token 字段,没有 cache_creation、service_tier、inference_geo。请分开解析或全部设为可选。

未实现接口

POST /v1/messages/count_tokens 未实现,返回 404。官方 SDK 的 client.messages.count_tokens() 会失败。需要预估 token 时请在本地估算,或读取响应中的 usage.input_tokens。

必须忽略未知字段

本接口对上游透传,Anthropic 可能随时新增字段(如 stop_details、inference_geo、caller、output_tokens_details)。请勿开启严格 schema:

  • Go:不要用 DisallowUnknownFields()
  • Pydantic:不要 extra="forbid"
  • TypeScript / Zod:用 .passthrough() 而非 .strict()

模型名建议

带 -thinking 后缀的同名模型是平台扩展别名。推荐用不带后缀的标准模型名 + 请求体 thinking 参数,便于迁移官方端点。

请求体其它字段与官方一致:model、messages、max_tokens(必填)、system、temperature、top_p、top_k、stop_sequences、stream、tools、tool_choice、thinking、metadata。语义以 Anthropic Messages API 为准。

注意事项

  1. API 密钥安全:
    * 使用环境变量存储 API 密钥
    * 不要在代码中硬编码密钥
    * 定期轮换密钥

  2. 速率限制:
    * 注意 API 的速率限制
    * 实现重试机制(按 HTTP 状态码)
    * 使用指数退避策略

  3. Token 管理:
    * 监控 token 使用量(读 usage)
    * 优化提示词长度
    * 使用适当的 max_tokens 值
    * 开启 thinking 时 output_tokens 已含 thinking,勿重复计费

  4. 模型选择:
    * Opus: 复杂任务、需要深度思考
    * Sonnet: 平衡性能和成本
    * Haiku: 快速响应、简单任务

  5. 内容解析:
    * 遍历 content 取 type == "text",不要写死 content[0].text
    * 模型若返回 Markdown 代码块包裹的 JSON,属模型输出而非接口包装(见下方 FAQ)

  6. 内容过滤:
    * 验证用户输入
    * 过滤敏感信息
    * 实现内容审核机制

FAQ

响应里 content 的 text 是 ```json ... ``` 代码块,怎么去掉?

这不是接口结构问题。text 字段装的是模型生成的原始内容:模型判断你想要 JSON,就用 Markdown 代码块包起来了。接口不会也不应该改写模型输出。

想拿到干净的结构化数据,有三种正确做法(推荐程度从高到低):

  1. 用 tools 强制结构化输出——最可靠,input 字段直接就是解析好的对象:
{
  "tools": [{
    "name": "emit_result",
    "input_schema": {
      "type": "object",
      "properties": { "answer": { "type": "string" } }
    }
  }],
  "tool_choice": { "type": "tool", "name": "emit_result" }
}
  1. prefill 助手消息,让模型从 { 接着写:
{
  "messages": [
    { "role": "user", "content": "..." },
    { "role": "assistant", "content": "{" }
  ]
}
  1. 在 system prompt 里明确要求「只输出 JSON,不要加 Markdown 代码块」。

不推荐用正则去剥 code fence——模型偶尔不加围栏时会解析失败。