新闻详情

新闻详情

首页 / 资讯中心 / 详情

大模型驱动的硅基客服:架构设计、代码实现与规模化落地

发布时间:2026/9/6 1:49:30来源:尧图网络
大模型驱动的硅基客服:架构设计、代码实现与规模化落地
1. 背景为什么“硅基客服”突然开始大规模上岗过去两三年客服系统一直处于一个尴尬状态传统 IVR 按键式客服体验差人工客服成本居高不下而早期的机器人客服更多是“关键词匹配 固定话术”用户稍微换一种说法就答非所问。最近圈内讨论度很高的一个方向是大模型驱动的“硅基客服”。所谓硅基客服本质上是以大语言模型LLM作为对话理解和生成核心叠加语音识别ASR、语音合成TTS、知识库检索RAG、CRM/工单系统联动等模块构成一套能独立完成对话接待、意图识别、业务办理、人工接管等任务的智能客服系统。之所以叫“硅基”是对应“碳基”的人类坐席强调由芯片和模型承担主要服务工作。我们看到一个很典型的数据变化从每天 1000 通电话做到 1.5 万通电话接通能力提升了一个数量级。这背后不只是换了一个更聪明的模型而是整个客服系统的架构、流程、知识库管理、人机协作机制都发生了改变。这篇文章围绕“硅基客服”从技术落地角度展开核心讨论四件事一套可落地的硅基客服系统由哪些模块组成如何从零搭建一个最小可运行的语音/文本客服原型从千通到万通规模系统架构要做什么升级真实落地中频繁踩到的坑和排障思路。不管你是后端开发、算法工程师还是负责客服系统选型的技术负责人这篇文章都会有一个整体视角。2. 核心概念硅基客服不是“一个机器人”而是一套系统2.1 硅基客服与传统客服机器人的区别传统客服机器人更多是“规则 关键词 多轮对话状态机”。它的逻辑可以被简化为用户输入 - 关键词匹配 - 命中意图 - 返回配置好的话术这种方案有两个致命弱点一是语义理解能力弱用户表达稍微复杂就匹配不到二是知识维护成本高每新增一个业务场景都要人工配置大量规则和节点。硅基客服的核心变化在于用 LLM 做意图识别和对话生成理解能力大幅提升用 RAG检索增强生成动态接入企业知识库不再把知识硬编码到对话流程里用 Agent 机制串联 CRM、工单、支付、物流等系统让机器人不只是“聊天”而是能“办事”用完整的人机协同机制在机器人无法处理时平滑转接人工坐席。2.2 一套完整的硅基客服系统组成从工程视角来看一套可以投入生产的硅基客服系统通常包含以下模块模块作用常见技术选型接入层承接电话、网页、App、微信等多渠道流量SIP 网关、WebSocket、IM SDKASR 语音识别将用户语音转为文字阿里云语音识别、腾讯云 ASR、Whisper 本地部署对话引擎理解意图、管理多轮对话、生成回复大模型 API / 私有化 LLM 对话管理框架知识库/RAG从企业文档中检索答案减少幻觉Elasticsearch、Milvus、向量数据库TTS 语音合成将机器回复转为语音播报火山引擎 TTS、Azure TTS、开源 TTS业务系统对接查询订单、办理业务、创建工单REST API、消息队列人机协同模块情绪识别、转人工、坐席工作台自研或第三方 CCaaS监控与运营通话质检、数据看板、模型迭代日志系统 BI 看板从“1000 通到 1.5 万通”的变化来看并不是简单地把 ASR、LLM、TTS 三个服务部署起来就能做到。真正支撑万通级并发的是一个工程体系包括并发控制、语音链路优化、知识库更新、人工介入策略、数据回流和模型迭代。3. 环境准备与版本说明开始实战之前先明确环境。不同企业的技术栈差异很大本文以一个通用、可落地的示例为主版本按常见稳定版本处理重点讲配置思路。3.1 基础环境操作系统CentOS 7.9 / Ubuntu 22.04生产环境以 Linux 为主 Python3.10 Node.js18用于 Web 管理端 Redis6.2 MySQL8.0 Docker24.03.2 大模型相关目前大模型的选择非常多包括国内的开源模型和闭源 API。为了避免绑定具体厂商示例代码统一使用兼容 OpenAI SDK 的接口风格便于替换。实际部署请根据团队的采购和合规要求选择模型服务并确认模型 API 的 base_url、api_key、model_name 三个参数。模型服务任意兼容 OpenAI Chat Completions 接口的服务 embedding 模型用于知识库向量化例如 bge-m3 或 text-embedding 系列3.3 语音能力语音识别和语音合成如果从零自研成本极高。生产环境通常直接使用云厂商能力或者基于开源模型如 Whisper、GPT-SoVITS做私有化。云厂商的接口形式差异较大本文不绑定具体厂商以 REST API 抽象接口代替。4. 从零搭建一个最小可用“硅基客服”系统我们先不上一套复杂的生产级架构而是搭建一个最小原型帮助理解整个链路。这个原型实现以下功能接收用户文本消息调用 LLM 生成回复从本地知识库检索相关内容辅助回答输出对话结果。语音部分会在后面单独讲解接入方式。4.1 创建项目结构silicon-customer-service/ ├── app/ │ ├── __init__.py │ ├── main.py # FastAPI 入口 │ ├── config.py # 配置文件 │ ├── llm_client.py # LLM 调用客户端 │ ├── knowledge_base.py # 知识库检索 │ ├── conversation.py # 多轮对话管理 │ └── schemas.py # 数据模型 ├── data/ │ └── knowledge.md # 示例知识库 ├── requirements.txt └── .env4.2 安装依赖pip install fastapi uvicorn openai redis pymysql python-dotenv4.3 配置项在.env文件中写入以下配置MODEL_API_KEYyour-api-key MODEL_BASE_URLhttps://your-llm-service.example.com/v1 MODEL_NAMEyour-model-name REDIS_URLredis://localhost:6379/0这里重点解释三个参数MODEL_BASE_URL模型服务的接口地址不同服务商地址不同需要按实际情况填写。MODEL_NAME模型名称闭源模型需要确认 API 是否支持直接传入开源模型部署时也需要确认服务暴露的模型名。REDIS_URLRedis 地址用于存储对话状态和限流计数。4.4 实现 LLM 客户端主要目的是封装模型调用后续如果更换模型服务商只需要改这里。# 文件路径app/llm_client.py import os from openai import OpenAI client OpenAI( api_keyos.getenv(MODEL_API_KEY), base_urlos.getenv(MODEL_BASE_URL), ) def chat_with_llm(messages, temperature0.3): response client.chat.completions.create( modelos.getenv(MODEL_NAME), messagesmessages, temperaturetemperature, ) return response.choices[0].message.content注意temperature参数。客服场景对答案稳定性要求较高建议设置为 0.2~0.4不要使用过高的值否则同一个问题每次回答都不一样用户会觉得“不靠谱”。4.5 实现知识库检索这里用一个非常轻量的本地检索方案核心目的是演示 RAG 思路。生产环境通常使用向量数据库示例中选择关键词 简单相似度匹配便于理解。# 文件路径app/knowledge_base.py import re class KnowledgeBase: def __init__(self, file_path): with open(file_path, r, encodingutf-8) as f: self.content f.read() self.sections self._split_sections() def _split_sections(self): # 按 Markdown 标题切分知识库 sections [] current_title current_content [] for line in self.content.splitlines(): if line.startswith(## ): if current_title: sections.append({ title: current_title, content: \n.join(current_content) }) current_title line.replace(## , ).strip() current_content [] else: current_content.append(line) if current_title: sections.append({ title: current_title, content: \n.join(current_content) }) return sections def search(self, question, top_k3): keywords re.findall(r[\u4e00-\u9fa5]{2,}, question) scored [] for section in self.sections: score 0 text section[title] section[content] for kw in keywords: if kw in text: score 1 scored.append((score, section)) scored.sort(keylambda x: x[0], reverseTrue) return [s for s in scored if s[0] 0][:top_k]知识库文件示例data/knowledge.md## 退款政策 用户在购买后 7 天内可以申请无理由退款。退款将在 3-5 个工作日内原路退回。 ## 发货时间 工作日 16:00 前下单的订单当天发货16:00 后下单的订单次日发货。 ## 会员权益 黄金会员享受专属客服、生日礼包和双倍积分权益。4.6 实现多轮对话管理客服场景中用户可能会问“运费多少”接着问“那退货呢”如果只做单轮问答第二个问题就失去了上下文。Redis 在这里的作用就是保存每个会话的历史消息。# 文件路径app/conversation.py import json import redis r redis.Redis.from_url(redis://localhost:6379/0) SESSION_EXPIRE_SECONDS 1800 # 30 分钟无操作则清空会话 def get_history(session_id: str): key fconversation:{session_id} data r.get(key) if data: return json.loads(data) return [] def save_history(session_id: str, messages): key fconversation:{session_id} r.setex(key, SESSION_EXPIRE_SECONDS, json.dumps(messages))4.7 实现主接口下面把整个流程串起来先取历史消息再检索知识库把知识库内容和用户问题一起交给 LLM最后保存历史。# 文件路径app/main.py from fastapi import FastAPI from pydantic import BaseModel from llm_client import chat_with_llm from conversation import get_history, save_history from knowledge_base import KnowledgeBase app FastAPI() kb KnowledgeBase(data/knowledge.md) class ChatRequest(BaseModel): session_id: str question: str SYSTEM_PROMPT 你是某电商平台的客服助手。请根据提供的知识库内容回答问题。 如果知识库中没有相关信息请如实告知用户并表示会转接人工客服。 回答要简洁、友好、准确不要编造信息。 知识库内容 {knowledge} app.post(/chat) def chat(req: ChatRequest): history get_history(req.session_id) # 1. 检索相关知识 related_docs kb.search(req.question) knowledge_text \n\n.join( [f【{doc[title]}】\n{doc[content]} for _, doc in related_docs] ) # 2. 组装 prompt messages [{role: system, content: SYSTEM_PROMPT.format(knowledgeknowledge_text)}] messages.extend(history) messages.append({role: user, content: req.question}) # 3. 调用 LLM result chat_with_llm(messages) # 4. 保存历史只保留最近 10 轮 history.append({role: user, content: req.question}) history.append({role: assistant, content: result}) history history[-20:] save_history(req.session_id, history) return {answer: result}4.8 运行与验证uvicorn app.main:app --host 0.0.0.0 --port 8000使用 curl 测试curl -X POST http://localhost:8000/chat \ -H Content-Type: application/json \ -d {session_id: test-001, question: 退款政策是什么}预期返回类似下面的结果{ answer: 用户在购买后 7 天内可以申请无理由退款退款将在 3-5 个工作日内原路退回。 }继续测试多轮能力curl -X POST http://localhost:8000/chat \ -H Content-Type: application/json \ -d {session_id: test-001, question: 那多久到账}因为有了历史上下文模型能理解“那”指的是退款回答仍然围绕退款场景进行这就是多轮对话管理的作用。5. 从 1000 通到 1.5 万通生产级架构要做的升级上面的原型可以在本地跑通但要支撑大规模呼叫任务远远不够。从 1000 通到 1.5 万通不是量变而是架构质变。下面拆解最关键的变化。5.1 并发链路升级1000 通电话假设平均每通 2 分钟同时在线的话路约 30~40 路。1.5 万通电话如果集中在 8 小时业务时间内平均每秒约 0.5 通但峰值时间段可能在早高峰、活动期间达到每秒 5~10 通呼叫。这意味着API 网关必须支持动态限流和熔断LLM 调用不能同步阻塞否则一个模型接口抖动就会拖垮全部会话必须引入消息队列削峰填谷。生产推荐架构呼叫中心 SIP 网关 - 语音网关服务ASR 接入 - 对话调度服务 - MQRocketMQ / Kafka - LLM Worker 集群 - 结果回写 - TTS 合成 - SIP 网关放音5.2 语音链路的时延控制语音客服和文本客服最大的区别是用户能感知到“沉默”。如果 ASR 识别需要 1 秒LLM 生成需要 2 秒TTS 合成需要 1.5 秒整体响应时间超过 4 秒用户体验会非常差。控制时延的关键手段ASR 使用流式识别边说边识别而不是等用户说完再识别LLM 使用流式输出SSE首 token 时间控制在 1 秒以内TTS 使用流式合成边合成边播放对高频问题设置“快速回复缓存”直接命中缓存就不再调用 LLM。5.3 并发隔离与优雅降级大规模客服系统中必须区分会话优先级。例如高优先级VIP 用户、投诉电话、支付相关问题中优先级普通业务咨询低优先级营销外呼。在不同优先级之间做资源隔离避免低优先级任务占用大量 LLM 并发导致高优任务排队。5.4 知识库的更新机制“1000 通到 1.5 万通”背后还有一个变化用户问的问题种类显著增加。1000 通时可能 80% 的问题集中在 20 个业务知识点1.5 万通时长尾问题大量出现。生产环境的 RAG 系统必须解决知识文档的定期更新与版本管理新知识发布后向量索引的增量更新知识冲突检测未命中知识的记录和人工补充流程。推荐的做法是让知识库运营人员在管理后台编辑文档提交后触发向量索引重建任务同时保留一份历史版本便于回滚。5.5 人机协同已经是刚需再强的模型也不可能 100% 处理所有问题。生产系统必须解决何时转人工用户情绪激动、重复提问、明确要求“转人工”、系统置信度低如何转人工会话上下文、ASR 转写文本、已尝试的方案要完整给到人工坐席人工接管后如何回归坐席结束会话后把解决方案回填到知识库。一个可参考的转人工判定流程用户输入/语音转写 - 模型判断用户意图 - 是否命中转人工关键词 - 是否出现负向情绪 - 是否同一问题重复提问超过 2 次 - 是否业务类型属于高危退款投诉、法律咨询等 - 以上任一命中则转人工5.6 数据回流与模型迭代硅基客服不是一成不变的系统。每通电话结束后系统应记录ASR 转写文本模型回复内容用户是否满意通过后续行为判断或短信评价是否转人工工单是否解决。这些数据积累到一定程度后可以做两件事微调模型让模型更适应企业特定场景的表达方式优化提示词和知识库解决高频错误。6. 完整语音客服流程设计有很多团队在文本客服上已经跑通了但接入语音后会遇到新的问题。下面给一个完整的语音客服外呼/呼入流程参考。6.1 呼入场景流程用户拨打热线 - SIP 网关接通 - 播放欢迎语 - 启动 ASR 流式转写 - 用户说话ASR 输出中间结果 - 静音检测VAD判断用户说完 - 将文本送入对话引擎 - 对话引擎返回回复文本 - TTS 合成为语音 - 播放回复 - 循环以上步骤直到用户挂断或转人工6.2 外呼场景流程外呼场景通常用于回访、通知、营销。与呼入不同外呼系统要主动发起呼叫并且要处理“空号检测”“拒接”“关机”等状态。# 外呼任务批次提交示例伪代码 calls [ {phone: 138****1234, purpose: 满意度回访, timeout: 30}, {phone: 139****5678, purpose: 账单提醒, timeout: 30}, ] for call in calls: result sip_gateway.make_call( phonecall[phone], play_prompt您好这里是 XX 客服中心请问现在方便接听吗 ) if result.status ANSWERED: conversation start_conversation(call[purpose]) # 进入正常的 ASR - LLM - TTS 循环 run_dialogue(conversation) else: mark_failed(call[phone], result.status)这里要特别提醒外呼业务必须遵守相关法律法规和行业规范只能在用户授权或合理业务场景下进行不得用于骚扰营销。6.3 通话过程中的静音与打断处理语音对话中用户随时可能打断机器人的播报。如果系统不支持打断检测用户会非常烦躁。支持打断的处理逻辑def handle_barge_in(stream): # 在 TTS 播放期间持续检测用户语音 if asr_detected_user_speech(stream): # 停止当前 TTS 播放 tts.stop() # 清空当前未完成的回复等待用户说完 wait_for_user_finish(stream) # 将用户新输入送入对话引擎 process_user_input(get_asr_result(stream))6.4 通话结束后的质检每通电话结束后自动生成一条质量检测记录通话 ID、时间、时长 ASR 转写全文 意图识别结果 是否转人工 用户情绪标签正面/中性/负面 坐席处理动作针对转人工的场景这些数据既用于运营分析也用于模型迭代。7. 常见问题与排查思路下面整理“硅基客服”从开发到生产落地过程中最常见的问题。问题现象常见原因解决思路模型回答与业务事实不符RAG 知识库没有命中相关知识或知识库内容过时检查知识库检索结果调试检索策略更新向量索引用户重复提问不解决模型只回答了表面问题没有理解用户核心诉求增加多轮对话上下文长度提示模型追问澄清语音通话时机器回复过慢ASR、LLM、TTS 全链路串行处理导致时延叠加改用流式识别、流式生成、流式合成缩短首包时间高峰期大量通话排队并发处理能力不足或 LLM 接口限流增加 Worker 数量使用消息队列削峰设置合理的限流策略转人工后坐席看不到上下文会话状态没有在系统间传递统一会话 ID将 ASR 文本、模型回复、业务标签一并传递给坐席工作台模型轻率承诺赔付/补偿System Prompt 缺少边界设定模型幻觉在 Prompt 中明确“不确定的信息不能承诺”结合知识库约束回答范围某些用户方言识别率低ASR 模型对特定口音支持不足收集样本微调 ASR或切换对地域口音支持更好的语音服务商知识库更新后模型仍回答旧答案向量索引未重建或 Prompt 中仍缓存旧知识检查索引构建流程重启缓存或清理检索缓存下面针对两个最常见的“隐形坑”做详细说明。7.1 RAG 检索不到内容的排查现象知识库里明明有“退款政策”用户问“钱什么时候退回来”模型却说“抱歉我不了解相关信息”。排查顺序打印知识库检索结果确认search()返回的内容是否为空检查关键词切分逻辑看“钱什么时候退回来”是否被切分成了“钱”、“什么”、“时候”、“退回来”而知识库中用的是“退款”换更专业的向量检索方案例如 embedding 模型 向量数据库加入 query 改写步骤先让 LLM 把用户口语化问题改写成标准业务问题再检索知识库。这种问题的根因往往是“字面匹配”和“语义匹配”的差距关键词检索在服务场景下只能兜底不能作为主要方案。7.2 LLM 回答“正确的废话”现象模型没有胡说八道但回答非常泛化对业务没有实际帮助。例如用户问“发货时间是什么”模型回答“我们会尽快为您发货请耐心等待”而不是告诉用户“工作日 16:00 前下单当天发货16:00 后次日发货”。根因是知识库内容和提示词约束不足。解决办法将知识库内容写得足够具体包含数字、条件、时间限制在 System Prompt 中要求“优先使用知识库中的精确信息不要模糊表达”对答案做后处理校验例如检查模型输出是否包含知识库中的关键数字。8. 最佳实践与工程建议8.1 提示词工程规范客服场景的 System Prompt 建议固定包含以下内容角色定义权限边界哪些话不能说、哪些事不能承诺知识库使用规则回复风格要求转人工触发条件。示例你是 XX 平台的智能客服助手。 - 只基于知识库内容回答知识库中没有的信息回复“这个问题我需要转接人工坐席为您处理”。 - 禁止承诺退款金额、赔偿、法律效力等敏感内容。 - 回复控制在 50 字以内口语化表达。 - 当用户连续两次表达不满或要求转人工时必须引导转人工。8.2 数据安全与权限控制客服系统涉及大量用户个人信息必须关注对话记录加密存储传输使用 TLS坐席后台按角色控制查看权限不是所有坐席都能查看全部通话记录ASR 转写文本在用于模型训练前需要脱敏模型服务如果使用第三方 API不能把用户手机号、身份证号等敏感信息直接拼进 Prompt录音文件的保存周期和访问审计需要符合企业安全规范。8.3 灰度发布与回滚机制客服系统的每一次提示词调整、知识库更新、模型版本切换都可能在线上引发问题。推荐做法按 5%、20%、50%、100% 的比例灰度放量设置实时监控看板关注解决率、转人工率、平均通话时长、用户负面情绪占比等指标一旦指标恶化立即回滚到上一个稳定版本所有 Prompt 和知识库修改走 Git 管理做到可追溯。8.4 成本控制大模型客服的成本主要来自三部分LLM Token 消耗ASR/TTS 调用费用人工坐席的转接成本。控制成本的方向高频问题缓存答案减少重复调用 LLM使用轻量模型处理简单问题复杂问题再升级到强模型优化 Prompt 长度避免把完整知识库每次都发给模型只发送检索命中的片段设置单用户单日调用上限防止异常刷接口。8.5 监控体系建设生产级系统至少要监控以下指标指标说明告警阈值建议并发通话数当前同时进行中的通话数按规格设定接通率外呼场景有效接通比例低于 40% 告警平均响应时延从用户说完到机器开始播报的耗时超过 4 秒告警LLM 错误率模型调用失败的占比超过 5% 告警转人工率机器人会话转人工的比例超过 30% 需要分析 bot 能力是否下降解决率用户问题在机器人阶段被解决的比例低于 60% 触发分析9. 总结从 1000 通到 1.5 万通本质上不是某一个大模型的功劳而是一整套“硅基客服”系统工程能力的体现。语音识别、大模型对话、知识库检索、业务系统对接、人机协同、监控运营缺了任何一块规模都上不去。这篇文章从最小可用原型写到了生产级架构重点覆盖了文本客服的核心代码、语音客服的链路设计、规模化后的架构变化、常见排障思路以及工程实践建议。你可以先照着原型代码跑通一个 demo再去逐步替换和补充生产级组件。接下来建议按这个顺序深入把关键词检索替换成向量检索接入真正的 RAG 方案接入流式 ASR 和 TTS实现语音通话闭环设计转人工逻辑搭建坐席工作台建立通话数据的回流与分析体系推动模型持续迭代。硅基客服的价值不在于“替代人工”而在于让人工坐席从大量重复咨询中解放出来专注于真正复杂、高价值的用户问题。对开发者来说这是一片值得深耕的技术领域。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

