跳到主要内容

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

· 阅读需 23 分钟

翻译自: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

· 阅读需 6 分钟

翻译自: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的新应用商店

· 阅读需 4 分钟

翻译自: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正在革新人工智能工具

· 阅读需 8 分钟

翻译自: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构建现代化文档网站

· 阅读需 26 分钟

翻译自: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 © 2007-${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,请随时联系我!