news 2026/10/3 3:23:48

搭建AI编程基础设施:统一管理多模型API与上下文的实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
搭建AI编程基础设施:统一管理多模型API与上下文的实践

最近把小半年散的 AI 编程工具整理成了一套统一的基础设施。以前写代码的时候,这边开一个 ChatGPT,那边开一个 Claude,本地终端还挂着 DeepSeek 的 API,遇到要切换供应商就得重新配环境变量,配完 key 又得重启终端,折腾几次我就放弃了。这周终于把 cc-switch 和 sdcb/chats 这两块补上了,整个工作流才算真正顺起来。

这套东西不复杂,但确实解决了我自己的真实问题:把多个大模型供应商、多个 API Key、多个工作场景统一到一个入口里,让「用哪个模型写代码」变成一次切换,而不是一场配置灾难。cc-switch 负责账号和供应商配置的集中管理与快速切换,sdcb/chats 负责提供一个轻量的网页对话前端,把所有模型会话统一收口。两套工具配合起来,基本就是我日常的 AI 编程基础设施底座了。

这篇就记录一下我自己的搭建过程、踩坑记录,以及在团队协作、成本控制、上下文管理这几个实际场景里的处理方式。我不打算写成像文档那样的长篇说明,更多是站在「自己真正用下来」的角度,把值得注意的地方讲清楚。如果你也同时用很多家大模型 API,或者你团队里有人天天在各种供应商之间来回切,这套思路值得参考。

1. 整体设计思路:为什么需要一套 AI 编程基础设施

1.1 痛点其实不在模型,而在配置和上下文

很多人以为「AI 编程」的问题在于哪个模型更强,但实际用起来会发现,模型之间的差距远没有「切换成本」对你工作效率的杀伤力大。你今天用 Claude 写架构,明天用 DeepSeek 做批量重构,后天用 GPT 跑一轮代码 review,如果每个场景都要打开不同网站、登录不同账号、复制不同 key,那你每天真正花在写代码上的精力就被切得七零八落。

我第一次意识到这件事,是在一个项目里同时接了三家大模型的服务。每换一家,我都要去改环境变量、重启终端、重新加载会话,最离谱的是有几次改完配置之后,之前和模型对话的上下文全找不回来了。那种感觉就是:工具越多越乱,最后反而比不用 AI 的时候效率更低。

所以我要搭的这套基础设施,核心目标只有两个。第一个是「配置集中」,所有供应商的 API Key、Base URL、模型名,都由一个统一的地方管理,切换供应商只需要一条命令或者点一下界面。第二个是「会话统一」,不管底层用的是哪个模型,所有对话都沉淀在同一个前端里,会话历史、上下文、当时的代码片段都能按项目回查。cc-switch 解决第一个问题,sdcb/chats 解决第二个问题。

1.2 组件职责划分

这套架构里,我刻意把「配置」和「对话」拆成了两层。这是为了将来扩展方便:如果哪天换了一个更好用的对话前端,配置层完全不用动;如果某家供应商把接口协议改了,也只影响配置层,会话历史不会丢。

  • cc-switch 这一层:负责供应商、API Key、模型参数的管理。它本质上是一个配置切换器,把「当前该用哪家模型、哪个 Key」这件事从人肉记忆变成程序化管理。
  • sdcb/chats 这一层:负责对话。它提供网页界面,支持多个模型供应商接入,所有聊天记录、上下文、提示词模板都存在这边。
  • 中间的联动:cc-switch 切换结果要能同步给 chats,或者两者共享同一份配置源。我实际用的是环境变量文件统一注入的方式,一会儿在实操部分详细说。

为什么选这两个项目而不是直接用各家官方客户端?原因很简单:官方客户端只能连自家的服务,没法做到「一个界面、所有模型」。而市面上很多聚合客户端要么太重,要么部署复杂,sdcb/chats 属于轻量、配置直观、能直接吃 OpenAI 兼容协议的那类,正好满足我的需求。cc-switch 在切换配置这件事上做得够聚焦,没有多余的功能,合我的脾气。

1.3 这套方案的适用范围与边界