AI时代30+程序员转型指南:从编码执行者到问题解决者 2026/9/6 2:25:35

AI时代30+程序员转型指南:从编码执行者到问题解决者

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

阅读更多 →
Qt 打包 exe 避坑指南:windeployqt + NSIS 生成安装包 2026/9/6 2:25:35

Qt 打包 exe 避坑指南:windeployqt + NSIS 生成安装包

本文介绍如何将 Qt 开发的应用程序打包成专业的 Windows 安装包(.exe),使用 windeployqt 收集依赖,再通过 NSIS 制作安装程序。 一、准备工作二、第一步:生成 Release 版 exe 必须使用 Release 模式编译,De…

阅读更多 →
AI前沿日报 2026-09-05 2026/9/6 2:25:35

AI前沿日报 2026-09-05

GPT-6 Astra 全面推送首日:安全边界与性能飞跃的交织一、今日头条:GPT-6 Astra 全球推送日2026年9月5日,OpenAI 正式向全体 Plus 用户推送 GPT-6 Astra 模型,标志着大模型能力边界的又一次重大突破。然而,性能飞跃的同…

阅读更多 →
Cesium WebGL Shader编程:地图扫描与飞线动画性能优化实战 2026/9/6 2:25:35

Cesium WebGL Shader编程:地图扫描与飞线动画性能优化实战

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

阅读更多 →
工业AI技术指南:从数据采集到模型部署的完整实战方案 2026/9/6 2:25:35

工业AI技术指南:从数据采集到模型部署的完整实战方案

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

阅读更多 →
Claude Code 实战:从安装配置到安全用法的完整指南 2026/9/6 2:22:35

Claude Code 实战:从安装配置到安全用法的完整指南

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

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