跳到主要内容

模型上下文协议规范(2025-03-26)—— 授权

· 阅读需 12 分钟

翻译自:https://spec.modelcontextprotocol.io/specification/2025-03-26/basic/authorization/

ℹ️ 协议修订:2025-03-26

1. 引言

1.1 目的和范围

模型上下文协议(MCP)在传输层提供了授权能力,允许MCP客户端代表资源所有者向受限的MCP服务器发出请求。本规范定义了基于HTTP传输的授权流程。

1.2 协议要求

MCP实施的授权是可选的。当得到支持时:

  • 使用基于HTTP的传输实现应该遵守本规范。
  • 使用STDIO传输的实现不应该遵循这个规范,而是应该从环境中获取凭据。
  • 使用替代传输实现必须遵循其协议的既定安全最佳实践。

1.3 标准合规性

这种授权机制基于下列已建立的规范,但实现了其特性中的选定子集,以确保在保持简单性的同时,保证安全性和互操作性:

2. 授权流程

2.1 概述

  1. MCP授权实现必须为机密客户端和公开客户端实施OAuth 2.1,并采取适当的安全措施。
  2. MCP鉴权实现应该支持OAuth 2.0动态客户端注册协议(RFC7591)。
  3. MCP服务器应该而MCP客户端必须实现OAuth 2.0授权服务器元数据(RFC8414)。不支持授权服务器元数据的服务器必须遵循默认的URI架构。

2.2 基础的 OAuth 2.1 授权

当授权是必需的而客户端尚未提供证明时,服务器必须HTTP 401 Unauthorized响应。

客户端在收到HTTP 401 未授权后启动OAuth 2.1 IETF 草案的授权流程。

以下展示了使用PKCE的公共客户端的基本OAuth 2.1流程。

OAuth 2.1 流程

2.3 服务器元数据发现

服务器能力发现:

  • MCP 客户端必须遵循在 RFC8414 中定义的 OAuth 2.0 授权服务器元数据协议。
  • MCP服务器应当遵循OAuth 2.0授权服务器元数据协议。
  • 不支持 OAuth 2.0 授权服务器元数据协议的MCP服务器,必须支持后备URL。

发现流程如下图所示:

服务器元数据发现流程

2.3.1 服务器元数据发现头部

在服务器元数据发现过程中,MCP 客户端应该包含头部 MCP-Protocol-Version: <protocol-version>,以便MCP服务器可以根据MCP协议版本进行响应。

例如:MCP-Protocol-Version: 2024-11-05

2.3.2 授权基础网址

授权基础URL 必须 通过舍弃任何现有的 path 组件从MCP服务器URL确定。例如:

如果MCP服务器的URL是https://api.example.com/v1/mcp,那么:

  • 授权基础 URL 是 https://api.example.com
  • 元数据端点 必须 位于 https://api.example.com/.well-known/oauth-authorization-server

这确保了授权端点始终位于托管MCP服务器的域的根级别,无论MCP服务器URL中的路径组件如何。

2.3.3 没有元数据发现功能的服务器的备选方案

对于不实现OAuth 2.0授权服务器元数据的服务器,客户端必须使用以下默认的端点路径,相对于授权基础URL(如第2.3.2节中定义):

端点默认路径描述
授权端点/authorize用于授权请求
令牌端点/token用于令牌交换和刷新
注册端点/register用于动态客户端注册

例如,如果一个MCP服务器托管在https://api.example.com/v1/mcp,那么默认的端点将会是:

客户端必须首先尝试通过元数据文档来发现端点,再回退到默认路径。当使用默认路径时,所有其他协议要求保持不变。

2.3 动态客户端注册

MCP 客户端和服务器应该支持 OAuth 2.0 动态客户端注册协议,以便 MCP 客户端可以在没有用户交互的情况下获取 OAuth 客户端 ID。这为客户端自动向新服务器注册提供了一种标准化的方式,这对于 MCP 来说至关重要,因为:

  • 客户端无法提前知晓所有可能的服务器。
  • 手动注册会给用户带来不便。
  • 它实现了与新服务器的无缝连接
  • 服务器可以实现自己的注册策略

任何不支持动态客户端注册的MCP服务器需要提供其他方法来获取客户端ID(如果适用,还有客户端密钥)。对于这些服务器之一,MCP客户端将必须选择以下方式之一:

  1. 硬编码一个客户端ID(如果适用,还包括客户端密钥)专门用于那个MCP服务器,或者
  2. 向用户展示一个用户界面,让他们在注册了OAuth客户端后输入这些详细信息(例如,通过服务器托管的配置界面)。

2.4 授权流程步骤

完整的授权流程如下进行:

授权流程步骤

2.4.1 决策流概述

决策流概述

2.5 访问令牌的使用

2.5.1 令牌要求

访问令牌处理必须符合OAuth 2.1 第5节对资源请求的要求。具体来说:

  1. MCP 客户端必须使用授权请求头字段 第5.1.1节
Authorization: Bearer <access-token>

请注意,在客户端向服务器发送的每个HTTP请求中都必须包含授权信息,即使它们是同一个逻辑会话的一部分。

  1. 访问令牌必须不能包含在URI查询字符串中。

示例请求:

GET /v1/contexts HTTP/1.1
Host: mcp.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

2.5.2 令牌处理

资源服务器必须按照第5.2节所描述的方式验证访问令牌。如果验证失败,服务器必须根据第5.3节的错误处理要求做出响应。无效或过期的令牌必须收到HTTP 401响应。

2.6 安全考虑

以下安全要求必须被实施:

  1. 客户端必须根据OAuth 2.0的最佳实践安全地存储令牌。
  2. 服务器应该执行令牌的过期和轮换。
  3. 所有授权终端点必须通过HTTPS服务。
  4. 服务器必须验证重定向URI以防止公开重定向漏洞
  5. 重定向URI 必须 是localhost URLs或HTTPS URLs。

2.7 错误处理

服务器必须为授权错误返回适当的HTTP状态码。

状态码描述使用场景
401未授权需要授权或令牌无效
403禁止访问权限范围无效或权限不足
400错误的请求授权请求格式错误

2.8 实施要求

  1. 实现必须遵循OAuth 2.1安全最佳实践
  2. PKCE对所有客户端来说都是必需
  3. 为了增强安全性,应该实施令牌轮换
  4. 令牌的有效期应该根据安全需求来限定。

2.9 第三方授权流程

2.9.1 概述

MCP服务器可以通过第三方授权服务器支持委派授权。在这个流程中,MCP服务器既是OAuth客户端(对第三方授权服务器而言)也是OAuth授权服务器(对MCP客户端而言)。

2.9.2 流程描述

第三方授权流程包括以下步骤:

  1. MCP客户端与MCP服务器启动标准的OAuth流程
  2. MCP服务器将用户重定向到第三方授权服务器。
  3. 用户授权第三方服务器
  4. 第三方服务器带着授权码重定向回MCP服务器。
  5. MCP服务器交换代码以获取第三方访问令牌
  6. MCP 服务器生成了绑定到第三方会话的自有访问令牌。
  7. MCP服务器完成与MCP客户端的原始OAuth流程

第三方授权流程

2.9.3 会话绑定要求

MCP服务器实现第三方授权必须

  1. 维持第三方令牌与发行的MCP令牌之间的安全映射。
  2. 在承认MCP令牌之前验证第三方令牌的状态
  3. 实施适当的令牌生命周期管理
  4. 处理第三方令牌过期和更新

2.9.4 安全性考虑

在实现第三方授权时,服务器必须

  1. 验证所有重定向URI
  2. 安全地存储第三方凭据
  3. 实现适当的会话超时处理
  4. 考虑令牌链接的安全隐患
  5. 实现对第三方授权失败的适当错误处理

3. 最佳实践

3.1 本地客户端作为公共OAuth 2.1 客户端

我们强烈推荐本地客户端作为公共客户端实施OAuth 2.1:

  1. 利用代码挑战(PKCE)进行授权请求以防止拦截攻击
  2. 为本地系统实现适当的安全令牌存储
  3. 遵循令牌刷新的最佳实践以维持会话
  4. 正确处理令牌过期和续订

3.2 授权元数据发现

我们强烈建议所有客户端实施元数据发现。这减少了用户手动提供端点的需求,或者客户端回退到定义的默认值。

3.3 动态客户端注册

由于客户端事先不知道MCP服务器的集合,我们强烈推荐实施动态客户端注册。这允许应用程序自动注册到MCP服务器,并且消除了用户手动获取客户端ID的需求。

模型上下文协议规范(2025-03-26)—— 关键变化

· 阅读需 2 分钟

翻译自:https://spec.modelcontextprotocol.io/specification/2025-03-26/changelog/

此文件列出了自上一修订版2024-11-05以来,模型上下文协议(MCP)规范所做的更改。