我得先说清楚,这套东西不是给所有人用的。如果你只是偶尔用一下 AI 聊天,或者只在官方网页版里点点点,那完全没必要上基础设施,直接用网页版反而省事。如果你像我一样,日常要写大量代码、要在多个模型之间做对比、要管理好几个 API Key,甚至要带着团队一起用,那这套东西的价值就非常明显。

还有一个现实问题需要提前讲:成本。多家供应商意味着多个计费通道,如果不对用量做统一管理,月底账单出来的时候你可能会吓一跳。文末我会专门写一节「成本控制」相关的实操,把我在实际中用的方法列出来,包括怎么设预算、怎么追踪每个项目的花费、怎么让团队成员的 Key 不裸奔。这些都是搭建过程中绕不开的事。

2. cc-switch 配置中心:实现供应商与密钥的统一管理

2.1 安装与初始化

我接触的 cc-switch 版本,常见的分发方式包括 npm 包和 Docker 镜像两种。我个人的建议是:如果你只是本机单人在用,用命令行版本就够了,装起来快,切起来也顺手;如果你要在团队里共享一套配置,或者你有多台机器,直接上 Docker 方式,把配置目录挂出来,所有成员共用一个配置源。

以命令行版本为例,安装之后第一件事是初始化配置目录。它会生成一个默认的配置文件,里面预置了 OpenAI 兼容协议的标准字段,比如base_url、api_key、model这些。你可以把各家供应商理解成一个个「配置档位」,每个档位包含三样东西:连到哪、用什么身份连、默认用哪个模型。

初始化完成后,我习惯先做一次自检,用命令列出当前已经存在的配置档,确认配置文件格式没问题。这一步看起来多余,但实际很关键,因为很多后续问题(比如切换后不生效、上下文加载不出来)追根溯源都是初始化没做好,配置路径不对或者文件权限有问题,后面修起来反而更花时间。

2.2 多供应商接入与字段解析

接入供应商的时候,我见过很多人直接照搬官方文档里的 Base URL 就填进去了,结果请求一直报错。这里有个核心概念需要理解:几乎所有流行的大模型厂商都提供了 OpenAI 兼容的接口,所以你只需要把每个厂商的 Base URL 填成它自己的地址,剩下的请求格式都一样。

举几个我实际用过的例子:

  • Anthropic 系的服务,如果你通过兼容层暴露出来,那 Base URL 会指向兼容层的地址,而不是原生的 Anthropic API;
  • DeepSeek、智谱、Kimi 这些国内可以直接访问的服务,它们的 Base URL 相对直观,直接填官方提供的地址就行;
  • 如果你用 OpenRouter 这类聚合网关,那它一个 Base URL 背后可以路由到几十个模型,这时候你只需要把 key 换成 OpenRouter 的 key,模型名换成目标模型就行。

这里有一个容易踩坑的点:模型名千万别写错。不同供应商对同一个模型的命名可能不一样,甚至同一家的新旧版本之间都会有细微差别。我在配置的时候通常会先单独用一行 curl 或者一个最小脚本测一下,确认这个模型名称真的能返回结果,再写进配置档。否则你配置界面看起来一切正常,一发起对话就给你报 model not found,排查起来一头雾水。

2.3 API Key 安全管理

API Key 是整个配置中心里最敏感的东西,怎么强调安全都不过分。我见过有人直接把 key 写进配置文件然后提交到 Git 仓库,结果把密钥泄露到了公司内部的代码库,最后只能一个个重新生成所有的 key,极其痛苦。

我现在用的是这么一套方案:cc-switch 的配置模板里不写真实 key,而是引用本地环境变量。具体做法是,在配置文件里填${OPENAI_API_KEY}这类占位符,真实值放在本机单独的环境变量文件里,而那个文件被.gitignore忽略掉。切换供应商时,cc-switch 只负责切换配置档,真实 key 从环境变量里读取,不落到任何版本控制文件里。

如果你是团队使用,建议再加一道控制:不要直接发原始 key,而是给每个人生成独立的子 key,再在网关层配置好额度上限。这样即使某个人的 key 泄露了,影响范围也是可控的,不至于把主账号的额度全部暴露出去。

3. sdcb/chats 对话层:把会话沉淀与上下文管起来

3.1 部署方式选择

