news 2026/9/20 6:05:04

LibreChat部署实战:用Docker Compose搭建多模型AI聊天聚合平台

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LibreChat部署实战:用Docker Compose搭建多模型AI聊天聚合平台

1. LibreChat是什么:一个把多家大模型服务收进同一聊天窗口的开源客户端

如果你手里同时握着OpenAI、Anthropic、Google、Groq还有本地Ollama的API Key,每天切换网页、切来切去,一定会觉得特别割裂。更别提团队协作的时候,每个人都有自己的本地对话记录,想共享一个上下文都难。

LibreChat解决的就是这个事。它是一个开源的AI聊天客户端,不是模型本身,而是把所有你能调用的模型服务统一放到一个聊天窗口里。你可以像在ChatGPT官方界面里一样新建会话、切换模型、管理历史记录,但背后实际去调用的,是你自己配置好的各家API或自托管模型。

我最早接触LibreChat是在找能替代ChatGPT网页版的工具时,当时它的Star数还没现在这么夸张。用了一段时间后,我确定它就是我要找的那个“聚合聊天面板”:一方面它支持OpenAI、Anthropic、Google Gemini、Mistral、Groq、Ollama等一堆来源,另一方面它自带用户注册登录、对话管理、Token用量统计、团队算力池这些功能,连多模态图片输入、文件上传、Web搜索这类细节也有覆盖。

适合谁来用?范围其实挺宽:个人开发者想统一管理自己的API Key;小团队想搭一个内部共享的AI问答平台,但不想自己开发前端;企业想先用开源方案跑通场景,验证之后再决定要不要上商业化产品;甚至你只是有几个不同的模型订阅,也想把对话历史集中管理,LibreChat都能应付。

这个项目最吸引我的还不是功能列表,而是它的形态:一个可以完全自托管的AI聊天入口,数据在自己的服务器上,模型服务自己指定,界面想改就改,后端是Node.js加MongoDB,前端是React,整个项目的可定制程度非常高。换个直白点的说法,LibreChat相当于你给自己搭了一个“AI聊天中台”,想接谁就接谁,想给谁用就给谁用。

2. 场景拆解:谁需要它、哪些场景真正派得上用场

LibreChat不是那种“看起来很酷但实际用不上”的开源项目,它在真实场景里能解决不少让人头大的问题。我把用过的场景拆成几类,你对照看看自己是不是也有类似需求。

2.1 多模型统一管理:不再被单一模型绑定

现在做AI应用开发的人,手头往往不止一个模型账号。OpenAI的GPT系列适合通用对话和代码生成,Claude在长文档理解上表现突出,Gemini在多模态场景更方便,Groq适合需要低延迟的实时问答,而本地跑的Qwen、Llama则用于离线或隐私敏感的数据处理。

过去我是在哪个网页就开哪个网页,后来干脆写了脚本调API。但脚本只能解决批量调用的问题,日常想要对比几个模型的回答、在同一个上下文里切换模型,就非常不方便。LibreChat把这一切放进了同一个界面,你可以在一个会话里随手切到另一个模型继续聊,历史记录不断开。这种体验对日常做模型评测的人尤其重要,我试过在同一段需求上让三个模型分别回答,再复制到表格里挑选,效率比之前高了太多。

2.2 团队共享与权限隔离:一条部署,全员使用

如果你在一个小团队或者工作室里,经常有人问“这个Prompt怎么调”“这个需求怎么让AI帮忙写”,你会发现自己反复复制粘贴同一段对话,既浪费时间又没法沉淀知识。

LibreChat自带用户系统,管理员可以控制用户注册开关,团队成员各自登录后使用默认分配或自己配置的模型。它还有一个比较实用的设计:Token用量按用户统计,管理员能看出谁在用、用了多少、主要花费在哪些模型上。这种“能协作、能计量、能控制”的能力,让LibreChat不止是个人的玩具,而是可以真的拿到团队环境中当生产力工具的。

我见过有朋友的创业公司直接把LibreChat部署到内网服务器,让客服、运营、市场部门各用各的模型,再配一个公共的Prompt模板,整个团队的AI使用效率提升非常明显。比较关键的是,数据都留在自己服务器上,不会经过第三方平台。