重大变化

  1. 添加了一个基于OAuth 2.1的全面**授权框架**(PR #133
  2. 替换了先前的HTTP+SSE传输,采用了更灵活的**可流式HTTP传输**(PR #206)。
  3. 增加了对JSON-RPC **批处理**的支持(PR #228
  4. 为了更好地描述工具行为,例如它是只读的还是具有破坏性的,我们增加了全面的工具注释(PR #185)。

其他架构更改

  • ProgressNotification中添加了message字段,以提供描述性的状态更新。
  • 增加了对音频数据的支持,与现有的文本和图像内容类型一起使用。
  • 添加了completions功能,用于明确指示对参数自动完成建议的支持。

查看更新后的Schema以获取更多细节。

完整的更新日志

要查看自上次协议修订以来所做的所有更改的完整列表,请访问GitHub

模型上下文协议规范(2025-03-26)—— 传输

· 阅读需 14 分钟

翻译自:https://spec.modelcontextprotocol.io/specification/2025-03-26/basic/transports/

ℹ️ 协议修订:2025-03-26

MCP 使用 JSON-RPC 来编码消息。JSON-RPC 消息必须使用 UTF-8 编码。

该协议目前定义了两种标准的传输机制用于客户端与服务器之间的通信:

  1. 通过标准输入和标准输出进行通信
  2. 可流式传输的HTTP

客户端在可能的情况下应该支持标准输入输出。

客户端和服务器也可以以可插拔方式实现自定义传输

标准输入输出

stdio 传输中:

  • 客户端作为一个子进程启动MCP服务器。
  • 服务器从其标准输入(stdin)读取JSON-RPC消息,并将消息发送到其标准输出(stdout)。
  • 消息可以是JSON-RPC请求、通知、响应,或者是一个包含一个或多个请求和/或通知的JSON-RPC批处理
  • 消息通过换行符进行界定,并且必须不包含嵌入的换行符。
  • 服务器可以将UTF-8字符串写入其标准错误(stderr)用于记录日志。客户端可以捕获、转发或忽略这些日志记录。
  • 服务器绝对不可以向它的stdout写入任何非有效MCP消息的内容。
  • 客户端绝不能向服务器的stdin写入任何不是有效MCP消息的内容。

stdio传输

可流式传输的HTTP

ℹ️ 这替换了协议版本 2024-11-05 中的HTTP+SSE 传输。请参阅下面的向后兼容性指南。

可流式的HTTP传输中,服务器作为一个独立的进程运行,可以处理多个客户端连接。这种传输使用HTTP POST和GET请求。服务器可以选择使用服务器发送事件(SSE)来流式传输多个服务器消息。这允许基本的MCP服务器,以及支持流式传输和服务器到客户端通知和请求的更丰富功能的服务器。

服务器必须提供一个支持POST和GET方法的单一HTTP端点路径(以下称为MCP端点)。例如,这可以是像https://example.com/mcp这样的URL。

向服务器发送消息

每个从客户端发送的JSON-RPC消息必须是一个对MCP端点的新的HTTP POST请求。

  1. 客户端必须使用HTTP POST方法向MCP端点发送JSON-RPC消息。

  2. 客户端必须包含一个Accept头部,列出application/jsontext/event-stream作为支持的内容类型。

  3. POST请求的主体必须成为以下之一:

    • 一个单独的JSON-RPC 请求通知响应
    • 一个数组 批处理 一个或多个请求和/或通知
    • 一个数组 批处理 一个或多个响应
  4. 如果输入仅仅包含(任意数量的)JSON-RPC 通知响应:

    • 如果服务器接受输入,服务器必须返回HTTP状态码202 Accepted并且不包含任何内容。
    • 如果服务器不能接受输入,它必须返回一个HTTP错误状态码(例如,400错误的请求)。HTTP响应体可以包含一个没有id的JSON-RPC错误响应
  5. 如果输入包含任意数量的JSON-RPC请求,服务器必须返回Content-Type: text/event-stream以初始化一个SSE流,或者返回Content-Type: application/json以返回一个JSON对象。客户端必须支持这两种情况。

  6. 如果服务器启动一个SSE流:

    • SSE流应该最终包括针对POST正文中发送的每个JSON-RPC请求的一个JSON-RPC响应。这些响应可以批处理的

    • 服务器可以在发送JSON-RPC响应之前发送JSON-RPC请求通知。这些消息应该与发起的客户端请求有关。这些请求和*通知可以批处理

    • 服务器在发送每个收到的JSON-RPC请求的响应之前,不应该关闭SSE流,除非会话过期。

    • 在所有JSON-RPC响应发送完毕后,服务器应该关闭SSE流。

    • 断开连接可能随时可能发生(例如,由于网络条件)。因此:

      • 断开连接不应该被解释为客户端取消了它的请求。
      • 为了取消,客户端应该明确发送一个MCP CancelledNotification
      • 为了避免由于连接断开而导致消息丢失,服务器可以使流可以恢复

监听服务器的消息

  1. 客户端可以向MCP端点发出HTTP GET请求。这可以用来打开一个SSE流,允许服务器与客户端通信,而无需客户端首先通过HTTP POST发送数据。
  2. 客户端必须包含一个Accept头部,列出text/event-stream作为支持的内容类型。
  3. 服务器必须对这个HTTP GET请求返回Content-Type: text/event-stream,或者返回HTTP 405 方法不被允许,表明服务器在这个端点不提供SSE流。
  4. 如果服务器启动一个SSE流:
    • 服务器可以在流上发送JSON-RPC的请求通知。这些请求通知 可以批处理的
    • 这些消息应该与客户端同时运行的任何JSON-RPC请求无关。
    • 服务器不得在流上发送JSON-RPC response除非恢复与先前客户端请求关联的流。恢复
    • 服务器可能会在任何时间关闭SSE流。
    • 客户端可以在任何时候关闭SSE流。

多重连接

  1. 客户端可以同时保持与多个SSE流的连接。

  2. 服务器必须将其每一条JSON-RPC消息只发送在一条已连接的流上;也就是说,它不得在多个流中广播相同的消息。

    • 通过使流可恢复可能可以降低消息丢失的风险。

恢复性和重传

为了支持恢复断开的连接,并重新传送可能丢失的信息:

  1. 正如在SSE标准介绍的,服务器可以附加一个id到他们的SSE事件中。

    • 如果存在,该ID 必须 在该会话中的所有流之间全局唯一——或者如果没有使用会话管理,那么在与那个特定客户端的所有流之间全局唯一。
  2. 如果客户希望在连接断开后恢复,它应该向MCP端点发起一个HTTP GET请求,并包含Last-Event-ID标头用于指示它收到的最后一个事件ID。

    • 服务器可以使用此头部来重放在最后一个事件ID之后本应发送的消息,在被断开的流上,并从那个点恢复流。
    • 服务器不得重播本应在不同流上交付的消息。

换言之,这些事件 ID 应该由服务器在每个流的基础上分配,以便在特定流内充当游标。

会话管理

一个MCP“会话”包含客户端与服务端之间逻辑上相关的交互,始于初始化阶段。为了支持想要建立有状态会话的服务器:

  1. 使用可流式传输的HTTP协议的服务器可以在初始化时分配一个会话ID,通过在载有InitializeResult的HTTP响应中增加Mcp-Session-Id头传递给访问方。

    • 会话ID 应该 是全球唯一且加密安全的(例如,一个安全生成的UUID、一个JWT或一个加密散列)。
    • 会话ID 必须 只包含可见的ASCII字符(范围从0x21到0x7E)。
  2. 如果一个Mcp-Session-Id在初始化期间由服务器返回,使用 Streamable HTTP 传输的客户端必须包在所有随后的HTTP请求中包含该头部。

    • 需要会话 ID 的服务器应该对没有 Mcp-Session-Id 头部的请求(初始化除外)以 HTTP 400 错误请求响应。
  3. 服务器可以在任何时候终止会话,在此之后,它必须用HTTP 404未找到对包含该会话ID的请求作出响应。

  4. 当客户端在包含Mcp-Session-Id的请求中收到HTTP 404响应时,它必须通过发送一个没有附加会话ID的新InitializeRequest来开始一个新会话。

  5. 客户端不再需要某个特定会话时(例如,因为用户要离开该客户端应用程序)应该向MCP端点发送一个包含Mcp-Session-Id头部HTTP DELETE请求,用来明确结束会话。

    • 服务器可以使用HTTP 405方法不允许响应此请求,表明服务器不允许客户端终止会话。

时序图

可流式传输的HTTP传输

向后兼容性

客户端和服务器可以通过以下方式与已弃用的HTTP+SSE传输(来自2024-11-05的协议版本)保持向后兼容:

想要支持旧版客户端的服务器应该:

  • 继续同时托管旧传输的SSE(Server-Sent Events)和POST端点,以及为可流式HTTP传输定义的新的“MCP端点”。
    • 也可以将旧的POST端点和新的MCP端点结合起来使用,但这可能会引入不必要的复杂性。

想要支持旧服务器的客户端应该:

  1. 接受用户提供的一个MCP服务器的URL,该URL可能指向使用旧传输协议或新传输协议的服务器。

  2. 尝试向该URL发送一个包含有InitializeRequest和前述Accept头部的POST请求:

    • 如果成功,客户端可以假设这是一个支持新的Streamable HTTP传输的服务器。
    • 如果它失败并返回一个HTTP 4xx状态码(例如,405 方法不允许 或 404 未找到):
      • 向服务器URL发起一个GET请求,期待这将打开一个SSE流,并将endpoint事件作为第一个事件返回。
      • endpoint 事件到达时,客户端可以认为这是一个运行着旧版HTTP+SSE传输协议的服务器,并且应该使用该传输协议进行所有后续的通信。

自定义传输

客户端和服务器可以根据其特定需求实现额外的自定义传输机制。该协议与传输方式无关,可以在支持双向消息交换的任何通信渠道上实现。

选择支持自定义传输的实施者必须确保它们保留由MCP定义的JSON-RPC消息格式和生命周期要求。自定义传输应当记录它们特定的连接建立和消息交换模式以便于对接。

模型上下文协议规范(2025-03-26)

· 阅读需 6 分钟

翻译自:https://spec.modelcontextprotocol.io/specification/2025-03-26/

ℹ️ 协议修订:2025-03-26

模型上下文协议 (MCP) 是一个开放的协议,它使得语言模型应用程序与外部数据源和工具之间的无缝集成成为可能。无论您是在构建一个由人工智能驱动的集成开发环境(IDE),增强一个聊天界面,还是创建自定义的AI工作流程,MCP都提供了一种标准化的方式连接语言模型与它们所需的上下文。

这个规范定义了权威的协议要求,基于位于schema.ts的TypeScript Schema。

对于实施指南和示例,请访问 modelcontextprotocol.io

本文档中的关键词“MUST”、“MUST NOT”、“REQUIRED”、“SHALL”、“SHALL NOT”、“SHOULD”、“SHOULD NOT”、“RECOMMENDED”、“NOT RECOMMENDED”、“MAY”和“OPTIONAL”应当按照BCP 14 [RFC2119] [RFC8174]所描述的意义进行解读,当且仅当它们如本文所示全部以大写字母出现时。

概览

MCP为应用程序提供了一种标准化的方式来:

  • 与语言模型分享上下文信息
  • 向人工智能系统暴露工具和能力
  • 构建可组合的集成和工作流程

该协议使用 JSON-RPC 2.0消息来建立以下之间的通信:

  • 主机:发起连接的LLM应用程序
  • 客户端:宿主应用程序内部的连接器
  • 服务器:提供上下文和能力的服务

MCP 从 语言服务器协议 中获得了一些灵感,该协议标准化了如何在整个开发工具生态系统中增加对编程语言的支持。与此类似,MCP 标准化了如何将额外的上下文和工具集成到 AI 应用的生态系统中。

关键细节

基础协议

  • JSON-RPC 消息格式
  • 有状态连接
  • 服务器和客户端能力协商

特性

服务器向客户提供以下任一特性:

  • 资源:上下文与数据,供用户或人工智能模型使用
  • 提示:为用户提供的模板化消息和工作流程
  • 工具:AI模型执行的函数

客户端可能会向服务器提供以下功能:

  • 采样:服务器主动的代理行为和递归的大型语言模型交互

附加工具

  • 配置
  • 进度跟踪
  • 取消
  • 错误报告
  • 记录

安全与信任与安全保障

模型上下文协议通过任意数据访问和代码执行路径开启了强大的功能。随着这种能力的增加,所有实现者必须仔细考虑重要的安全和信任问题。

关键原则

  1. 用户同意与控制
    • 用户必须明确同意并理解所有数据访问和操作。
    • 用户必须保留对哪些数据被共享以及采取什么行动的控制权。
    • 实施者应为审查和授权活动提供清晰的用户界面。
  2. 数据隐私
    • 主机在将用户数据暴露给服务器之前,必须获得用户的明确同意。
    • 主机在未经用户同意的情况下不得将资源数据传输到其他地方。
    • 用户数据应该通过适当的访问控制来保护。
  3. 工具安全
    • 工具代表任意代码执行,必须谨慎对待。
      • 特别是,工具行为的描述,如注解,应被视为不可信的,除非它们来自于一个可信的服务器。
    • 主机在调用任何工具之前必须获得用户的明确同意。
    • 用户应在授权使用每个工具之前了解它的功能。
  4. LLM 采样控制
    • 用户必须明确批准任何LLM抽样请求。
    • 用户应该控制:
      • 是否会发生抽样
      • 实际将要发送的提示
      • 服务器可以看到什么结果
    • 该协议有意限制了服务器对提示的可见性。

实施指南

虽然MCP本身不能在协议层面强制执行这些安全原则,但是实现者应该

  1. 将强大的同意和授权流程构建到他们的应用程序中
  2. 提供清晰的安全隐患文档说明
  3. 实施适当的访问控制和数据保护
  4. 在他们的集成中遵循安全最佳实践。
  5. 在他们的功能设计中考虑隐私影响。

在Linux系统上手动配置iSCSI设备

· 阅读需 6 分钟

翻译自:https://www.ibm.com/docs/en/tsmfve/7.1.8?topic=tasks-manually-configuring-iscsi-device-linux-system

这个程序描述了在iSCSI挂载操作中如何配置一个Linux系统。来自Tivoli® 存储管理器服务器存储的VM快照将被挂载。

在你开始之前

在进行iSCSI挂载时,会在Tivoli存储管理器恢复代理系统上创建一个iSCSI目标。Tivoli存储管理器恢复代理系统上不需要Microsoft iSCSI发起器。

提示: Open-iSCSI Initiator随Red Hat Enterprise Linux和SUSE Linux Enterprise Server一起提供。

在您继续执行此任务之前,请审核以下iSCSI要求:

  • 您可以从任何系统连接到iSCSI目标,以创建包含备份数据的卷。您可以从另一个系统挂载这个卷。
  • 任何需要连接到iSCSI目标的系统都需要一个iSCSI发起器。
  • 必须在需要恢复数据的系统上安装一个iSCSI发起器。
  • 如果一个卷跨越多个磁盘,您必须挂载所有需要的磁盘。当使用镜像卷时,只需挂载镜像磁盘中的一个。挂载一个磁盘可以防止耗时的同步操作。

关于这个任务

完成这些步骤来配置在iSCSI装载操作期间使用的Linux系统:

程序

  1. 记录要恢复数据的系统上的iSCSI发起者名称。

iSCSI发起程序的名称位于

/etc/iscsi/initiatorname.iscsi

文件。如果这

发起者名称=

值为空,请使用以下命令创建一个初始化器名称:

twauslbkpoc01:~ # /sbin/iscsi-iname

以下是一个示例的发起者名称:

iqn.2005-03.org.open-iscsi:3f5058b1d0a0
  1. 将发起方名称添加到 /etc/iscsi/initiatorname.iscsi 文件中。

    1. 使用 vi 命令编辑 /etc/iscsi/initiatorname.iscsi 文件。例如:
twauslbkpoc01:~ # vi /etc/iscsi/initiatorname.iscsi
  1. 更新 InitiatorName= 参数为启动者名称。例如:
InitiatorName=iqn.2005-03.org.open-iscsi:3f5058b1d0a0
  1. 在安装了Tivoli存储管理器恢复代理(或iSCSI目标)的系统上完成以下步骤:

    1. 启动Tivoli存储管理器恢复代理。完成选择TSM服务器和选择快照对话框,然后点击挂载

    2. 在 "选择挂载目的地" 对话框中,选择 "挂载一个 iSCSI 目标"。

    3. 创建一个目标名称。确保它是唯一的,并且你可以从运行iSCSI启动器的系统中识别出它。例如:

iscsi-mount-tsm4ve
  1. 输入在步骤1中记录的iSCSI发起者名称,然后点击确定

  2. 请验证您刚刚挂载的卷是否显示在已挂载的卷字段中。

  3. 在步骤1中选定的发起系统上,定位并启动iSCSI发起器程序。

    1. 通过发出这个命令来验证iSCSI服务是否正在运行:

Red Hat Enterprise Linux:

service iscsi status

SUSE Linux Enterprise Server:

service open-iscsi status

如果服务没有运行,执行此命令以启动服务:

Red Hat Enterprise Linux:

service iscsi start

SUSE Linux Enterprise Server:

service open-iscsi start
  1. 通过执行这个命令来连接到iSCSI目标:
iscsiadm -m discovery -t sendtargets -p <IP/hostname of Tivoli Storage Manager recovery agent  system> --login
  1. 通过执行以下命令来验证一个新的原始设备是否可用:
fdisk -l
  1. 挂载文件系统:

对于非LVM卷,请执行以下命令。在这个例子中,新设备是

/dev/sdb1

冒号

mkdir /mountdir
mount /dev/sdb1 /mountdir

对于LVM卷,在Linux客户端完成以下任务:

  1. 确保Linux系统上有vgimportclone脚本。这个脚本不包含在基础(默认)的LVM包中。因此,您可能需要将LVM包更新到提供此脚本的版本。

  2. 发行

vgimportclone

命令并包含一个新的基础卷组名称(

VolGroupSnap01

例如:

vgimportclone --basevgname /dev/VolGroupSnap01 /dev/sdb1
  1. 发行

    lvchange

command to mark the logical volume as active. For example:

lvchange -a y /dev/VolGroupSnap01/LogVol00
  1. 执行这些命令来挂载卷:
mkdir /mountdir 
mount -o ro /dev/VolGroupSnap01/LogVol00 /mountdir
  1. 在文件恢复操作完成后,执行这些命令:

    • 对于非LVM卷,执行以下命令:

      1. 卸载文件系统:
umount /dev/sdb1 /mountdir
  1. 移除该卷。如果该卷是卷组的一部分,首先需要通过以下命令将卷从卷组中移除:
vgreduce <your_volume_group> /dev/sdb1

执行这个命令来移除卷:

pvremove /dev/sdb1
  1. 退出单个目标:
iscsiadm --mode node --targetname <target_name> --logout 
  1. 退出所有目标:
iscsiadm --mode node --logout 
  • 对于LVM卷,在Linux客户端上完成以下任务:

    1. 卸载文件系统:
unmount /mountdir
  1. 移除逻辑卷:
lvm lvremove LogVol00
  1. 删除卷组:
lvm vgremove VolGroupSnap01
  1. 退出单个目标:
iscsiadm --mode node --targetname <target_name> --logout 
  1. 退出所有目标:
iscsiadm --mode node --logout 

Wi-Fi扩展器/中继器与RelayD

· 阅读需 27 分钟

翻译自:https://openwrt.org/docs/guide-user/network/wifi/wifiextenders/relay_configuration?s[]=relayd

这篇文章描述了如何将OpenWrt路由器变成Wi-Fi扩展器/中继器。扩展器使用其一个无线电波段与主路由器进行“上行”Wi-Fi连接,并使用其其他无线电波段作为本地设备的AP(接入点)。然后,扩展器依靠relayd包来桥接两个连接。

为了简便起见,本文从现在开始将使用“Wi-Fi扩展器”或“扩展器”一词。

在以下情况下使用此配置:当你无法控制主路由器,或者主路由器没有运行OpenWrt,或者主路由器不支持首选的无线中继/扩展器与WDS802.11s 网络成型

下图展示了正常的配置。图中右侧的是主路由器:它的LAN端口(192.168.1.1/24)为本地客户端服务,而它的WAN端口(未显示)则连接到互联网。左边的是Wi-Fi扩展器。它通过无线上行链路(标记为“W-LAN (客户端)”)与主路由器相连。Wi-Fi扩展器的其他无线电则作为本地设备的接入点。

有一个Youtube视频演示了这个过程:https://www.youtube.com/watch?v=Bfmx5NjIWLQ,该过程已在OpenWrt 23.05.3版本中进行了测试,该版本发布于2024年6月。

img

使用LuCI Web GUI进行设置

配置局域网接口

本文假设主路由器的地址是192.168.1.1(子网192.168.1.0/24),而“Wi-Fi扩展器子网”的地址是192.168.2.1(子网192.168.2.0/24)。这些子网必须是不同的。

  • 移除Wi-Fi扩展器与主路由器之间的所有有线连接。
  • 将一台电脑通过以太网连接到Wi-Fi扩展器的LAN端口,并在192.168.1.1(默认地址)登录LuCI网页界面。
  • (可选)将Wi-Fi扩展器的固件更新至当前版本。
  • 系统 → 备份/刷写固件 页面,点击 执行重置 按钮可恢复至默认的 OpenWrt 设置。
  • 前往网络 → 接口,点击LAN接口旁的编辑
  • 局域网协议设置为静态地址,点击更改协议(下图)
  • 使用“Wi-Fi扩展器子网”(例如192.168.2.1)分配一个IP地址。
  • 点击保存
  • 点击“保存并应用”

img


  • 重新连接到扩展器的新IP地址(例如 192.168.2.1)
  • 网络 → 接口,点击编辑局域网接口
  • 点击 DHCP Server 标签并禁用DHCP、IPv6 RA-Service和DHCP-v6 Service。操作步骤如下:
    • 通用设置标签页(下图所示),勾选“忽略接口”框以禁用该接口的DHCP功能。
    • IPv6设置标签页(如下图),选择“禁用”RA-服务DHCP-v6服务
  • 点击保存
  • 点击“保存并应用”。
  • 最后,将您电脑的以太网端口设置为在Wi-Fi扩展器的子网中使用静态IP(例如,192.168.2.10)以及默认网关(例如,192.168.2.1),然后使用以太网再次连接到扩展器。

img


img

配置Wi-Fi上行连接

中继器通常会有多个无线电频段可作为上行链路。根据您的环境选择最适合您的一个。5GHz(n/ac/ax)频段传输速度更快,但2.4GHz(b/g/n)频段的覆盖范围更远。

  • 将你的电脑通过以太网线连接到Wi-Fi扩展器上。移除任何其它的物理连接。
  • 导航至“网络 → 无线”页面
  • 选择用于连接到主路由器的无线电频率。
  • 点击扫描按钮来使用那个无线电。

img

  • 从扫描结果中的SSID列表选择主路由器的Wi-Fi SSID,然后点击“加入网络”。

img


  • 你将看到“加入网络”面板(下图)。
    • 将“新网络的名称”设置为`wwan
    • 请输入任何 Wi-Fi 凭证,例如 WPA 密码
    • 选择lan防火墙区域。
  • 点击保存
  • 点击“保存并应用”。

img


您将会看到客户端Wi-Fi设置页面(下图)。根据需要进行编辑。最重要的设置位于操作频率一行。

  • 如果您正在连接到Wi-Fi g网络,请将模式设置为传统;如果您正在连接到Wi-Fi n网络(依此类推),请将其设置为N
  • 宽度设置为与主路由器相同的信道宽度。
  • 保持与扫描过程中发现的相同的Wi-Fi信道号。这将与主路由器相匹配。
  • 完成后点击“保存”。
  • 点击“保存并应用”。

img

移除多余的WAN接口和防火墙区域

虽然这是可选的,但建议删除多余的WAN接口和防火墙区域。

  • 转到“网络 → 接口”(如下图)
  • 删除 WANWAN6 这两个接口。
  • 转到 网络 > 防火墙(下图).
  • 删除 wan 规则。
  • 点击 保存 & 应用

**注意:**这些操作也将自动移除任何多余的防火墙流量和端口转发规则。

img

img

在"wwan"上添加静态IP地址

为新创建的wwan接口分配一个与主路由器LAN(例如192.168.1.30)同一子网中的静态IP地址。然后,你可以使用这个地址来管理路由器,该地址稍后在创建中继接口时也将使用。

  • 转到“网络 → 接口”(如下图)
  • 点击 编辑 来修改 wwan 接口设置

img

  • 在“通用设置”选项卡上,将协议更改为“静态地址”(下图)。
  • 输入一个来自主路由器局域网子网的IP地址(例如,192.168.1.30);一个子网掩码(例如,255.255.255.0);以及一个网关IP地址(例如,192.168.1.1)

img

  • 在“高级设置”标签页(下图)
  • 使用自定义DNS服务器设置为主路由器的IP地址(例如,192.168.1.1)。
  • 点击“保存”按钮
  • 按下“保存并应用”

img

测试连接

此时,Wi-Fi扩展器应该已经无线连接到主路由器。要验证连接:

  • 前往 网络 → 诊断(如下图)
  • 通过点击“IPv4 Ping”按钮进行一次ping测试。
  • 几刻钟后,如果主路由器连接到了互联网,你应该能看到ping的结果。
  • 您没有提供任何内容进行翻译,请输入需要翻译的文本。

img

安装relayd包

  • 转到系统 → 软件(如下图)
  • 点击更新列表按钮。如果Wi-Fi扩展器已连接到主路由器,并且主路由器已连接到互联网,那么几分钟后,更新的结果将会显示出来。
  • 在过滤框中输入 luci-proto-relay (下图所示),然后点击 安装
  • 当操作完成后,从系统 → 重启(下图)重启路由器。

img

img

添加中继接口

添加relayd接口,该接口将在扩展器的lanwwan接口之间进行桥接。为此:

  • 转到网络 → 接口
  • 点击 添加新接口(下图)

img

  • 添加新界面窗口中(下图)
    • 输入一个名称(“repeater_bridge”是一个不错的选择)
    • 选择下图所示的中继桥接协议。(如果中继桥接选项没有出现,请重启您的设备。)
  • 点击 创建接口

img

  • 网络 → 接口中,点击新的“repeater_bridge”接口旁的编辑按钮(如下图)
    • 确保协议为“中继桥”。
    • 输入分配给wwan接口的IP地址。(例如:192.168.1.30)
    • 在“网络之间的中继”列表中选择lanwwan
  • 点击保存
  • 点击“保存并应用”。
  • 完成上述步骤后,请重启路由器。

img

启用AP(接入点);

启用并配置Wi-Fi扩展器作为本地设备的接入点。

您可以使用与主路由器相同的Wi-Fi网络名称(SSID)以及相同的加密、密码等设置。这样可以让无线设备在最佳的Wi-Fi网络之间自由漫游。或者,您也可以选择给Wi-Fi扩展器设置与主路由器不同的SSID/加密/密码凭据。

  • 前往 网络 → 无线
  • 点击任何标有“模式:主”的SSID旁边的编辑按钮。(不要编辑连接到主路由器的“模式:客户端”上行链接。)
    • 接口配置部分,配置SSID、安全性和其他参数,以便Wi-Fi扩展器可以像接入点一样工作。
    • 如果您正在配置也用作上行链接的无线电,请确保操作频率保持不变。
    • 点击保存
  • 启用那个无线网络。
  • 您可以编辑/启用其他无线电(例如,同时启用b/g/n和n/ac/ax等无线电)。
  • 点击“保存并应用”。

你已完成!再进行更多测试

你已经完成了!Wi-Fi扩展器应该已经开始扩展你主路由器的网络了。将你的计算机切换回DHCP客户端模式,并连接到新配置的Wi-Fi。你的计算机应该已经完全接入互联网,并且从你主路由器那里获取了一个DHCP IP地址。

状态 → 概览 窗口(下图)显示最终结果。radio1 是主路由器的DHCP客户端。客户端Wi-Fi在 Host 列中有一个问号而不是IP地址,因为它的 wwan IP地址只能在网络接口页面中看到。在下面的图片中,radio0(接入点)还没有被配置/启用。但是它会显示你为扩展器配置的SSID。

img

使用命令行界面设置

在进行任何实际配置之前,必须启用 Wi-Fi 接口以便扫描附近的网络:

uci set wireless.@wifi-device[0].disabled="0"
uci commit wireless
wifi
  • 将禁用选项设置为0(以启用无线)
  • 保存更改后的配置文件
  • 使用 wifi 命令启动无线连接

现在我们可以使用iw dev wlan0 scan列出范围内的网络,如果你的无线接口名称不同,请将wlan0替换为实际的接口名称(ifconfig列出所有可用的接口,以便找出你的无线局域网是如何命名的)。

iw dev wlan0 scan` output example:

# iw dev wlan0 scan
BSS c8:d5:fe:c8:61:b0(on wlan0) -- associated
TSF: 24324848870 usec (0d, 06:45:24)
freq: 2412
beacon interval: 100 TUs
capability: ESS (0x0411)
signal: -72.00 dBm
last seen: 140 ms ago
Information elements from Probe Response frame:
SSID: Violetta
RSN: * Version: 1
* Group cipher: CCMP
* Pairwise ciphers: CCMP
* Authentication suites: PSK
* Capabilities: 1-PTKSA-RC 1-GTKSA-RC (0x0000)
BSS f8:35:dd:eb:20:f8(on wlan0)
TSF: 24225790925 usec (0d, 06:43:45)
freq: 2457
beacon interval: 100 TUs
capability: ESS (0x0431)
signal: -90.00 dBm
last seen: 1450 ms ago
Information elements from Probe Response frame:
SSID: GOinternet_EB20FB
HT capabilities:
Capabilities: 0x11ee
HT20/HT40
SM Power Save disabled
RX HT20 SGI
RX HT40 SGI
TX STBC
RX STBC 1-stream
Max AMSDU length: 3839 bytes
DSSS/CCK HT40
Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
Minimum RX AMPDU time spacing: 4 usec (0x05)
HT RX MCS rate indexes supported: 0-15, 32
HT TX MCS rate indexes are undefined
HT operation:
* primary channel: 10
* secondary channel offset: below
* STA channel width: any
RSN: * Version: 1
* Group cipher: TKIP
* Pairwise ciphers: TKIP CCMP
* Authentication suites: PSK
* Capabilities: 1-PTKSA-RC 1-GTKSA-RC (0x0000)

在这个例子中,有两个网络,一个叫Violetta的Wi-Fi g网络和一个叫GOinternet_EB20FB的Wi-Fi n网络。该设备被配置为连接到名为Violetta的那个网络。

这些是配置过程中添加或更改的uci值。对于SSID、BSSID和加密,您必须使用上面的Wi-Fi扫描得到的信息。关于为什么这些值会被更改的解释,请阅读上面的luci教程。

network.lan.ipaddr='192.168.2.1'
network.repeater_bridge=interface
network.repeater_bridge.proto='relay'
network.repeater_bridge.network='lan wwan'
network.wwan=interface
network.wwan.proto='dhcp'
firewall.@zone[0].network='lan repeater_bridge wwan'
dhcp.lan.ignore='1'
wireless.radio0.hwmode='11g'
wireless.radio0.country='00'
wireless.radio0.channel='1'
wireless.radio0.disabled='0'
wireless.@wifi-iface[0]=wifi-iface
wireless.@wifi-iface[0].device='radio0'
wireless.@wifi-iface[0].mode='ap'
wireless.@wifi-iface[0].encryption='none'
wireless.@wifi-iface[0].ssid='OpenWrt'
wireless.@wifi-iface[0].network='lan'
wireless.@wifi-iface[1]=wifi-iface
wireless.@wifi-iface[1].network='wwan'
wireless.@wifi-iface[1].ssid='Violetta'
wireless.@wifi-iface[1].encryption='psk2'
wireless.@wifi-iface[1].device='radio0'
wireless.@wifi-iface[1].mode='sta'
wireless.@wifi-iface[1].bssid='C8:D5:FE:C8:61:B0'
wireless.@wifi-iface[1].key='myWifiPasswordHere'

请注意,在这个例子中设备生成的Wi-Fi网络(叫做OpenWrt)是没有密码和加密的。之所以这么做是因为本文的重点是搭建中继桥接。您可能会希望按照这里解释的Wi-Fi设置页面中的说明,以更安全的方式设置您的设备Wi-Fi网络。

网络细节

如果不需要桥接网络,你可以考虑使用简单无线客户端作为替代 relayd 的方法。Wi-Fi扩展器可以通过其静态wwan IP 地址(例如,192.168.1.30)进行管理。

即便所有连接在Wi-Fi扩展器上的终端设备都会从主路由器的LAN子网获得DHCP地址,Wi-Fi扩展器的LAN接口必须处于不同的子网中,以便relayd能够工作(由于它需要路由交通,它预期有两个不同的子网)。

由于以太网端口和接入点Wi-Fi网络都在同一个LAN接口上,所有连接到Wi-Fi扩展器设备的以太网端口和接入点Wi-Fi网络的客户端都将通过relayd进行路由,并将连接到您的主网络。

LAN 接口子网将仅用作“管理”接口,因为连接到 Wi-Fi 中继器的设备将位于主网络的子网中。如果 relayd 设备变得无法访问,您将不得不配置一台 PC,为其设置与 LAN 接口同一子网中的静态地址(例如,在我们的例子中是192.168.2.10),以便能够连接并使用 LuCI GUI 或 SSH。

故障排除

访问扩展器

如果你发现Wi-Fi扩展器本身仅能通过直接连接到W-LAN AP的计算机访问,而不能通过连接到OpenWrt W-LAN客户端的计算机访问,并且处于192.168.1.0子网中,请确保Relay bridge接口中的Local IPv4 address(本地IPv4地址)设置与无线上行链路的IP地址匹配。(另一种方法比较繁琐:如果你手动将计算机配置到该子网,可以通过OpenWrt盒子的192.168.2.1地址访问。)

检查防火墙区域

![:!:]配置的以下部分本不应该是必要的。默认操作应该已经自动更改了它们。如果有什么不工作,请也检查这个。

img


img

添加IPv6支持

在你的主路由器上激活 IPv6 支持以获取公共 IPv6 前缀。在我们的 Wi-Fi 扩展器上激活 IPv6,以允许对你的公共 IPv6 地址进行无状态地址自动配置(SLAAC)以及处理 IPv6 流量。

  1. 前往“网络/接口”,创建一个新的接口。将其命名为WWAN6,使用DHCPv6协议,并覆盖WWAN接口。在新接口的“常用配置”中,配置:请求IPv6地址:禁用。在防火墙设置中:检查“lan / repeater bridge…”行是否被选中。保留其他默认设置,特别是,将“自定义委派IPv6前缀”字段留空。在“接口/概览”页面上检查WWAN接口是否获得了公共IPv6地址。

  2. 编辑LAN接口设置,DHCP服务器/IPv6设置:检查/修改以下设置:路由器通告服务:中继模式,DHCPv6服务:禁用,NDP-Proxy:中继模式。

  3. 在你的OpenWrt设备上开启一个SSH会话。执行以下命令:

uci set dhcp.wan.interface=wwan
uci set dhcp.wan.ra=relay
uci set dhcp.wan.ndp=relay
uci set dhcp.wan.master=1
uci commit

我们假设你在之前的指南中建议加入另一个Wi-Fi网络时选择了wwan作为名称。如果不是,请相应地更改dhcp.wan.interface=…这一行。

就是这样。重新启动ophcpd(通过系统 → 启动或者执行service odhcpd restart命令),你的IPv6网络应该会开始自行配置。连接的支持IPv6的设备应该会获取来自你公共IPv6前缀派生的公共IPv6地址,并且IPv6流量应该会通过你的Wi-Fi扩展器传输。

已知问题

以下是一些最近报告的问题清单:

  1. 由接入点引起的DHCP问题。OWrt论坛
  2. 极低的上行传输速度问题影响了一些MT762x设备。OpenWrt论坛 故障报告FS#2816
  3. 连接到relayd设备的设备无法被访问。 参考这个讨论 第二个可能类似的案例 参考这个讨论
  4. 无法在同一无线电频率上启用客户端和接入点(AP)
  5. 路由器后门附加指令,因为一旦在LAN上禁用了dhcp,路由器就变得无法访问。如果无线接入点有更改,可能会发生这种情况。例如,wifi SSID、信道号或安全密码发生变化。
    1. 使用以太网缆线将计算机连接到Wifi桥的LAN端口。
    2. 在计算机上配置一个静态IP地址。例如,如果无线桥接在上述例子中使用的局域网IP地址为192.168.2.1,那么使用静态IP地址:192.168.2.10。
    3. 根据上述示例,在浏览器中访问192.168.2.1以进入LuCI界面。
  6. '''替代的relayd设置指南'''
  7. 替代的详细Relayd设置指令也可以在1-OpenWrt-LEDE安装指南HH5A的第9.10节中找到。
  8. 在macOS 10.15及以上版本上,当在局域网设置ULA前缀时,IPv6无法工作 https://github.com/openwrt/openwrt/issues/7561

使用NAT

**评论:**这看起来像是配置一个简单无线客户端的基本说明。

这种方法基本上是在第一个无线路由器上串接了一个第二个无线路由器;即通常这意味着扩展器的客户端将位于双重NAT之后。

就像用一根电缆将Wi-Fi扩展器的WAN端口与主路由器的LAN端口连接起来,Wi-Fi扩展器为自己和连接到它的设备创建了一个新的网络,这样就可以连接到互联网,并且访问主路由器的LAN网络中的设备。但在这种情况下,我们是通过无线网络来实现的。

前提条件:- 带有两个初始接口(局域网,广域网)的路由器

使用WebUI进行设置:

  • 进入“网络 → 接口”页面,点击编辑局域网接口,
  • 将局域网设置为静态IPv4地址192.168.x.1(其中x与您将通过Wi-Fi连接的网络不同),
  • 进入网络 → Wi-Fi,点击扫描,选择“网络”链接,然后点击“加入网络”。
  • 输入Wi-Fi密码,将“新网络名称”保留为“WWAN”并选择WWAN(或WAN)防火墙区域。点击保存。
  • 进入网络 → 接口页面,点击编辑 wwan 接口,
  • 移动到防火墙标签页。点击保存并应用。
  • 进入网络 → 防火墙,点击wan区域的编辑,然后在“覆盖的网络”中勾选WAN和WWAN,点击保存并应用。

现在你已经正确地将WWAN与WAN进行了绑定,并因此将WWAN与LAN也绑定起来了。

可能过时

这部分收集了本文档前面所有不确定的声明和条款。任何仍然有效的应该移动到相关的部分。

按照本文的指导使用relayd并不能保证与所有兼容Openwrt的设备或wifi网络兼容 - 仅作为最后的手段使用。

如果两个设备都支持,可以考虑使用首选的无线中继器/扩展器与WDS802.11s Mesh 网络

如果需要支持虚拟局域网(VLAN),您可以使用第2层GRE隧道(“gretap”)。

最常见的问题是,客户端路由器无法在主路由器和连接到客户端路由器的客户端之间传递DHCP消息。目前看来似乎是硬件/SOC(系统芯片)的限制(与MAC克隆有关?)。

应该可以使用 kmod-trelay 来代替 relayd,关于如何使用它的唯一信息可以在其源代码中查看,如果你成功地使用了它,请在本文中添加一个相关部分。

在这篇文章中,您将看到如何配置您的设备以使其成为一个Wi-Fi扩展器/中继器/桥接器。

在某些情况下,OpenWrt中使用的无线驱动程序不支持在客户端模式下与特定的“上游”无线系统进行“第二层”桥接。当这种情况发生时,一种方法是将LAN和上游无线系统之间的流量进行路由。像DHCP这样的广播流量和mDNS之类的本地链接发现通常是不可路由的。

当其他选项不起作用时,relayd 包为 IPv4(仅限)实现了类似桥接的行为,包括 DHCP 和广播中继。这种配置可以通过 SSH(远程终端)或通过 Luci GUI 进行。

这张图片展示了一个示例设置。中继设备的LAN接口必须位于不同的子网上,中继功能才能工作(因为它需要路由流量,它预期有两个不同的子网)。

由于以太网端口和接入点Wi-Fi网络都在同一个LAN接口上,所有连接到Wi-Fi扩展器设备的以太网端口和接入点Wi-Fi网络的客户端都将通过relayd进行路由,并将连接到您的主网络。

LAN 接口子网将仅用作“管理”接口,因为连接到 Wi-Fi 中继器的设备将位于主网络的子网中。如果 relayd 设备变得无法访问,您将不得不配置一台 PC,为其设置与 LAN 接口同一子网中的静态地址(例如,在我们的例子中是192.168.2.10),以便能够连接并使用 LuCI GUI 或 SSH。

OpenAI Responses对比Chat Completions

· 阅读需 8 分钟

翻译自:https://platform.openai.com/docs/guides/responses-vs-chat-completions?api-mode=responses

比较响应(Responses)API和聊天补全(Chat Completions)API。

Responses APIChat Completions API 是与 OpenAI 的模型交互的两种不同方式。本指南解释了这两个 API 之间的主要区别。

为什么选择Responses API?

Responses API是我们最新的核心API,也是一个代理性(Agentic)的API原语,它结合了聊天补全任务的简单性和执行更多能动任务的能力。随着模型能力的发展,Responses API是构建以行动为导向的应用程序的灵活基础,其内置了多种工具:

如果您是新用户,我们推荐使用Responses API。

CapabilitiesChat Completions APIResponses API
Text generation
Audio即将推出
Vision
Structured Outputs
Function calling
Web search
File search×
Computer use×
Code interpreter×即将推出

Chat Completions API不会消失

Chat Completions API 是构建 AI 应用程序的行业标准,我们打算无限期地继续支持这个 API。我们引入的 Responses API 旨在简化涉及工具使用、代码执行和状态管理的工作流程。我们相信这个新的 API 原语将使我们能够在未来更有效地增强 OpenAI 平台。

具有状态的API和语义事件

使用Responses API可以使事件处理更为简单。它拥有一个可预测的事件驱动架构,而Chat Completions API在生成字符时会不断向内容字段追加,这要求您手动跟踪每个状态之间的差异。多步骤的会话逻辑和推理通过Responses API来实施会更加容易。

Responses API 明确发出了语义事件,详细说明了发生了什么变化(例如,具体的文本添加),因此您可以编写针对特定发出事件(例如,文本更改)的集成,从而简化集成并提高类型安全性。

比较代码

以下示例展示了如何对聊天补全APIResponses API进行基本的API调用。

文本生成示例

这两个API都使我们能够轻松地从模型生成输出。一个completion需要一个messages数组,但是一个response需要一个input(字符串或数组,如下所示)。

聊天补全API

from openai import OpenAI
client = OpenAI()

completion = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "user",
"content": "Write a one-sentence bedtime story about a unicorn."
}
]
)

print(completion.choices[0].message.content)

响应 API

from openai import OpenAI
client = OpenAI()

response = client.responses.create(
model="gpt-4o",
inputs=[
{
"role": "user",
"content": "Write a one-sentence bedtime story about a unicorn."
}
]
)

print(response.output_text)

当你从Responses API收到回复时,字段有细微差异。你会收到一个带有独立id的类型化response对象,而不是一个message。默认情况下会存储响应。对于新账户,默认情况下会存储聊天补全信息。要在使用任一API时禁用存储,请设置store: false

聊天补全API

[
{
"index": 0,
"message": {
"role": "assistant",
"content": "在柔和的月光下,独角兽露娜跳舞穿梭在闪烁的星尘中,为每一个沉睡的孩子留下梦境的轨迹。",
"refusal": null
},
"logprobs": null,
"finish_reason": "stop"
}
]

响应 API

在月光柔和的照耀下,独角兽露娜在闪烁的星尘田野中舞动,为每一个熟睡的孩子留下梦境的轨迹。

其他值得注意的差异

  • 响应返回output,而聊天补全返回一个choices数组。
  • Structured Outputs API 的结构不同。使用 Responses 中的 text.format 而不是 response_format。在结构化输出指南中了解更多信息。
  • 函数调用API的形式不同——这体现在请求中的函数配置以及响应中发回的函数调用上。详见函数调用指南中的完整差异。
  • 推理是不同的。在聊天续写API中使用reasoning_effort,而在Responses API中使用reasoning.effort。阅读推理指南中更多的细节。
  • Responses SDK 有一个 output_text 助手函数,而 Chat Completions 没有。
  • 对话状态:在聊天补全中,你必须自己管理对话状态,而响应中有previous_response_id来帮助你处理长时间运行的对话。
  • Responses API响应默认情况下会被存储。对于新账户,默认也会存储聊天补全接口结果。要禁用存储,请设置store: false

这对现有的API意味着什么

聊天补全API

Chat Completions API 仍然是我们使用最广泛的 API。我们将通过新模型和功能继续支持它。如果您的应用程序不需要内置工具,您可以放心地继续使用 Chat Completions。

我们将继续发布新的聊天补全模型,只要它们的功能不依赖内置工具或多个模型调用。当你准备好使用为代理工作流程专门设计的高级功能时,我们推荐使用Responses API。

助手

根据开发者对Assistants API测试版的反馈,我们在Responses API 中整合了关键的改进,使其更加灵活、快速以及易于使用。Responses API 代表了在 OpenAI 上构建代理的未来方向。

我们正在努力实现Assistants API与Responses API之间的全部功能对等,包括对助手式和线程式对象以及代码解释工具的支持。完成后,我们计划在2026年上半年前正式宣布停用助手API,并确定一个目标停用日期。

在弃用后,我们将提供从Assistants API到Responses API的明确迁移指南,该指南允许开发人员保留所有数据并迁移他们的应用程序。在我们正式宣布弃用之前,我们将继续向Assistants API提供新模型。

介绍MCP市场:Cline的新应用商店

· 阅读需 5 分钟

翻译自:https://cline.bot/blog/introducing-the-mcp-marketplace-clines-new-app-store

记得在安装新应用程序时需要在终端输入晦涩难懂的命令,手动解决依赖关系,还得祈祷不会出错吗?那正是我们现在用模型上下文协议(MCP)服务器的情况。但现在不再是这样了。今天,我很兴奋地宣布Cline的MCP市场——想象一下,它就像是你AI能力的应用商店。这是我们让每个人都能轻松获取AI超能力的答案,而不仅仅是技术精通的少数人。

为什么这很重要

几个月前,Anthropic发布了模型上下文协议——一种高级的说法就是“嘿,让我们标准化人工智能与外部工具的交流方式。”这是个很酷的概念,但就像许多伟大的技术一样,最初的设置过程大概和报税一样有趣。在Cline,我们亲眼看到了这一点。用户喜欢MCPs的强大能力但讨厌设置过程。他们需要:

  • 找到正确的GitHub仓库
  • 阅读技术文档
  • 手动配置JSON文件
  • 交叉他们的手指并希望它能奏效

并不完全是我们所期望的“人工智能的未来”体验。

进入MCP市场

这是我们构建的:一个清晰、简洁的界面,在这里你可以:

  • 浏览可用的MCP服务器
  • 查看评分、下载次数和描述
  • 单击一次即可安装任何MCP。
  • 获取自动设置和配置

不再需要处理JSON。不再有依赖地狱。只需点击一下,让Cline来处理剩下的。

它是如何工作的

  1. 在VS Code中打开Cline(顺便说一下,我们刚达到了70万次下载,谢谢大家!)
  2. 导航到MCP市场
  3. 找到一个你想要的MCP服务器(我们拥有从Figma集成到网络搜索的所有功能)
  4. 点击"下载"
  5. 让Cline来处理设置

就是这样。Cline 阅读安装说明,向您询问任何必要的 API 密钥,并自动配置一切。

针对MCP开发者

如果您正在构建MCP服务器(你真是个好人),我们正在引入一项新标准:llms-installation.md 文件。这是一套专门的指导说明,可以帮助像Cline这样的AI代理可靠地安装您的MCP服务器。把它当作是为一个非常能干但思维很字面化的初级开发者编写指导说明。包括:

  • 必需的依赖项
  • API密钥要求(必需及可选)
  • 逐步安装过程
  • 常见故障排除提示

想要在我们的列表中看到你的MCP服务器吗?在我们的mcp-marketplace 仓库创建一个问题,附上:

  1. 你的GitHub仓库网址
  2. 一个400x400的PNG格式的标志
  3. 它应该被包括在内的简要描述

接下来是什么

这仅仅是个开始。随着我们的市场不断增长,我们看到了令人难以置信的MCPs(Marketplace Creators' Programs)被构建起来——从代码分析工具到设计集成。可能性是无限的,我们迫不及待想看到你们打造出什么。如果你已经在使用Cline(感谢你!),MCP市场更新现在正在推出。如果你还没有尝试Cline,那么现在是给你的AI赋予超能力的最好时机。想要持续了解Cline并获得新功能的早期访问权限吗?请在下面订阅我们的新闻通讯。我们正在构建AI开发的未来,我们很乐意带你一起加入这趟旅途。

PS:如果你正在用MCP打造一些酷炫的东西,我很想听听。在Twitter上联系我!

MCP服务器解释:它们是什么,如何工作,以及为什么Cline正在革新人工智能工具

· 阅读需 12 分钟

翻译自:https://cline.bot/blog/mcp-servers-explained-what-they-are-how-they-work-and-why-cline-is-revolutionizing-ai-tools

了解MCP服务器是什么以及它们是如何工作的。学习Cline是如何利用模型上下文协议(MCP)服务器来彻底改变AI工具整合和开发的。继续阅读以获取深入的见解!

周二我在旧金山的CodeGen Night活动上,有机会与一些Cline的高级用户讨论MCP(模型上下文协议)服务器。这些都是精通技术的开发者,他们听说过MCP,但因为不完全了解它的工作原理或者它为何重要,所以没有使用它。

这次对话让我意识到一点:如果连高级用户都不能完全理解MCP服务器,我们需要一个更好的方法来解释它们。那么让我一次性以最简单的方式把这个问题说明白。

什么是MCP服务器以及它们是如何工作的?

想象一下没有MCP的Cline,就像一台没有互联网接入的电脑——功能强大但孤立无援。添加了MCP就像不仅仅是给它接入了互联网,还给它提供了一个应用商店,每个新应用都赋予了它新的功能。但有趣的是:Cline实际上能够为自己创造新应用。

MCP服务器 就像是人工智能和工具之间的智能适配器。传统的API需要按照特定的格式输入精确的命令——就像必须记住特定的咒语才能让事物运作一样。而MCP服务器,则提供了一个灵活的界面,让人工智能更自然地理解和使用工具。

底层原理

MCP服务器就像一个工具菜单,每个工具都被仔细描述以便AI能理解如何使用它。例如,当你看一个Notion的MCP服务器时,你会发现像create_databasequery_database这样的工具。每个工具包括:

  • 一个名称: 它叫什么。
  • 一个自然语言描述: 它的作用。
  • 一个模式(一套参数): 确切定义了它需要的信息。
  • 实际代码: 发起API调用。

img

当Cline想在Notion中创建数据库时,这是他的过程:

  1. 发现: MCP服务器告诉Cline可用的工具有哪些。
  2. 选择: Cline 观察到一个像 create_database 这样的工具以及它的描述。
  3. 规格说明: 服务器会明确告诉客户端它需要什么信息(例如,创建的位置、命名等)。
  4. 执行: Cline以正确的格式提供那些信息,服务器则负责实际调用Notion的API。

注意: 您仍然需要API密钥和适当的安全措施。MCP并不神奇;它特别之处在于它创造了一种标准方式,使AI可以发现并使用工具而无需学习每个API的具体细节。

一个令人震惊的MCP实战

两个月前,当我们首次将MCP支持加入Cline时,我目睹了一些完全改变了我对人工智能工具可能性认知的事情。以下是发生的事情:

  • 步骤1: Cline 阅读了一个自述文件,解释了如何构建一个 Notion MCP 服务器。
  • 步骤2: 它实际上构建了服务器本身并将其添加到了工具包中。
  • 步骤3: 第一次尝试向Notion数据库中添加内容时,它的架构设置错误了。
  • 步骤4: 它没有失败,而是识别出了错误,理解了正确的模式应该是什么,并对其进行了修正。
  • 步骤5: 然后它成功完成了任务。

这是我意识到MCP真正特别之处的时刻——它不仅仅是关于连接到工具;它是关于使这些连接变得足够聪明和灵活,以至于人工智能可以理解它们、使用它们,甚至调试它们。

img

为什么MCP服务器是游戏规则的改变者

当Anthropic两个半月前发布MCP时,它是一个有前景的标准。但就在两个月前,当我们在Cline中增加了MCP支持时,我们不仅仅是实现了它——我们重新想象了它的潜能。

当其他人工智能助手刚刚开始增加基本的MCP支持时,Cline已经在构建它自己的MCP服务器了。想象一下:一个可以阅读文档或自然语言需求并为自己创建新工具的人工智能助手。

每新增一个MCP服务器,就好比为Cline的工具箱增添了一项新能力。与传统的集成方式不同,开发者必须手动构建一切,Cline能够自行创建这些工具。更重要的是,这些功能将成为不断增长的生态系统的一部分,所有与MCP兼容的人工智能工具都可以使用。

未来MCP为AI工具集成所启用的功能

还记得网页浏览器刚问世时吗?它们为我们提供了一个与在线信息互动的通用方式。MCP正在为AI做同样的事情——提供一种让AI工具与软件互动的通用方式。而Cline正在促进这一运动。

想象一下可以做到以下事情的AI工具:

  • 与公司内部工具集成: 允许安全、无缝地访问内部数据。
  • 自动学习新应用: 通过探索并与各种API进行交互,无需人工干预。
  • 即时适应工具变更: 无需不断更新。
  • 与支持MCP的任何软件协作: 从Notion和GitHub到您构建的任何自定义工具。

当其他人刚开始使用MCP作为连接人工智能和工具的方法时,我们却有不同的看法。对于Cline来说,MCP不仅仅是关于连接到工具——它是关于人工智能可以创建自己的连接。Cline构建的每一个新的MCP服务器不仅增强了它自己的能力,也为整个生态系统做出了贡献。

这对你意味着什么

如果你现在正在构建AI工具或集成,MCP服务器应该列入你的关注范围。它们不仅仅是另一种协议——它们代表了AI工具与软件交互方式的根本转变。

在Cline,我们全面投入到MCP上,因为我们相信这是AI工具集成的未来。AI能够自然地与工具交互,而不需要复杂的集成,这改变了一切关于可能性的事情。

想要了解更多吗? 查看我们的创建自定义MCP服务器的文档,看看它有多简单——并探索无限的可能性。


常见问题解答(FAQ)

MCP服务器是什么?

MCP服务器是标准化、智能的适配器,它们允许AI工具发现、理解和与各种外部API和服务进行交互,无需为每一个都进行定制集成。

MCP服务器是如何工作的?

他们提供了一系列工具的菜单,每个工具都用自然语言描述,并有一个定义好的模式。AI应用程序(如Cline)可以动态查询这些服务器来执行诸如读取文件、查询数据库或创建新集成等任务。

MCP服务器对于人工智能开发为什么重要?

MCP服务器简化了AI与外部工具交互的方式,使AI系统能够即时适应、创建和调试集成,使它们比传统的API集成更加灵活和强大。

Cline如何使用MCP服务器?

Cline不仅集成了现有工具(如Notion或GitHub)的MCP服务器,而且还能够通过阅读文档和自主创建新的工具连接来构建自己的MCP服务器。


结论

MCP服务器是AI领域的一项根本性创新,它们充当AI与外部数据和工具海量世界之间的通用连接器。通过标准化AI与软件的交互方式,MCP服务器将一个静态、孤立的模型转变为一个动态的、能够感知上下文的助手——就像不仅仅给电脑提供互联网接入,而是提供了一个拥有众多能力的应用商店。

在Cline,我们正在利用MCP(主控程序)来彻底改变AI辅助开发。随着每一个新的MCP服务器的加入,我们的人工智能变得更加强大、更加适应性强,以及与您每天使用的工具更好地整合。这不仅仅是另一个协议——这是AI工具集成的未来。

使用Docusaurus构建现代化文档网站

· 阅读需 38 分钟

翻译自:https://semaphoreci.com/blog/docusaurus?spm=5176.29680977.0.0.29b8PErsPErscX

在构建一个软件产品时,无论是一个框架、库,或者任何有趣的技术,拥有一个设计良好的文档网站,提供优秀的用户体验是必不可少的。不管产品本身有多出色,如果文档不到位,它可能严重影响该产品的采用和使用性。用户经常抱怨浪费时间寻找答案,不得不求助于外部资源,或对官方文档付出的努力微乎其微表达失望。

对于投入了无数时间构建产品的开发者或组织来说,这样的批评可能会令人沮丧,但它们突出了一个重要的现实:如果你的文档网站建设得很糟糕,它会给人留下产品质量差的坏印象。

然而,从头开始构建一个软件文档网站可能令人望而却步。这需要极大的努力和对细节的敏锐注意。使用像Next.js这样的通用工具无疑是一个可行的选择,但它需要手动处理内容管理、SEO、可访问性、版本控制以及其他技术复杂性方面的问题。处理这些复杂性可能会分散人们创建全面软件文档这一核心目标的注意力。

多年来,为了应对这些挑战,涌现出了多种专门工具。Docusaurus就是其中一个受到欢迎的工具。Docusaurus通过处理技术上的繁重工作,使得构建软件文档变得极为容易,让你能够更多地专注于创造高质量的内容,而不是担心底层的基础设施。在这篇文章中,我们将学习如何使用Docusaurus来构建既美观又实用、而且使用起来令人愉悦的文档。

Docusaurus是什么?

Docusaurus 是一个用于构建文档网站的开源工具。它由 Meta 的工程师们创建,目的是使创建和维护文档变成一种愉悦的体验。Docusaurus 背后的理念是允许您使用 Markdown 和基于 React 的 MDX 来编写文档。这种结合让创建常规文档页面和互动内容变得简单。Docusaurus 最大的优点之一是它建立在 React 之上,这意味着您可以利用现有的 React 知识并编写自定义 React 组件。包括 Algolia、Redis Labs Developer Site、Atlas、Jest 和 React Native 在内的许多知名公司,仅举几例,都因为它提供的卓越开发者体验而采用了 Docusaurus 来构建他们的文档。

为什么选择Docusaurus?与其他选择的比较

Docusaurus经常是构建文档网站的热门选择,但它并不是唯一可用的选项。让我们将Docusaurus与一些流行的替代品进行比较:

功能DocusaurusGitBookMkDocsVuePressJekyllSphinx
基础技术ReactJavaScriptPythonVueRubyPython
自定义性中等中等
学习曲线中等中等中等陡峭
版本控制内置有限插件插件插件内置
国际化内置内置插件插件插件内置
性能中等中等
MDX 支持
搜索功能内置内置插件插件插件内置
输出格式网页网页,PDF网页网页网页网页,PDF,ePub
最适用于大型Web文档,React开发者快速设置,非开发人员中小项目Vue开发者静态站点Python项目

每个工具都有其优势,但当你需要一个现代化、可定制的文档网站,并且拥有版本控制和国际化等开箱即用的功能时,Docusaurus表现尤为出色。其基于React的基础使它对那些已经在处理基于React的项目的团队格外吸引人。

先决条件

为了确保你能有效地跟上进度,本教程假设你具备以下条件:

  • Node.js已安装
  • React的基础知识
  • Markdown语法的基本理解

开始使用

Docusaurus 简化了设置文档网站的过程,使您能够快速从概念到部署。在本节中,我们将初始化一个新的 Docusaurus 项目,探索其结构,并使其在本地运行。

安装Docusaurus

Docusaurus 提供了一个实用的命令行工具,该工具使用合理的默认值来构建一个新项目。要初始化一个新项目,请打开你的终端并运行:

npx create-docusaurus@latest my-docs classic

这将创建一个名为 my-docs 的新Docusaurus项目,但您可以使用任何您喜欢的名字。classic 标志指定该项目将使用经典模板,其中包括文档站点所需的基本功能和配置。在设置过程中,您将被提示选择:

  • Javascript或者Typescript(为了本教程的目的,我将使用Javascript)
  • 可选的 GitLab/GitHub 仓库创建

您也可以从一开始就选择使用任何包管理器,比如npm、yarn或pnpm。

npm init docusaurus
# or
yarn init docusaurus
# or
pnpm init docusaurus

项目结构

让我们进入新创建的Docusaurus项目,并熟悉其结构:

cd my-docs

你会看到类似于:

my-docs
├── blog
├── docs
│ ├── intro.md
│ └── tutorial-basics
│ ├── congratulations.md
│ ├── create-a-blog-post.md
│ ├── create-a-document.md
│ ├── create-a-page.md
│ ├── deploy-your-site.md
│ ├── markdown-features.md
│ └── thank-you.md
├── package.json
├── src
│ ├── components
│ ├── css
│ └── pages
├── static
├── .gitignore
├── barbel.config.js
├── package.json
├── package-lock.json
└── docusaurus.config.js

关键目录:

  • blog/:这个目录包含用 Markdown 或 mdx 编写的博客文章。
  • docs/:这是一个放置文档文件的位置,文件格式为Markdown或mdx。
  • src/:在这里,你可以创建页面和自定义组件、布局以及其他与你的网站相关的React代码。
  • static/:这个目录用于存放静态资源,如图片、字体等。
  • docusaurus.config.js:这是您的Docusaurus站点的主要配置文件。
  • sidebars.js:文件负责自动生成和自定义侧边栏。

在本地运行

首先,运行 npm install 来安装所有所需的依赖项,然后启动你的开发服务器:

npm run start

这将编译所有Markdown和React文件,启动一个本地开发服务器(通常位于http://localhost:3000),并启用热重载以便立即更新。你应该可以在浏览器中看到默认的Docusaurus站点正在运行。

img

理解配置文件

我们将从探索docusaurus.config.js文件开始。这个文件作为你的Docusaurus项目的控制中心,你可以通过它调整站点的行为、外观和功能。让我们解析这个配置文件,并理解每一部分如何塑造你的文档的身份和用户体验。

在你的编辑器中打开docusaurus.config.js。你会看到如下结构:

const config = {
title: "My Site",
tagline: "Dinosaurs are cool",
favicon: "img/favicon.ico",
url: "https://your-docusaurus-site.example.com",
baseUrl: "/",
organizationName: "facebook",
projectName: "docusaurus",
onBrokenLinks: "throw",
onBrokenMarkdownLinks: "warn",
i18n: {
defaultLocale: "en",
locales: ["en"],
},
//...
};

export default config;

核心字段:

  • title:你的Docusaurus网站的标题。
  • tagline:您网站的简短标语或描述。
  • favicon:你的网站的favicon图标的路径。
  • url:您的网站将托管的URL地址。
  • baseUrl:您网站的基础URL路径(通常是/)。
  • organizationNameprojectName:这些用于 Docusaurus 的某些特性,比如编辑按钮。
  • onBrokenLinksonBrokenMarkdownLinks:这些控制Docusaurus如何处理损坏的链接。
  • i18n:该对象配置国际化(i18n)设置,如默认区域设置和支持的区域设置。

主题配置

themeConfig对象用于定义网站的外观和感觉。

const config = {
//...
themeConfig: {
image: "img/docusaurus-social-card.jpg",
navbar: {
title: "My Site",
logo: {
alt: "My Site Logo",
src: "img/logo.svg",
},
items: [
{
type: "docSidebar",
sidebarId: "tutorialSidebar",
position: "left",
label: "Tutorial",
},
{ to: "/blog", label: "Blog", position: "left" },
{
href: "https://github.com/facebook/docusaurus",
label: "GitHub",
position: "right",
},
],
},
footer: {
style: "dark",
links: [
{
title: "Docs",
items: [
{
label: "Tutorial",
to: "/docs/intro",
},
],
},
{
title: "Community",
items: [
{
label: "Stack Overflow",
href: "https://stackoverflow.com/questions/tagged/docusaurus",
},
{
label: "Discord",
href: "https://discordapp.com/invite/docusaurus",
},
{
label: "Twitter",
href: "https://twitter.com/docusaurus",
},
],
},
{
title: "More",
items: [
{
label: "Blog",
to: "/blog",
},
{
label: "GitHub",
href: "https://github.com/facebook/docusaurus",
},
],
},
],
copyright: `Copyright © ${new Date().getFullYear()} My Project, Inc. Built with Docusaurus.`,
},
prism: {
theme: prismThemes.github,
darkTheme: prismThemes.dracula,
},
},
//...
};
  • navbar:定义 logo、标题和导航项。
  • footer:设置样式、链接和版权声明。
  • prism:选择一个语法高亮主题。

预设和主题

Docusaurus 使用预设来打包插件和主题:

const config = {
//...
presets: [
[
"classic",
{
docs: {
sidebarPath: "./sidebars.js",
editUrl: "link/to/edit/page",
},
blog: {
showReadingTime: true,
editUrl: "link/to/edit/page",
},
theme: {
customCss: "./src/css/custom.css",
},
},
],
],
//...
};
  • docs:设置路径和侧边栏配置。
  • blog:配置博客功能。
  • theme:应用自定义CSS以进行精细调整的样式。

这是对docusaurus.config.js文件的快速概述。这个文件的优点是,你可以通过修改它来自定义你的文档的各种方面,而无需触及其他文件或编写额外的代码。例如,如果你更改titletagline为其他内容,它将更新首页和其他使用这些值的部分。以下示例演示了这一点:

const config = {
title: "Semaphore",
tagline: "Build, Test, Deploy - At Lightning Speed",
//...
};

这将更新首页的 titletagline,无需直接修改 src/pages/index.js

img

创建页面

Docusaurus允许您在src/pages目录中创建独立页面。这些页面与文档页面不同,可用于自定义内容,诸如主页、关于页面或您需要的任何其他静态内容。要创建一个新页面,请导航到src/pages文件夹。例如,如果您需要创建一个关于页面,您将在该文件夹内创建about.jsx文件。

touch src/pages/about.jsx

about.jsx文件添加内容:

import React from "react";
import Layout from "@theme/Layout";

function About() {
return (
<Layout title="About Us">
<div style={{ padding: "20px" }}>
<h1>About Us</h1>
<p>
Semaphore CI is a cloud-based continuous integration and delivery platform that accelerates software development. We help teams build test, and deploy code faster and more reliably.
</p>
</div>
</Layout>
);
}

export default About;

现在访问:http://localhost:3000/about

img

这段代码定义了一个简单的关于页面的React组件。来自Docusaurus的layout组件提供了网站的头部、尾部和其他布局特性。虽然使用Javascript/JSX创建页面很方便,你也可以选择使用Markdown或React MDX。

将页面添加到导航栏

要想通过导航栏访问 about 页面,你需要更新根目录中的 docusaurus.config.js 文件。

const config = {
//...
themeConfig: {
image: "img/docusaurus-social-card.jpg",
navbar: {
title: "My Site",
logo: {
alt: "My Site Logo",
src: "img/logo.svg",
},
items: [
{
type: "docSidebar",
sidebarId: "tutorialSidebar",
position: "left",
label: "Tutorial",
},
{ to: "/blog", label: "Blog", position: "left" },
// Add new Navlink here
{ to: "about", label: "About", position: "left" },
{
href: "https://github.com/facebook/docusaurus",
label: "GitHub",
position: "right",
},
],
},
//...
},
//...
};

这个配置在导航栏中添加了一个指向关于页面的链接。检查浏览器以查看更改。

img

创建文档页面

在Docusaurus中,文档内容通常位于项目的docs目录中。让我们通过删除docs文件夹中的默认文件来开始新的操作。接下来,我们将把导航栏中的Tutorial项重命名为Docs,以更好地代表一个真实的文档网站。打开docusaurus.config.js文件并找到themeConfig.navbar.items部分。更新docSidebar项的标签字段,从Tutorial改为Docs

const config = {
themeConfig: {
navbar: {
items: [
// ...
{
type: "docSidebar",
sidebarId: "tutorialSidebar",
position: "left",
label: "Docs",
},
// ...
],
},
},
};

要创建一个新的文档页面,请确保您位于 docs 文件夹中。创建一个新的 Markdown 或 React MDX 文件。以这个例子来说,我们创建一个名为 welcome.mdx 的文件:

touch docs/welcome.mdx

在你的文本编辑器中打开 welcome.mdx 文件,并添加以下内容:

---
id: welcome
title: 欢迎
description: 这是欢迎页面的描述
slug: /welcome
---

# 欢迎来到我的文档

这是我在Docusaurus中的第一个文档页面。

新的 welcome 页面链接将出现在文档的侧边栏中。您也可以在浏览器中导航至 localhost:3000/docs/welcome 来访问该页面。

docusaurus

理解文档页面的结构

Docusaurus 文档页面由两个主要部分组成:

  • 前言部分:被三个破折号(---)所包围的顶部区域。它包含了元数据,如独特的idtitle(标题)、description(描述)、slug(固定链接)以及关于页面的其他细节。这些元数据指导了Docusaurus如何生成侧边栏、页面标题、URL等。就像HTML中的<head>部分一样。这些元数据在渲染后的文档页面中是不可见的,但是被Docusaurus用来生成侧边导航栏、页面标题、URL和其他功能。
  • 主要内容:这里您可以使用Markdown语法撰写实际文档。在这里,您可以通过标题、代码块、图像来构建内容,并充分利用Markdown的表现力。

自定义文档页面

您可以使用各种前置字段自定义文档页面的行为和外观。例如,要更改侧边栏中页面的顺序,您可以使用 sidebar_position 字段:

---
id: welcome
title: 欢迎
description: 这是欢迎页面的描述
slug: /welcome
sidebar_position: 1
---

# 你的 Markdown 内容放在这里

设置 sidebar_position: 1 将会把页面移动到侧边栏的第一个位置。其他接受的前言字段包括:

  • sidebar_label: 这份文档在侧边栏导航中显示的标签。
  • hide_title:一个布尔标志位,用来隐藏文档页面顶部的标题。
  • pagination_label: 文档页面底部的分页导航标签。
  • custom_edit_url:自定义“编辑此页面”链接的 URL。
  • keywords:与文档相关的关键词数组,用于搜索引擎优化。
  • image: 文档的预览图或社交媒体缩略图可以使用的相对路径或URL。
  • hide_table_of_contents:一个布尔标志,用于隐藏该文档的目录。
  • toc_min_heading_level`:一个整数值(1-6),它指定要在目录中包含的最小标题级别。
  • toc_max_heading_level: 指定要包含在目录中的最大标题级别的整数值(1-6)。
  • pagination_next: “下一页”分页链接的标签。
  • pagination_prev: “上一页”分页链接的标签。

分组文档页面

在Docusaurus中,您可以通过在docs目录内创建一个子文件夹来对页面进行分组。假设您想创建一个包含“安装”和“集成”页面的“入门”类别。首先,在docs目录中创建子文件夹:

mkdir docs/getting-started

getting-started文件夹内创建一个名为_category_.json的JSON文件。这个文件定义了类别的侧边导航结构。添加如下内容:

{
"label": "Getting Started",
"position": 1,
"link": {
"type": "generated-index"
}
}

label 指定了类别名,而 position 决定了它在侧边栏中的顺序。link 字段为该类别创建了一个索引页面,列出了其所有页面。

将页面添加到分类

接下来,为这个类别创建页面:

touch docs/getting-started/installation.md docs/getting-started/integration.md

installation.md页面添加适当的前言内容:

---
id: installation
title: Installation
sidebar_position: 1
---

# Installation

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

integration.md中添加内容:

---
id: integration
title: Integration
sidebar_position: 2
---

# Integration

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

现在,这些页面将会被归纳到侧边栏的“入门”类别下,并且索引页将会列出它们。

img

在Docusaurus中使用React

Docusaurus 允许你直接在文档页面中嵌入 React 组件,这为你创建互动和动态内容提供了灵活性。这得益于 MDX(带有 JSX 的 Markdown),它允许你在 Markdown 文件中使用 JSX。这个功能在你想展示实时示例、抽象出重复代码或者为你的文档增加复杂交互性时特别有用。要在文档页面中使用 React 组件,保证你的文档文件格式是 .mdx 而不是 .md。在这个示例中,我们将创建一个名为 ColorBox 的基础组件。在项目的根目录中,导航到 src/components 文件夹(如果它不存在则创建它),然后创建一个 .js.jsx 组件:

mkdir -p src/components
touch src/components/ColorBox.jsx

向文件中添加内容:

import React from 'react';

const ColorBox = ({ color }) => (
<div
style={{
backgroundColor: color,
width: '100px',
height: '100px',
display: 'inline-block',
margin: '10px'
}}
/>
);

export default ColorBox;

您可以在 MDX 文件中使用这个组件。以下例子使用之前创建的 welcome.mdx 文件来进行演示:

---
id: welcome
title: 欢迎
description: 这是欢迎页面的描述
slug: /welcome
---

import ColorBox from '@site/src/components/ColorBox';

# 欢迎来到我的文档
这是我在Docusaurus中的第一篇文档页面。

<ColorBox color="red" />
<ColorBox color="blue" />
<ColorBox color="green" />

注:在import语句中的@site别名是Docusaurus中的一个特殊路径别名,它指向你的项目根目录。

在浏览器中,你应该会看到自定义组件随着Markdown内容一起渲染出来:

docusaurus

这种方法使您能够创建丰富且互动的文档,超越了静态文本和图像。您可以在文档页面中直接嵌入实时代码编辑器、交互式图表甚至小型应用程序。

专业提示:虽然React组件可以极大地提升你的文档质量,但要谨慎使用。对于简单的内容,简单的Markdown经常更易于维护且性能更好。将React组件保留给交互元素或复杂的视觉效果,这些是标准Markdown无法实现的。

版本控制文档

Docusaurus具有内置的文档版本控制支持,它允许您维护文档的多个版本,并向用户提供特定版本的内容。要启用版本控制,您首先需要配置您的Docusaurus项目以支持它。

打开 docusaurus.config.js 并更新它以包括版本设置。在配置文件的 docs 字段中添加以下内容:

const config = {
//...
presets: [
[
"classic",
{
docs: {
// ....
lastVersion: "current",
versions: {
current: {
label: "Next",
path: "next",
},
},
},
//...
},
],
],
//...
};

这个配置通过Next版本来设置版本控制,这是当前文档版本的默认标签。

要创建你的文档的初始版本,请运行以下命令:

npm run docusaurus docs:version 1.0.0

这将在新的 versioned_docs 目录内创建一个 version-1.0.0 目录,并在项目目录中创建一个 versions.json 文件。你应该有如下的文件夹结构:

my-docs/
├── docs/
│ └── ... # 当前文档文件
├── versioned_docs/
│ └── version-1.0.0/
│ └── ... # 为版本1.0.0复制的文档文件
├── versions.json # 版本控制的元数据文件
├── ...

创建新版本

要添加更多版本的文档,请使用新的版本号运行docs:version命令:

npm run docusaurus docs:version 1.1.0

这将在versioned_docs文件夹内创建一个名为version-1.1.0的新目录,并将docs目录中的文档文件复制到其中。新版本还会被添加到versions.json文件中。创建新版本后,您应该会看到更新后的文件夹结构如下:

my-docs/
├── docs/
│ └── ... # 当前文档文件
├── versioned_docs/
│ ├── version-1.0.0/
│ │ └── ... # 1.0.0版本的文档文件
│ └── version-1.1.0/
│ └── ... # 1.1.0版本的文档文件
├── versions.json
├── ...

你可以继续更新docs目录中的文档文件,当你准备创建一个新的版本时,只需要再次运行docusaurus的docs:version命令,并附上新的版本号即可。

管理版本

根目录中的versions.json文件包含有关您文档不同版本的元数据。它看起来像这样:

["1.0.0", "1.1.0"]

您可以手动编辑这个文件来按需添加或删除版本。

在导航栏中添加版本下拉菜单

设置版本控制之后,您可以更新 docusaurus.config.js 中的导航栏以显示版本下拉菜单。打开配置文件,在 config.themeConfig.items 中添加以下内容:

const config = {
//...
themeConfig: {
//...
items: [
// ...
{
type: "docsVersionDropdown",
position: "right",
},
],
},
//...
};

这将在导航栏中显示一个版本下拉菜单。

docusaurus

专业提示:如果你的文档很少更改,版本控制可能引入不必要的复杂性。在大多数情况下,维护一份最新的文档版本更为简单且更有效。

探索插件

Docusaurus 拥有一个兴旺的插件生态系统,这些插件可以扩展你的文档网站的功能。让我们来看一个在 Docusaurus 中集成翻译和国际化插件的例子。

翻译和国际化

Docusaurus内置了对国际化(i18n)的支持,允许您创建多语言文档网站。这个功能让您能够通过提供多种语言的翻译内容,接触全球观众。让我们在Docusaurus项目中设置和管理翻译。

配置区域设置

第一步是配置你希望你的文档网站支持的语言环境(语言)。打开 docusaurus.config.js 文件并找到 i18n 对象。默认情况下,它应该是这样的:

i18n: {
defaultLocale: 'en',
locales: ['en'],
},

要添加一种新的地区设置,例如法语(fr),更新地区设置数组:

i18n: {
defaultLocale: 'en',
locales: ['en', 'fr'],
},

翻译内容

在配置好区域设置后,你可以开始翻译你的内容。Docusaurus 期望将翻译放置在 project-root/i18n 文件夹内的特定目录结构中。在根文件夹中创建一个名为 i18n 的目录:

mkdir -p i18n

Docusaurus提供了一个命令行工具,您可以使用它来管理翻译。要从Markdown文档和React组件中提取可翻译的内容,请运行以下命令。

npm run write-translations

这个命令默认只会在i18n目录下生成英语(en)区域目录和可翻译的JSON文件。要指示命令生成法语区域或您指定的区域,您必须通过提供--locale标志来指定。例如,要生成法语(fr)区域,请运行:

npm run write-translations -- --locale fr

这将在i18n目录内生成一个包含可翻译文件的fr语言区域目录。你应该拥有如下的文件夹结构:

my-docs/
└── i18n
├── en
│ ├── code.json
│ ├── docusaurus-plugin-content-blog
│ │ └── options.json
│ ├── docusaurus-plugin-content-docs
│ │ ├── current.json
│ │ ├── version-1.0.0.json
│ │ └── version-1.1.0.json
│ └── docusaurus-theme-classic
│ ├── footer.json
│ └── navbar.json
├── fr
│ ├── code.json
│ ├── docusaurus-plugin-content-blog
│ │ └── options.json
│ ├── docusaurus-plugin-content-docs
│ │ ├── current
│ │ │ ├── version-1.0.0
│ │ ├── current.json
│ │ ├── version-1.0.0.json
│ │ └── version-1.1.0.json
│ └── docusaurus-theme-classic
│ ├── footer.json
│ └── navbar.json
//....

在locale的每个JSON文件代表了你的文档中的一个特定方面,你可以在其中手动翻译内容。例如,current.json文件负责翻译一般文本内容和UI元素,如网站的title(标题)、description(描述)和主题labels(标签)。而在i18n/fr/docusaurus-theme-classic目录下的navbar.jsonfooter.json分别负责翻译navbar(导航栏)和footer(页脚)的内容到法语。你可以浏览所有的JSON文件,并翻译尽可能多的方面,从而创建一个完全本地化的文档网站。

要翻译你的文档内容,你需要将文档内容从 docs 文件夹复制到 i18n/fr/docusaurus-plugin-content-docs/current/ 中。复制 docs 目录内的所有文件:

mkdir -p i18n/fr/docusaurus-plugin-content-docs/current
cp -r docs/* i18n/fr/docusaurus-plugin-content-docs/current/

复制之后,你需要手动将内容翻译成你所希望的语言,在这个例子中是法语。多语言设置的结构应该看起来是这样的:

my-docs/
└── i18n
├── en
│ ├── code.json
│ ├── docusaurus-plugin-content-blog
│ │ └── options.json
│ ├── docusaurus-plugin-content-docs
│ │ ├── current.json
│ │ ├── version-1.0.0.json
│ │ └── version-1.1.0.json
│ └── docusaurus-theme-classic
│ ├── footer.json
│ └── navbar.json
├── fr
│ ├── code.json
│ ├── docusaurus-plugin-content-blog
│ │ └── options.json
│ ├── docusaurus-plugin-content-docs
│ │ ├── current
│ │ │ ├── getting-started
│ │ │ │ ├── installation.md
│ │ │ │ ├── integration.md
│ │ │ ├── welcome.mdx
│ │ │ ├── version-1.0.0
│ │ ├── current.json
│ │ ├── version-1.0.0.json
│ │ └── version-1.1.0.json
│ └── docusaurus-theme-classic
│ ├── footer.json
│ └── navbar.json

要使翻译生效,您需要重启服务器并添加 --locale 标志。

npm run start -- --locale fr

现在,当你刷新浏览器时,在访问localhost:3000/fr/docs/next/welcome时你应该会看到类似这样的内容:

docusaurus

启用语言下拉菜单

配置了区域设置并提供了翻译之后,您可以在站点的导航栏中启用语言下拉菜单。打开 docusaurus.config.js 文件并找到 themeConfig.navbar.items 数组。添加以下条目:

const config = {
themeConfig: {
navbar: {
items: [
// ...
{
type: "localeDropdown",
position: "right",
},
],
},
},
};

这将在导航栏的右侧添加一个语言下拉菜单,允许用户在已配置的区域设置之间切换。

img

路由和URL结构

注意:国际化在开发环境与生产环境中的工作方式略有不同。在生产环境中,您可以无缝切换所提供的语言,而不会遇到任何问题。然而,在开发环境中,您需要在启动服务器时指定区域设置,并且一次只支持一种语言。这意味着,如果您在法语区域设置中启动开发服务器,然后切换到比如英语,您将会收到一个404错误。在生产环境中,这将不是问题,因为Docusaurus会自动处理译文的路由和URL结构。当用户从语言下拉菜单中选择不同的区域设置时,Docusaurus将加载相应的翻译内容,并更新URL以反映所选的区域设置。例如,如果用户访问英文网站(en)/docs/welcome URL,然后切换到法语(fr)区域设置,Docusaurus将加载welcome.mdx文件的法语翻译,并将URL更新为/fr/docs/welcome

关于插件的更多信息

早些时候,我们学习了如何利用定位插件,但这只是插件可以为您的Docusaurus站点做的事情的一小部分。 有大量有用的插件可以使事情变得更容易。 假设您需要将Google Analytics集成到您的项目中。 方法如下:

安装插件

首先,通过运行这个命令来安装所需的插件:

npm install --save @docusaurus/plugin-google-gtag

插件安装后,您可以在docusaurus.config.js文件中对其进行配置。查找预设数组并找到presets条目。然后在其中添加这个gtag配置:

const config = {
//...
presets: [
[
'classic',
/** @type {import('@docusaurus/preset-classic').Options} */

({
gtag: {
trackingID: 'G-999X9XX9XX',
anonymizeIP: true,
},
docs: {
sidebarPath: './sidebars.js',
lastVersion: 'current',
versions: {
current: {
label: 'Next',
path: 'next',
},
},
},
//...
}),
],
],
//...
};

请确保将 G-999X9XX9XX 替换为您实际的谷歌分析跟踪ID。anonymizeIP 选项通过在发送数据前匿名处理访问者IP地址来帮助保护隐私。谷歌标签在开发环境中被禁用。这种行为是故意的,以防止在您本地开发和测试网站时发送不必要的分析数据。谷歌标签将在生产环境中启用,您的网站应该能够收集分析数据。您可以使用 tagassistant.google 确认您的谷歌分析实施是否使用您的生产链接正确工作。

您可以从Docusaurus官方网站探索更多插件,以扩展您的文档网站的功能性和能力。

部署你的 Docusaurus 网站

在构建了你的文档网站之后,没有什么比看到它实际上线和运行更令人满意的了。Docusaurus 提供了一个命令行界面(CLI)来简化部署流程,使该过程变得直接明了。你还可以将你的站点部署到像 Vercel 或 Netlify 这样的云服务上,它们提供了额外的特性和便利性。

使用Docusaurus CLI进行部署

Docusaurus 包含一个内置的命令行工具,可以简化部署过程。使用 Docusaurus CLI 部署你的网站:

确保你的网站已构建并准备好部署。运行以下命令以创建一个适合生产的构建:

npm run build

这将在build目录中生成静态文件,这些文件可以由任何静态网站托管服务来提供。

为了确保一切按预期工作,请通过运行以下命令在本地测试您的构建:

npm run serve

这将启动一个本地服务器,您可以通过导航到提供的URL查看您的网站。确保检查所有页面和功能,以验证它们是否正常工作。

部署到云服务

为了更高的灵活性,可以将你的Docusaurus站点部署到像Vercel或Netlify这样的云服务上,它们提供了与Git的无缝集成和自动化部署工作流。请跟随它们的设置指南进行操作。

专业提示:修复你的Docusaurus项目中的断链,以防止部署失败。

在本教程的前面部分,我们删除了docs目录中的所有默认文件和文件夹。这可能导致了链接断裂,特别是那些指向docs/intro的引用。为了确保部署顺利进行:

  1. 打开 docusaurus.config.js文件
  2. 导航到 `config.themeConfig.footer.links.items
  3. 删除或替换 /docs/intro 为一个有效链接,或者使用相对路径 /
const config = {
//...
themeConfig: {
footer: {
style: "dark",
links: [
{
title: "Docs",
items: [
{
label: "Tutorial",
to: "/docs/intro", // Resolve this broken link
},
],
},
//...
],
},
},
//...
};

重复此过程,针对 src/pages/index.js 文件,更新任何类似的引用。

总结

我们在本指南中覆盖了很多内容。我们涉及了初始化新的Docusaurus项目、创建文档、版本控制、集成插件、部署Docusaurus网站等关键概念。构建文档网站并非简单任务,但Docusaurus之类的工具通过提供流线型工作流程和开箱即用的核心特性,将许多复杂性从方程中去除了。虽然本指南旨在提供坚实的基础,但Docusaurus仍有更多可以探索的内容。通过Docusaurus广泛的插件和主题生态系统,有无限的自定义可能性。

请随意克隆我的工作仓库,在这里并行操作新的、逐步提供的教程。如果有任何问题/需要澄清的地方或者发现了bug,请随时联系我!