sdcb/chats 这层,我用的方式是跑一个轻量服务。你可以理解成它就是一个网页版的聊天前端,背后连接各个模型的 API。对我来说最重要的一个功能是:它把「对话」和「模型」解耦了。我可以在同一个界面里,左边是 Claude 的会话,右边是 DeepSeek 的会话,互不干扰;也可以一个问题同时发给多个模型,对比它们的答案。

部署方式上,sdcb/chats 这类项目通常都支持 Docker 部署,这也是我推荐的方式。一条docker compose up -d就能把服务拉起来,数据目录挂载在本地,不会因为容器更新而丢会话。如果你不想用 Docker,本地直接跑也行,但依赖环境可能会多一些,重来一遍的成本更高。

我自己的部署习惯是:Docker Compose 文件单独放在一个目录里,数据目录固定指向一个带日期的路径,方便备份。最关键的一点是,每次升级镜像之前先备份数据目录。聊天记录这种东西看起来不占地方,但一旦累积几个月,里面包含了大量你和模型的上下文对话,丢了是真的心疼。

3.2 模型供应商接入与界面配置

chats 的供应商接入逻辑,和 cc-switch 那边是同一套路:本质上也是 Base URL、API Key、模型名三要素。区别在于,chats 侧更侧重「会话管理和展示」,所以它会把这些配置分门别类放在界面或者配置文件里,让你为每个供应商设置别名、默认模型、以及一些上下文参数。

我实际配置的顺序是:先在 cc-switch 里把某家供应商的连通性跑通,确认 key 和模型名没问题,再到 chats 里添加这家供应商。这样万一有什么问题,我能一眼看出是配置层的问题还是对话层的问题,不用上下两头乱猜。

界面配置里有一个参数需要特别注意,就是「上下文长度」或者叫「最大对话轮数」。很多人在聊天前端里发现聊着聊着模型就「失忆」了,其实就是上下文窗口被塞满了,老消息被截断了。不同的模型上下文长度差别很大,你在配置里给它设定的值应该比模型真实上限小一些,留出余量给系统提示词和当前代码片段。我一般会设置为模型上限的 70% 到 80%,这样既不会浪费上下文,也不会在长对话中突然断片。

3.3 会话历史与上下文粘性

会话历史这个问题,是热词里提到的「cc-switch 切账号之前对话的上下文不能加载」的核心痛点。我自己也遇到过,后来梳理清楚了原因:上下文能不能加载,取决于两个东西,一是会话存储位置有没有变,二是对话前端的会话 ID 是否稳定。

cc-switch 切换的是供应商配置,理论上不应该影响 chats 侧的会话存储。但如果你的部署方式是「切换配置」和「对话服务」在同一套环境变量里联动,那切换配置时可能会附带重启服务,而重启之后会话 ID 如果重新生成,旧对话就找不到了。这是很多人遇到「切完上下文没了」的元凶。

解决办法其实不复杂:把会话存储独立出来,不要跟着配置切换一起动。我现在的做法是,chats 的数据目录固定指向一个独立挂载卷,cc-switch 切换时只更新环境变量文件,不去碰数据目录。服务可以热重载,甚至重启都无所谓,只要数据目录没变,会话 ID 稳定,历史记录就能接着用。如果你用的是终端侧的编程助手(比如 Claude Code 这类),那就把你的工作目录、会话记录目录保持固定,不要因为切换配置而改到另一个地方去。

4. 实操过程:从零到一搭建完整基础设施

4.1 搭建环境与基础依赖

我先说下我这边的环境,方便你对照:一台 Linux 服务器,装了 Docker 和 Docker Compose,本机日常开发是 macOS 环境,终端用了 zsh。整体不挑系统,Windows 上也可以用,但路径、脚本这块需要你自己微调一下。

第一步,建一个统一的项目目录,比如~/ai-infra,下面分成cc-switch、chats、data三个子目录。data 目录专门放会话数据和配置快照,这个目录不进 Git。

然后安装 cc-switch。我建议用 npm 全局安装,版本注意盯一下 Release 页,不要用太老的版本,因为老版本对某些新供应商的兼容协议支持得不好。安装完先跑一遍自检命令,确认版本号和基础命令都能用。

4.2 配置供应商档位

接着在 cc-switch 的配置目录里,逐个添加供应商档位。以三个模型为例:Anthropic 系的 Claude、DeepSeek 的通用对话模型、OpenRouter 聚合服务。每个档位都单独命名,方便后面切换时识别。