2.3 多供应商API聚合:让每一次调用都合理

聚合的价值不光在“省事”,还在于你可以针对不同任务类型选择不同价格的模型。LibreChat支持为不同用户组配置不同的模型列表和额度限制,比如日常简单问答分配给便宜的小模型,复杂的代码任务才允许使用更高端的模型。这样的配比能让整体的API成本明显降下来。

我在生产环境里试过给客服团队配Groq的免费模型,给研发团队配Claude,实测效果是既控制住了预算,又保证了关键任务的输出质量。这种“按角色配模型”的设计,很多商业SaaS都不一定提供,而LibreChat直接支持。

2.4 隐私优先与本地化部署:数据留给自己

有些项目的对话内容涉及内部代码、客户数据,不能发到别人的服务器上。LibreChat部署在自建服务器后,所有对话数据都存在你自己的MongoDB里,API调用是你服务器直接发到模型服务商,前端只跟你的后端通信。这意味着除了你主动接的模型服务商,其他人拿不到你的数据。

我还用过它配合Ollama做纯本地推理,整个链路不跨出内网,敏感数据完全不出环境,这在某些行业场景里是硬性要求。LibreChat的有趣之处就在这里——同一个项目,既能接入云端大模型,也能切到本地模型,灵活度非常高。

3. 部署前的准备:容器方案与关键前置信息

LibreChat的部署方式有不少,官方文档推荐Docker Compose,这也是我实际用下来最省心的方式。相比裸装Node.js和MongoDB,Docker Compose把整个应用栈打包到一起,启动、更新、迁移都比较干净。

3.1 为什么推荐Docker Compose

LibreChat依赖的组件包括:Node.js后端服务、MongoDB数据库、可能的Redis(用于部分协作场景),以及反向代理(Nginx/Caddy,可选的HTTPS方案)。如果全部手工安装,要处理Node版本、MongoDB鉴权、端口冲突等一堆问题,第一次部署少说要折腾两小时。

而Docker Compose只需要一份docker-compose.yml文件,里面定义好所有服务,一条docker compose up -d就全部起来。更新版本时,拉取新镜像再重建容器即可,比升级Node进程省心多了。

我自己实测,在2核4G的云服务器上跑LibreChat,日常几个人使用完全够用。如果团队人数多,建议上到4核8G,同时给MongoDB挂个独立数据盘,避免容器重建时数据丢失。

3.2 部署前需要准备的东西

动手之前,先把下面的信息备齐,不然启动后会来回折腾:

  • 一台能跑Docker的Linux服务器或本地开发机,建议Ubuntu 22.04以上系统,预装Docker和Docker Compose插件。
  • 至少一个模型API Key。OpenAI、Anthropic、Google之类的都行,如果暂时没有,本地装Ollama也能先跑通流程。
  • 一个域名和HTTPS证书属于可选,但如果要给团队外网使用,强烈建议配上,否则浏览器会警告不安全连接,部分浏览器还会限制剪贴板等功能。
  • 服务器防火墙需要放行80/443端口,或者你自定义的映射端口。

3.3 获取LibreChat项目文件

部署的第一步是拿到项目文件。LibreChat官方仓库提供了docker-compose.yml和对应的环境变量示例,我建议用官方仓库里的配置做基础,不要自己从头写,因为里面还包含了Meilisearch搜索服务、RAG API等可选组件,直接从示例上删改会比自己摸索更快。

git clone https://github.com/danny-avila/LibreChat.git cd LibreChat cp .env.example .env

复制好环境变量文件后,先不要急着启动,LibreChat的环境变量比较多,需要把最关键的几个配置好。

4. 基于Docker Compose的完整部署流程

4.1 理解环境变量的核心逻辑

LibreChat的环境变量文件(.env)是整个配置的中枢,几乎所有功能开关都在这里。初次使用不需要把每个变量都搞懂,先把下面几个配置明白,服务就能跑起来。

# 基础配置 ENDPOINTS=/api/chat,/api/completions ALLOW_REGISTRATION=true ALLOW_SOCIAL_LOGIN=false # MongoDB连接 MONGO_URI=mongodb://mongodb:27017/LibreChat # JWT密钥,用于用户登录状态加密 JWT_SECRET=your_random_secret_here CREDS_KEY=another_random_32_byte_hex CREDS_IV=another_random_16_byte_hex # 各模型服务商的API Key OPENAI_API_KEY=sk-xxxxx ANTHROPIC_API_KEY=sk-ant-xxxxx

