Skip to content

protocols - 多协议适配层

字数
897 字
阅读时间
5 分钟

概述

nbot/core/protocols/ 提供统一的多协议适配层,将不同 AI 模型 API 的请求/响应格式抽象为统一接口。选择模型的 provider_type 后,系统自动使用对应的接口地址、请求头、请求格式和响应解析器。

支持的协议

协议文件接口端点适用场景
OpenAI Chat Completionsopenai_chat.pyv1/chat/completionsOpenAI、DeepSeek、硅基流动等兼容服务
OpenAI Responsesopenai_responses.pyv1/responsesOpenAI 新一代 API,支持 agent 和内置工具
Anthropic Messagesanthropic_messages.py/v1/messagesClaude 原生 API
Gemini Nativegemini_native.pymodels/{model}:generateContentGemini 原生 API,支持多模态、thinking、结构化输出

核心接口

ModelProtocol

所有协议实现的抽象基类:

python
class ModelProtocol(ABC):
    name: str                    # 协议标识
    display_name: str            # 人类可读名称
    url_suffix: str              # 自动补全的 URL 后缀

    def resolve_url(base_url, model, *, append_base_url_path) -> str
    def build_headers(api_key, *, stream) -> dict
    def build_payload(model, messages, *, tools, stream, ...) -> dict
    def parse_response(data, *, model, ...) -> NormalizedModelResponse
    def parse_stream_chunk(chunk_data) -> Optional[dict]
    def supports_tools() -> bool

get_protocol()

根据 provider_type 获取对应协议实例:

python
from nbot.core.protocols import get_protocol

protocol = get_protocol("anthropic")          # -> AnthropicMessagesProtocol
protocol = get_protocol("openai_compatible")  # -> OpenAIChatProtocol
protocol = get_protocol("openai_responses")   # -> OpenAIResponsesProtocol

list_protocols()

返回所有已注册协议的元数据(供 UI 下拉框使用):

python
from nbot.core.protocols import list_protocols

protocols = list_protocols()
# [
#   {"key": "openai_compatible", "name": "OpenAI Chat Completions", "url_suffix": "/chat/completions", ...},
#   {"key": "openai_responses", "name": "OpenAI Responses API", "url_suffix": "/responses", ...},
#   {"key": "anthropic", "name": "Anthropic Messages", "url_suffix": "/v1/messages", ...},
# ]

provider_type 映射

provider_type 值协议实现
openai_compatible / openai / custom / deepseek / siliconflowOpenAI Chat Completions
openai_responsesOpenAI Responses
anthropic / claudeAnthropic Messages
gemini / google / gemini_nativeGemini Native (generateContent)

未知类型默认回退到 OpenAI Chat Completions。

三种协议对比

请求格式

OpenAI Chat Completions -- 用 messages[] 表示对话:

json
{
  "model": "gpt-4",
  "messages": [{"role": "user", "content": "你好"}],
  "stream": false
}

OpenAI Responses -- 用 input 表示输入:

json
{
  "model": "gpt-4",
  "input": [{"type": "message", "role": "user", "content": [{"type": "input_text", "text": "你好"}]}],
  "max_output_tokens": 4096
}

Anthropic Messages -- system 在顶层,max_tokens 必传:

json
{
  "model": "claude-3-opus",
  "system": "你是助手",
  "messages": [{"role": "user", "content": "你好"}],
  "max_tokens": 4096
}

响应文本提取

协议文本路径
OpenAI Chatchoices[0].message.content
OpenAI Responsesoutput[].content[].type=="output_text"
Anthropiccontent[].type=="text"
Gemini Nativecandidates[0].content.parts[0].text

工具调用格式

协议工具定义工具调用工具结果
OpenAI Chattools[].type="function"tool_calls[].function.namerole: "tool"
OpenAI Responsestools[].type="function"output[].type="function_call"type: "function_call_output"
Anthropictools[].name,input_schemacontent[].type="tool_use"type: "tool_result"
Gemini Nativetools[].functionDeclarations[]parts[].functionCallparts[].functionResponse (role: "user")

流式事件

协议文本增量
OpenAI Chatchoices[0].delta.content
OpenAI Responsesevent.type == "response.output_text.delta"
Anthropiccontent_block_delta.delta.text
Gemini Nativecandidates[0].content.parts[0].text

使用方式

直接使用协议

python
from nbot.core.protocols import get_protocol
from nbot.core.model_adapter import response_json_utf8
import requests

protocol = get_protocol("anthropic")
url = protocol.resolve_url("https://api.anthropic.com", model="claude-3-opus")
headers = protocol.build_headers(api_key)
payload = protocol.build_payload("claude-3-opus", messages, stream=False)

resp = requests.post(url, json=payload, headers=headers, timeout=120)
normalized = protocol.parse_response(response_json_utf8(resp), model="claude-3-opus")
print(normalized.content)

通过 AIClient 使用

python
from nbot.services.ai import ai_client

# 自动根据 provider_type 选择协议
response = ai_client.chat_completion(messages, stream=False)

通过 Pipeline 使用

python
from nbot.core.ai_pipeline import AIPipeline, PipelineContext

pipeline = AIPipeline()
result = pipeline.process(ctx, callbacks, tools=tools)
# Pipeline 内部自动根据模型配置选择协议

Web UI 集成

模型配置页面的 Provider 类型下拉框从 /api/ai-models/protocols 接口动态获取已注册协议。选择协议后:

  • 自动显示对应的 URL 后缀(如 /chat/completions/v1/messages/responses
  • 开启「自动补全 Base URL 后缀」时,自动拼接协议路径
  • 关闭时,Base URL 作为完整地址使用,但请求仍使用选中协议的格式

扩展新协议

实现 ModelProtocol 并注册:

python
from nbot.core.protocols.base import ModelProtocol, register_protocol

class MyCustomProtocol(ModelProtocol):
    @property
    def name(self) -> str:
        return "my_custom"

    @property
    def display_name(self) -> str:
        return "My Custom API"

    @property
    def url_suffix(self) -> str:
        return "/v1/custom"

    # ... 实现其他抽象方法

register_protocol("my_custom", MyCustomProtocol)

然后在 base.py_PROVIDER_ALIASES 中添加映射即可。

页面历史