配置文件的核心部分大概长这样:

{ "profiles": [ { "name": "claude-dev", "provider": "anthropic", "base_url": "${ANTHROPIC_BASE_URL}", "api_key": "${ANTHROPIC_API_KEY}", "default_model": "claude-sonnet-4-20250514", "params": { "max_tokens": 8192, "temperature": 0.3 } }, { "name": "deepseek-coder", "provider": "deepseek", "base_url": "${DEEPSEEK_BASE_URL}", "api_key": "${DEEPSEEK_API_KEY}", "default_model": "deepseek-coder", "params": { "max_tokens": 4096 } }, { "name": "openrouter-auto", "provider": "openrouter", "base_url": "https://openrouter.ai/api/v1", "api_key": "${OPENROUTER_API_KEY}", "default_model": "anthropic/claude-3.5-sonnet", "params": { "max_tokens": 4096 } } ] }

这里有几个细节值得展开:

  • base_url我写的是环境变量占位符,真实值不写在配置里;
  • api_key同理;
  • default_model这块要特别小心,OpenRouter 里的模型名和原生供应商的模型名经常不一样,必须一个一个核实;
  • temperature和max_tokens这些参数,我给编程场景设置了偏保守的值,比如temperature=0.3,避免模型放飞自我。

配好之后,执行切换命令切到deepseek-coder档,然后用一个最简单的测试请求验证一下能不能正常返回。这里我推荐写一个十行左右的小脚本,用 Python 的 requests 库直接发一个 OpenAI 兼容的聊天补全请求,既能验证 key 通不通,又能验证模型名对不对。别在没验证的情况下直接进 chats 界面,否则报错的时候你会分不清是配置问题还是前端问题。

4.3 部署 sdcb/chats 对话服务

chats 服务我用 Docker Compose 来跑。下面是我当时用的一个简化版 compose 配置:

services: chats: image: ghcr.io/sdcb/chats:latest container_name: chats restart: unless-stopped ports: - "8080:8080" environment: - TZ=Asia/Shanghai volumes: - ./chats-data:/app/data

这段配置里最需要注意的是volumes那个目录,它是会话历史存的地方。我专门把它放到数据目录里,而不是容器内部,这样版本升级不会丢数据。端口 8080 可以按需改,但如果你在服务器上跑,记得在防火墙里放行这个端口。

服务起来之后,浏览器打开http://服务器IP:8080,先进管理界面把供应商添加好。这里添加的供应商可以和 cc-switch 里的一致,也可以不一致。我的建议是:cc-switch 里保持一套「完整候选名单」,chats 里只放你真正经常用的两三个,界面干净一点,维护成本也低。

4.4 打通配置切换与对话服务

现在到了最关键的一步:让 cc-switch 切换配置后,chats 能自动跟着用新的供应商。我的方案是在中间加了一层「导出脚本」。

大致逻辑是:执行cc-switch 切换命令的时候,会更新当前配置状态;然后一个 shell 脚本读取当前激活的配置档,把对应的base_url和api_key导出成环境变量,再写入 chats 的配置目录或者通过 Docker Compose 的 env_file 注入。这样切换一次配置,两边就同步了。

脚本写起来不复杂,但有几个坑:

  • 写入配置之后要触发 chats 重新加载配置。有些前端支持热加载,有些需要重启容器。我的做法是通过docker compose restart chats这个命令,简单粗暴但可靠;
  • 千万不要在脚本里把真实 key 打印出来。日志里任何一行带 key 的输出都是潜在风险;
  • 切换前先备份 chats 的数据目录。如果你操作频繁,建议把备份做成自动的,用一个简单的 tar 命令配合定时任务就行。

我实际用的切换流程是:一条命令切换供应商,然后自动重启 chats,整个过程大概 15 秒左右。对比以前手动改环境变量的方式,体验提升是质变的。

4.5 验证链路与日常使用示例

链路打通之后,一定要做一次端到端验证。我习惯的验证方式是在 chats 界面新建一个会话,随便问一个和当前项目相关的问题,然后看三件事:

  • 界面能不能正常返回结果,说明 API 连通性 OK;
  • 返回的语言风格是否符合当前供应商的特征,说明切换真的生效了;
  • 刷新页面后旧会话还在不在,说明数据目录独立存储没问题。