这里有几个容易踩坑的地方。JWT_SECRET是保证登录安全的关键,如果不设置或设置得太简单,别人只要拿到你的服务地址,就可能伪造登录令牌。CREDS_KEY和CREDS_IV分别需要32字节和16字节的十六进制字符串,用来加密用户的第三方API Key配置,偷懒不配的话,用户自定义API Key的功能会报错。

MongoDB连接串里的mongodb是服务名,不是IP地址。因为在Docker Compose网络里,服务之间通过服务名互相访问。如果你把这行改成localhost,容器内部找不到数据库,应用就会反复重启。

4.2 修改docker-compose.yml中的必要项

官方默认的docker-compose.yml里,LibreChat服务会映射3000端口到宿主机。如果你不想直接用3000端口,可以改成其他端口:

services: api: image: ghcr.io/danny-avila/librechat:latest ports: - "3080:3080"

我习惯把宿主机端口改成3080,避免和本地的其他Node服务撞上。改完端口后,访问地址就变成http://服务器IP:3080。

如果要用Nginx做反向代理并配置HTTPS,LibreChat仓库里还有对应的Nginx示例配置文件,把server_name改成你的域名,再挂上证书路径就能用。我这里先用简单的方式,直接通过IP加端口访问。

4.3 一条命令启动服务

配置文件准备好后,启动服务:

docker compose up -d

第一次启动会拉取镜像,耗时取决于服务器网络和镜像大小,一般5到10分钟。拉取完成后,查看容器状态:

docker compose ps

只要api容器显示Up状态,MongoDB和Meilisearch也正常运行,就说明服务已经起来了。打开浏览器访问http://服务器IP:3080,应该能看到LibreChat的登录页面。

如果页面迟迟打不开,先排查容器日志:

docker compose logs api --tail=100

最常见的启动失败原因是环境变量有问题。比如MONGO_URI写错、JWT_SECRET缺失、格式不对,日志里都会打出具体的错误信息,根据提示一一修正再重启即可。

4.4 初始化管理员账号

LibreChat默认允许注册,第一个注册的用户可以通过环境变量或MongoDB操作提升为管理员。更简单的做法是注册第一个账号后,进入MongoDB容器手动赋予管理角色:

docker exec -it librechat-mongodb mongosh "mongodb://localhost:27017/LibreChat" db.users.updateOne({ email: "你的注册邮箱" }, { $set: { role: "ADMIN" } })

执行成功后,刷新页面重新登录,这个账号就能进入管理员面板,看到用户列表、会话日志、Token使用统计等信息。

5. 模型服务接入与聚合配置详解

服务跑起来后,最关键的一步就是把模型接入进来。LibreChat支持两种接入方式:后端统一配置和用户自定义API Key。

5.1 后端统一配置多供应商

在.env文件里配置的API Key是全局生效的,团队所有用户共享同一个后端Key,用完后统一在管理员面板里看用量。

我常用的几种配置方式:

# OpenAI OPENAI_API_KEY=sk-xxxxx # Anthropic Claude ANTHROPIC_API_KEY=sk-ant-xxxxx # Google Gemini GOOGLE_API_KEY=AIzaXXXX # Groq(提供免费额度的快速推理服务) GROQ_API_KEY=gsk_xxxxx

配置完重新加载环境变量并重启容器:

docker compose --env-file .env up -d

重启后,前端模型选择器里会出现对应提供商的默认模型列表。OpenAI一般自动列出GPT系列,Anthropic列出Claude系列,Groq列出Llama和Mixtral等模型。

5.2 自定义模型列表:让模型选择器更贴合需求

默认的模型列表是LibreChat根据服务商API接口自动拉取的,但如果你只想开放几个特定模型,可以在librechat.yaml文件里自定义模型配置。

在项目根目录创建一个名为librechat.yaml的文件,内容类似这样:

version: 1.0.4 endpoints: - name: openai apiKey: ${OPENAI_API_KEY} models: - name: gpt-4o supportsVision: true - name: gpt-4o-mini supportsVision: true

这个配置告诉LibreChat只开放gpt-4o和gpt-4o-mini两个模型,即使你的OpenAI账号有更多模型权限,用户在界面上也看不到。这样做的意义是控制成本,避免用户不小心选到那些价格很高的模型导致账单炸掉。

同样的方式可以配置Groq只开放空闲的免费模型,Claude只开放主力模型等。模型配置粒度非常细,还可以设置并发限制、上下文长度覆盖等参数。

5.3 本地模型接入:用Ollama跑通离线链路

如果你想让对话数据完全不发到外部服务,本地模型是唯一的方案。LibreChat对Ollama的支持很成熟,只需要在.env里配置Ollama服务的地址:

OLLAMA_BASE_URL=http://host.docker.internal:11434

宿主机安装Ollama后,先用ollama pull qwen2.5:7b拉取模型,然后在LibreChat的模型选择器里选择Ollama分组下的模型就能对话。

需要注意的是,Ollama默认只监听127.0.0.1,Docker容器里的LibreChat访问不到宿主机。需要先设置环境变量让Ollama监听所有网卡:

OLLAMA_HOST=0.0.0.0

再重启Ollama服务。Windows和macOS的Docker Desktop支持host.docker.internal这个特殊域名,Linux下需要在docker-compose.yml的api服务里加一行extra_hosts配置,手动映射host.docker.internal到宿主机IP。

我自己的经验是,7B级别的本地模型跑常规问答、总结、改写完全够用,延迟也能控制在可接受范围内。但做复杂推理或长文本分析时,质量跟云端大模型还是有明显差距。

5.4 用户自带Key模式:适合个人用户和团队内部分摊成本

LibreChat还允许每个用户在设置里填写自己的API Key,这样后端就不需要配置全局Key。这种模式的好处是每个用户用自己的账号计费,不会出现“一个人把团队预算全烧光”的情况。

要开启这个功能,需要在.env里设置:

ALLOW_OPENAI_API_KEY=true ALLOW_ANTHROPIC_API_KEY=true

开启后,用户登录进入设置页面,会看到API Key的输入框。填好保存后,对话请求就会走用户自己的Key。

这里有一个细节要说一下:用户填入的Key会用部署时配置的CREDS_KEY和CREDS_IV做加密存储,不是明文存放在数据库里。但加密密钥就在服务器的.env文件里,所以服务器管理员理论上可以解出来。如果你所在环境对Key安全要求极高,这个方案要谨慎使用。

6. 多用户管理与团队协作配置

LibreChat在多人使用场景下的功能设计,是我认为它区别于其他开源聊天客户端最大的优势之一。这里我挑几个实际用得上的功能详细讲讲。

6.1 用户注册控制与权限分级

默认配置下,任何人都能注册并登录你的LibreChat实例。如果是个人使用或内部团队,建议关闭开放注册:

ALLOW_REGISTRATION=false

关闭后,只有管理员才能在后台手动创建用户。管理员登录后,进入Admin面板的Users标签页,可以一键添加新用户并分配密码。

用户角色分为USER、ADMIN等几个级别。ADMIN可以查看所有人的会话记录和用量数据,USER只能看自己的对话。我用下来的体验是,给团队负责人的账号开成ADMIN,方便他掌握整个团队的AI使用情况。

6.2 对话分享与协作:把AI上下文变成团队资产

LibreChat支持把某条对话生成一个可分享的链接,通过这个链接,其他人可以直接看到对话内容和过程。实测这个功能对团队协作特别有用。

以前我们经常遇到一个情况:运营同事让AI写了一段文案,觉得效果不错,想分享给设计同事参考,结果是直接把那一大段文字复制到聊天软件里,不仅格式乱,还没有上下文。用LibreChat的分享功能,对方打开链接就能看到完整对话,还能继续在此基础上提问或复制其中的某段内容。

分享链接默认只有知道的人能访问,不需要对方注册登录。这在跨部门协作时很省事,不用为了一次性查看就单独创建账号。

6.3 Token用量统计:让成本透明起来

管理员面板里有Token使用统计和每个用户的用量排行。我可以看到过去一周里,哪个模型消耗了多少Token、哪个用户的调用量最大、平均每轮对话的成本是多少。

这些数据对预算控制很有价值。我记得有一次发现某个团队成员的用量异常高,点进详情一看,是他在用Claude Sonnet批量处理数据,每次都是超长的Prompt。后来给他单独配了便宜模型作为默认,问题就解决了。没有用量统计的话,这种成本黑洞很难及早发现。

7. 常见问题排查与避坑记录

部署和使用LibreChat的过程中,我踩过不少坑,大部分问题其实网上都能搜到,但很多答案都是只言片语,不够完整。这里把我遇到过的典型问题整理成一份速查表,尽量做到看到现象就知道怎么处理。

7.1 启动类问题

现象可能原因处理方法
容器反复重启MONGO_URI配置错误检查是否用了服务名mongodb而不是localhost
报错JWT_SECRET未设置环境变量缺失在.env中填入随机字符串
Meilisearch启动失败端口冲突修改docker-compose.yml中该服务的端口映射
页面502错误Nginx配置未指向api服务检查proxy_pass是否指向正确端口

最常见的还是MONGO_URI的问题。很多人第一次部署,习惯性地把localhost当作数据库地址,但容器里的localhost指向的是当前容器自己,不是宿主机,更不是MongoDB容器。这里必须写成mongodb服务在Compose网络中的服务名。

7.2 模型调用类问题

模型接入后没法对话,这类问题比较让人着急,因为界面看起来一切正常,但一发送消息就报错。

遇到这类情况,第一反应应该是查看api容器的日志:

docker compose logs api --since 5m

日志里会明确告诉你调用哪个服务商时失败,以及失败的具体原因。常见的错误有:

  • 403 Forbidden:API Key无效或者没有对应模型的权限。检查.env里填的Key是否正确,注意有些服务商区分ANTHROPIC_API_KEY和ANTHROPIC_AUTH_TOKEN,填反了就会这样报错。
  • 404 model not found:模型名称写错了。在界面上你看到的模型名是LibreChat映射过的别名,实际请求可能被映射到别的名称,去librechat.yaml里核对一下模型定义。
  • 429 Rate Limit:触发限流。可能因为某一段时间内请求太密集,也可能是免费额度用完。暂时不处理也行,等一段时间会自动恢复,但如果持续出现,需要检查是否有人写了一个并发循环在调用。
  • 超时无响应:请求后端模型或Ollama时,如果模型推理时间过长,会超过默认的超时阈值。在librechat.yaml里可以给该endpoint配置timeout参数,适当调大。

7.3 数据库与备份问题

MongoDB里存放着用户账号、会话记录等所有数据。容器一旦被删除或者重新创建,如果数据没有挂载到宿主机的Volume里,数据就全没了。

官方docker-compose.yml里一般已经定义了Volume映射,但我见过有人为了调整数据库存储位置,手动修改了路径,导致数据丢失。我的建议是:

  • 不要频繁删除MongoDB容器,需要升级时只升级api和应用服务,MongoDB保持原样。
  • 定期用mongodump做数据备份,至少保留最近一周的备份文件。恢复时用mongorestore命令一键还原。
  • 升级LibreChat之前,先看一眼Release Note,有些版本需要执行数据库迁移脚本,直接拉最新镜像可能会因为数据库结构不匹配而启动报错。

7.4 安全加固的几个细节

LibreChat默认不带HTTPS,直接暴露IP加端口的话,用户名密码都是明文传输,在内网用问题不大,但一旦暴露到公网就非常危险。以下是我实际用下来觉得必须做的事:

  • 用Nginx或Caddy做反向代理,加上HTTPS证书。Caddy可以自动申请Let's Encrypt证书,配置更简单。
  • 设置ALLOW_REGISTRATION=false,只允许管理员创建用户,避免陌生人注册进来乱用你的API额度。
  • 如果不需要用户自定义API Key功能,就关闭对应的开关,减少Key泄露面。
  • 定期更新镜像,关注官方安全公告,及时修补已知漏洞。

8. 一些实用心得与后续扩展思路

LibreChat能做的事情不止是“把几个模型放一起”,它的扩展能力比大多数人想象的都要大。有些玩法你可能暂时用不上,但了解一下没坏处。