验证通过后,日常使用就很顺了。我写代码的时候,终端里跑着 Claude Code 这类编程助手,浏览器开着 chats 作为备用对话入口,遇到代码问题直接在聊天里贴报错,需要写方案就让模型帮忙列思路。切换供应商的时候只动一个命令,之前的会话记录都在 chats 里,按项目名就能搜到。

5. 常见问题与排查技巧实录

5.1 切换后配置不生效或请求 404

这是我在搭建过程中遇到最多的问题。表面现象是你已经切到了某个供应商,但实际请求还是打到旧的地址上,或者直接返回 404。

排查顺序我建议固定下来:第一步看环境变量到底有没有更新,第二步看 chats 或者其他客户端进程有没有重新加载配置,第三步看 Base URL 是不是真的正确。很多时候 404 不是因为配置没切过去,而是因为你写的 Base URL 拼错了路径,比如漏掉了/v1这个前缀。

我自己的习惯是,切换之后立刻在终端里跑一条最简测试命令,用当前环境变量发一请求,这样能立刻定位问题在哪一层,不用反复重启服务瞎猜。

5.2 会话上下文「消失」的问题

前面说过,这个问题的本质是会话存储位置或者是会话 ID 不稳定。如果你在切完配置后发现之前的对话还在,但点进去没有历史消息,大概率是数据库连接或者存储目录被改动过。

我处理这个问题的方法是:所有与会话历史相关的路径,全部做成「只读」的引用,不参与任何切换逻辑。也就是说,cc-switch 只能碰环境变量和配置档,绝不允许它去动 chats 的数据目录。这样无论你怎么切,历史记录永远是稳定的。如果你有多个项目,也可以按项目区分会话目录,让不同项目之间的上下文互不污染,这样切换项目的时候还能保留每个项目独立的对话脉络。

5.3 API 限流与超时

多模型接入之后,限流是个躲不开的坎。每个供应商对并发、每分钟请求数都有不同的限制,如果代码里做了并行调用,很容易触发限流,表现就是请求偶尔成功偶尔报错,非常诡异。

排查限流问题,我一般看三点:返回的错误信息里有没有 rate limit 字样、请求日志里的时间戳分布是否集中、当前供应商的账号是不是免费额度阶段。解决办法也比较成熟:在代码或者前端配置里加上请求重试机制,对限流错误做退避重试;同时控制并发数,不要无脑开太多线程。如果同一个功能要调用多个模型,建议用带缓冲的队列做削峰,而不是一股脑全发出去。

另外,成本控制也要在这里提一句。多个供应商接入之后,最好在网关层面做月度预算限制和用量统计。我自己的做法是给每个团队成员的子 key 设定额度上限,每个月月初自动检查上月消费,超出阈值的账号直接禁用,等确认账单后再恢复。这样既不会让费用失控,也能倒逼大家只在自己真正需要的场景调用付费模型。

5.4 模型返回质量不稳定

最后说说模型质量。同一个问题,不同模型给出来的答案风格差异很大,这不一定是配置错了,而是模型本身的特色。我在实际使用中体会到一点:给不同编程任务固定不同的默认供应商,反而比「哪个模型最强用哪个」更高效。

比如,做整体架构设计、写复杂算法逻辑,我固定用 Claude 系;做批量代码补全、注释生成、简单重构,用 DeepSeek 这类性价比高的模型;需要跨模型做对比验证的时候,再临时切到聚合网关,一次问多个模型。这个思路听起来很简单,但真正落地需要基础设施支持快速切换,而 cc-switch 加 chats 这套组合正好满足。

6. 团队协作与运维沉淀

6.1 多人共用一个配置中心

如果你不是一个人折腾,而是带团队一起用,那配置管理的复杂度会立刻上一个台阶。我目前的做法是:cc-switch 的配置库放在 Git 仓库里,但里面只有占位符和公共配置,真实 key 通过 CI/CD 的 secret 注入。团队成员拉取配置库之后,只需要在自己的机器上补一个本地环境变量文件就能跑起来。