8.1 把LibreChat接进现有的工作流

LibreChat提供了标准的API接口,可以被其他程序调用。也就是说,你完全可以在自己的脚本或自动化工坊里,把LibreChat当成一个统一的大模型网关,通过它调用不同类型的模型。这样做的好处是,API Key不用散落在各个脚本里,而是统一由LibreChat管理,程序只需要请求LibreChat的接口即可。

我用这个方式做了个小工具:把公司内部的工单系统接入LibreChat,让AI先根据历史工单生成初步回复建议,再由人工审核确认。因为LibreChat已经把模型密钥、用户权限、用量统计都处理好了,工具本身的开发成本非常低。

8.2 用RAG功能让AI基于自己的资料回答

LibreChat带了RAG API,可以把文档上传后建立索引,让对话基于你的资料库进行回答。我试着把团队的操作手册和技术文档投进去,效果还是比较满意的。文档更新后重新上传一遍,回答内容就会同步更新。

这个方案对比独立的RAG服务(比如Dify),优点是不用多维护一套系统,LibreChat本身已经带了这个能力;缺点是目前RAG的调优空间有限,复杂的文档分块和排序策略还是稍微弱一些。如果你的需求只是“让AI会背团队文档”,LibreChat的RAG完全够用。

8.3 最后的两个实用小技巧

第一,LibreChat支持在对话中直接上传图片,配合支持视觉的模型可以进行多模态对话。比如把一张设计稿发过去,让AI给出修改建议,或者把一张截图丢过去,让它读里面的文字,这些场景我经常用到。

第二,管理员可以在设置里调整全局Prompt模板,给所有用户预设一个系统提示词。我在团队部署时,把“必须用中文回答,回答要简洁,结论先行”写进全局Prompt里,整队的使用体验统一了很多。这个设置用好了,会让你的LibreChat看起来更专业可信。

根据我的经验,LibreChat这类聚合客户端的核心价值不在于某一个模型的能力,而在于“统一入口、按需选择、全程可控”这套工作方式。如果你本身就是重度AI用户,或者要负责给团队搭一个共享的AI平台,花一个晚上把它部署起来,之后每一天都能省下不少折腾的时间。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 6:04:45

编码 Agent 脱离编辑器:本地优先工作台实战指南

写这篇文章的起因,是我最近把自己常用的编码 Agent 从编辑器里真正“搬”了出来——不是换个插件,而是让它以独立进程的方式跑在项目旁边,和我的文件系统、终端、浏览器并行工作。结果发现,原来习惯了编辑器内那种“边聊边改”的体…

作者头像 李华
网站建设 2026/9/20 6:03:42

手机中框制造工艺与缺陷解决方案详解

1. 手机中框制造工艺全景解析手机中框作为连接屏幕与后盖的核心结构件,其制造工艺直接决定了整机的结构强度、散热性能和外观质感。当前主流工艺路线主要分为三大类:金属一体化CNC加工:采用6系/7系航空级铝材,通过20余道工序铣削成…

作者头像 李华
网站建设 2026/9/20 6:03:24

STM32指纹考勤机开发实战:从硬件选型到数据存储与串口通信

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/20 6:03:21

ESP-IDF ESP-BLE-MESH 完整特性清单与最小上手路径

ESP-IDF ESP-BLE-MESH 完整特性清单与最小上手路径 【免费下载链接】esp-idf Espressif IoT Development Framework. Official development framework for Espressif SoCs. 项目地址: https://gitcode.com/GitHub_Trending/es/esp-idf ESP-BLE-MESH 是 ESP-IDF 内置的蓝…

作者头像 李华
网站建设 2026/9/20 6:01:14

AI与自动化:核心差异、技术实现与应用场景解析

1. 概念界定与核心差异人工智能(AI)和自动化这两个概念经常被混为一谈,但它们在技术实现和应用逻辑上存在本质区别。自动化更像是"固定流程的机械执行",而AI则是"具备学习能力的智能决策"。举个生活中的例子&…

作者头像 李华
网站建设 2026/9/20 6:00:08

SwiftUI重构Homebrew:macOS原生包管理GUI实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华