这里要特别提醒:不要图省事把 key 直接写在配置库里,哪怕是你私人的仓库也不行。只要密钥进了版本历史,被删除并不能抹掉它曾经出现过的事实。最稳妥的做法是,一旦 key 可能泄露,立即去供应商后台吊销并重新生成。

6.2 会话数据备份与迁移

chats 的会话数据每天都在涨,特别是你把它当主力编程助手用的时候。我建议把数据目录备份纳入日常运维,不用太复杂,两条规则就够:

  • 每周末做一次全量备份,保留最近一个月;
  • 每次升级 chats 镜像之前必须手动备份一次。

备份下来的数据是 JSON 或者 SQLite 格式,迁移的时候直接把整个数据目录带走就行,不需要额外处理依赖关系。这也验证了 Docker 部署的好处:数据在卷里,容器随便换版本,只要卷还在,就没什么好担心的。

6.3 个人经验总结

这套基础设施搭建完之后,对我最大的改变并不是「能用更多模型」了,而是「思考方式」变了。以前我打开一个 AI 工具,脑子里想的是「这个工具会不会用」,现在打开 chats,我想的是「今天这个任务适合交给哪个模型」。切换模型变成了一个可以随时做、不需要付出额外成本的操作,所以我的工作流也相应地变得更具实验性。

如果你也想搭一套类似的 AI 编程基础设施,我的建议是不要一开始就上太复杂的配置。先把一个供应商跑通,再加第二个,等两三家都能顺利切换了,再考虑接入聚合网关和团队协作。基础设施这种东西,最怕的就是一开始就追求大全,最后配到一半发现维护成本比收益还高。

最后再分享一个小技巧:所有环境变量的命名尽量统一,比如ANTHROPIC_BASE_URL、DEEPSEEK_API_KEY这种。命名统一之后,不管是在 cc-switch 里引用,还是在 chats 里做注入,或者在脚本里做逻辑判断,你都不用翻文档,一眼就知道这个变量是干嘛的。这套基础设施我用了几个星期,最大的感触就是:稳定和顺手,比多一个模型多一个功能重要得多。

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

基于SpringBoot+Vue的电影评论网站管理系统完整开发实战

最近一段时间,前后有好几个准备做毕业设计或者课程设计的同学来找我看代码,问的最多的就是同一个方向:基于SpringBootVue的电影评论网站管理系统。这东西乍一听感觉很常规,但真正从头到尾完整做一遍,你会发现它把Java后…

作者头像 李华
网站建设 2026/10/3 3:23:27

基于Scala与MySQL的交通拥堵预测:数据库课设高分实战解析

简介:这是一份基于Scala的交通拥堵预测源码,源自大三学期的高分数据库课程设计,适合计算机科学与技术、大数据、人工智能等专业学生用作课程设计、期末大作业或项目实战演练。压缩包共50个文件,以18个Scala源文件为核心&#xff0…

作者头像 李华
网站建设 2026/10/3 3:22:38

Spark+Hive交通智能研判系统源码解析与实战避坑指南

简介:《基于SparkHive的交通智能研判系统》是一套用于毕业设计和课程设计场景的大数据实践项目,基于Spark与Hive两大组件构建,面向交通流量实时计算、历史数据管理和智能研判分析等问题,适合正在学习或开发分布式数据处理系统的读…

作者头像 李华
网站建设 2026/10/3 3:22:20

AI Agent多智能体仿真:用大模型构建舆论推演沙盘

开门见山说一个事:把“社会舆论”放进AI里做思想实验,现在已经不是科幻设定,而是一套可以落地的工程方案。核心思路很简单——用大模型驱动一批虚拟智能体,让它们拥有不同身份、立场、信息渠道和表达习惯,在一个人造的…

作者头像 李华
网站建设 2026/10/3 3:22:02

S7-1200 PID_Temp恒温控制实战:从组态到参数整定

1. 做恒温控制,为什么我盯上了PID_Temp这条工艺指令做工业自动化这些年,温控项目几乎每个工程师都会碰到。从塑料挤出机的料筒加热,到烘箱、干燥罐、反应釜,再到实验室的小型恒温槽,场景千千万万,但控制逻辑…

作者头像 李华
网站建设 2026/10/3 3:21:42

CST时域仿真网格设置本质是时空耦合博弈

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

作者头像 李华