news 2026/9/20 18:01:55

多智能体协作实战:目标设定、角色分配与冲突解决的管理手册

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
多智能体协作实战:目标设定、角色分配与冲突解决的管理手册

1. 从单兵作战到团队协同:Agent 团队管理的核心命题

很多人第一次接触 Agent 开发,都是从单个 Agent 跑通一个任务开始的。你给它一个目标,它调用工具、检索信息、生成结果,整个过程行云流水,感觉像是找到了银弹。但当你试图让多个 Agent 一起完成一件复杂事情的时候,问题就全冒出来了:目标互相打架、角色边界模糊、一个 Agent 的输出被另一个 Agent 无视、两个 Agent 陷入无限循环的对话、甚至出现“三个和尚没水喝”的尴尬局面。

这些问题的根源不在于模型能力不够,而在于我们把“多智能体协同”想得太简单了。多智能体系统不是把几个 Agent 的 API 串起来就完事了,它本质上是一个组织管理问题。你需要设定目标、分配角色、建立沟通机制、处理冲突、评估绩效。这套逻辑和人类团队管理惊人地相似,只不过你的“员工”是一群没有情绪但也没有常识的 AI。

这篇文章要聊的就是这套管理手册。我会从目标设定、角色分配、冲突解决三个核心维度展开,把我在多个多智能体项目中踩过的坑、总结的方法、以及可以直接复用的配置思路都摊开来讲。无论你是在用 AutoGen、CrewAI、AgentScope 还是自己手搓编排层,这套管理逻辑都是通用的。适合已经跑通过单 Agent、正准备往多 Agent 方向走的开发者,也适合那些已经上了多 Agent 但被协作问题折磨得够呛的团队。

2. 目标设定:让每个 Agent 都知道“为什么而战”

2.1 目标层级拆解:从全局意图到可执行指令

多智能体系统里最常见的目标设定错误,就是把一个模糊的全局目标直接扔给所有 Agent。比如“帮我写一份行业分析报告”,这个目标对人来说都需要进一步拆解,对 Agent 来说更是灾难。每个 Agent 会按照自己的理解去执行,最后产出的东西拼在一起驴唇不对马嘴。

正确的做法是建立三层目标结构。第一层是全局意图,这是给编排层或者人类监督者看的,描述整个系统要达成的最终状态。第二层是角色目标,每个 Agent 角色对应一个子目标,这个子目标必须是对全局意图的必要分解。第三层是任务指令,这是 Agent 实际执行时接收到的具体输入,必须包含明确的输入格式、输出格式、约束条件和完成标准。

我拿一个实际项目举例。全局意图是“生成一份竞品分析报告”。拆解到角色目标层面:信息采集 Agent 的目标是“收集三家竞品的公开信息”,数据分析 Agent 的目标是“对比三家竞品的核心指标”,报告撰写 Agent 的目标是“基于分析结果生成结构化报告”。再往下拆到任务指令,信息采集 Agent 收到的指令会具体到“从以下五个维度收集信息,每个维度至少两条数据点,输出为 JSON 格式”。

这里有个关键原则:每个 Agent 的目标必须是可验证的。什么叫可验证?就是你能写一个判断函数,输入 Agent 的输出,返回 True 或 False。如果你写不出来,说明目标还不够具体。比如“收集竞品信息”不可验证,“收集竞品 A 的定价信息,包含至少三个价格档位”就可验证。

2.2 目标对齐:避免 Agent 各自为政

目标拆解完了,下一个坑是目标对齐。你给每个 Agent 设定了子目标,但它们执行的时候可能会偏离。信息采集 Agent 为了“收集更多信息”,开始抓取无关数据;分析 Agent 为了“分析更深入”,开始编造不存在的指标;撰写 Agent 为了“报告更漂亮”,开始堆砌辞藻。

解决这个问题的核心手段是在目标中嵌入约束。约束分三类:范围约束、质量约束、格式约束。范围约束限定 Agent 能做什么、不能做什么,比如“只使用提供的搜索结果,不得引入外部知识”。质量约束定义什么叫“好”,比如“每个结论必须有至少一条数据支撑”。格式约束规定输出结构,比如“必须包含标题、摘要、正文、参考来源四个部分”。

我在实际项目里还会加一个目标优先级的设定。当多个目标冲突时,Agent 需要知道哪个优先。比如“准确性优先于完整性”意味着当信息不足时,宁可少写也不要编造。这个优先级要写进系统提示词里,并且在编排层做校验。

注意:目标对齐不是一次性的工作。每轮迭代后,你都需要检查 Agent 的实际输出是否偏离了原始目标。偏离了就要调整提示词或者约束条件,这是一个持续调优的过程。

2.3 目标动态调整:当环境变化时怎么办

多智能体系统运行过程中,环境可能会变化。比如你原本让 Agent 去抓取某个网站的数据,结果网站改版了;或者用户中途改变了需求,原本要分析三家竞品,现在要分析五家。这时候如果目标不能动态调整,整个系统就会卡死。

我的做法是在编排层加一个目标重评估节点。这个节点定期检查当前状态和原始目标的差距,如果发现目标已经不可达或者需要调整,就触发目标更新流程。更新流程包括:暂停所有 Agent、重新拆解目标、更新每个 Agent 的指令、恢复执行。

这里有个实操技巧:给每个 Agent 的目标加上版本号。当目标更新时,版本号递增,Agent 在输出时会带上自己执行的目标版本。这样在排查问题时,你能清楚地知道哪个 Agent 用的是旧目标,哪个用的是新目标。

3. 角色分配:让每个 Agent 做自己最擅长的事

3.1 角色设计的基本原则

角色分配的核心问题是:一个多智能体系统里应该有几个角色?每个角色负责什么?我的经验是,角色数量不要超过五个,超过五个之后沟通成本会指数级上升。每个角色必须有明确的职责边界独特的价值贡献

什么叫独特的价值贡献?就是这个角色做的事情,其他角色做不了或者做不好。如果你发现两个角色的职责有重叠,要么合并,要么重新划分边界。比如“信息采集”和“信息整理”在很多系统里是两个角色,但如果采集 Agent 本身就能输出结构化数据,整理这个角色就是多余的。

角色设计还要考虑能力匹配。不同的 Agent 可能用不同的模型、不同的工具集、不同的提示词模板。你要根据任务需求来分配。比如需要创意生成的任务,用温度参数较高的模型;需要精确计算的任务,用代码解释器能力强的模型;需要长文本理解的任务,用上下文窗口大的模型。

3.2 常见角色类型与职责定义

根据我做过的一些项目,多智能体系统里常见的角色类型可以归纳为以下几类:

角色类型核心职责关键能力典型输出
协调者任务分解、进度管理、结果汇总全局视野、决策能力任务计划、状态报告
执行者具体任务执行工具调用、专业处理任务结果、执行日志
审查者质量检查、错误发现批判性思维、标准掌握审查意见、修改建议
信息者信息检索、知识提供检索能力、信息筛选参考资料、数据摘要
创意者方案生成、内容创作发散思维、语言能力创意方案、初稿内容

协调者这个角色特别关键。它不直接执行任务,而是负责把全局目标拆解成子任务,分配给合适的执行者,跟踪执行进度,处理异常情况。协调者的提示词里要包含完整的任务列表、每个执行者的能力描述、以及任务依赖关系。

审查者是我强烈建议每个系统都配备的角色。它的职责不是执行任务,而是检查其他 Agent 的输出。审查者的提示词要包含明确的检查清单:格式是否正确、内容是否完整、逻辑是否自洽、是否有事实错误。审查者发现问题后,不是直接修改,而是把问题反馈给协调者,由协调者决定是让原执行者修改还是重新分配任务。

3.3 角色间的依赖关系与通信拓扑

角色分配完了,接下来要定义它们之间怎么通信。常见的通信拓扑有三种:中心化去中心化混合式

中心化拓扑里,所有 Agent 都只和协调者通信,Agent 之间不直接对话。这种拓扑的优点是控制简单、状态清晰,缺点是协调者容易成为瓶颈,而且协调者一旦出错整个系统就崩了。适合任务流程固定、Agent 数量少的场景。

去中心化拓扑里,Agent 之间可以自由通信。优点是灵活、容错性好,缺点是容易出现通信风暴,两个 Agent 可能陷入无限对话。适合探索性任务、Agent 数量多的场景。

混合式拓扑是我最常用的。核心流程走中心化,协调者管理主要任务流;但允许特定 Agent 之间建立直接通信通道,比如执行者和审查者之间可以直接传递修改意见,不用经过协调者中转。这样既保证了整体可控,又减少了协调者的负担。

提示:无论用哪种拓扑,都要设置通信轮次上限。我一般设置单个任务内 Agent 间通信不超过 10 轮,超过就强制中断并上报协调者。这个限制能有效防止无限循环。

3.4 角色能力的动态切换

有些场景下,一个 Agent 可能需要扮演多个角色。比如在一个小规模系统里,协调者可能同时兼任审查者。这时候你需要定义角色切换规则:什么时候切换、切换后提示词怎么变、上下文怎么处理。

我的做法是给每个 Agent 维护一个角色状态机。状态机里定义了当前角色、可切换的角色、切换条件。比如协调者在完成任务分配后,如果检测到没有审查者角色,就自动切换到审查者模式,加载审查提示词,开始检查执行者的输出。

角色切换时最大的坑是上下文污染。协调者的上下文里包含了任务分配信息,切换到审查者后,这些信息可能会干扰审查判断。解决办法是在切换时对上下文做选择性保留:只保留与当前角色相关的信息,其他信息归档但不进入当前上下文。

4. 冲突解决:当 Agent 之间意见不合时

4.1 多智能体冲突的类型与成因

Agent 之间的冲突比人类团队更隐蔽,因为 Agent 不会拍桌子吵架,它们会用看似合理的方式表达分歧。常见的冲突类型有四种:

目标冲突:两个 Agent 的目标不一致。比如一个 Agent 追求速度,另一个追求准确性,在资源有限的情况下就会产生矛盾。这种冲突通常源于目标设定阶段没有做好优先级排序。

信息冲突:两个 Agent 基于不同的信息做出判断。比如信息采集 Agent 提供了两份矛盾的数据,分析 Agent 不知道该信哪个。这种冲突源于信息源没有做可信度分级。

资源冲突:多个 Agent 竞争同一个资源。比如两个 Agent 同时想调用同一个工具,或者同时想写入同一个文件。这种冲突在并发执行时特别常见。

逻辑冲突:一个 Agent 的输出和另一个 Agent 的输出在逻辑上矛盾。比如撰写 Agent 写了一个结论,审查 Agent 认为这个结论没有依据。这种冲突源于缺乏统一的逻辑校验标准。

4.2 冲突检测机制

冲突不会自己暴露出来,你需要主动检测。我在编排层设置了三个检测点:

第一个检测点是输出格式校验。每个 Agent 的输出都必须符合预定义的 schema,不符合就标记为异常。这个检测能发现大部分格式层面的冲突。

第二个检测点是交叉验证。对于关键结论,要求至少两个 Agent 独立验证。如果两个 Agent 的结论不一致,就触发冲突处理流程。比如分析 Agent 得出“竞品 A 市场份额第一”,审查 Agent 需要独立从数据中验证这个结论。

第三个检测点是一致性检查。在任务汇总阶段,检查所有 Agent 的输出是否逻辑自洽。比如报告里不能同时出现“市场增长 20%”和“市场萎缩 5%”这样的矛盾表述。

4.3 冲突解决策略与仲裁机制

检测到冲突后,怎么解决?我总结了四种策略,按优先级从高到低:

策略一:证据优先。如果冲突双方都能提供证据,比较证据的可信度和相关性,采信证据更强的一方。这要求每个 Agent 在输出结论时附带证据来源。

策略二:角色权威。如果冲突涉及专业判断,由对应角色的 Agent 做最终决定。比如格式问题由审查者决定,技术问题由执行者决定。这要求在角色定义时明确每个角色的决策权限。

策略三:协调者仲裁。如果前两种策略都无法解决,提交给协调者。协调者根据全局目标和当前状态做出裁决。协调者的裁决是最终决定,所有 Agent 必须服从。

策略四:人类介入。如果协调者也无法裁决,或者冲突涉及重大决策,暂停系统并请求人类介入。这是最后的手段,但必须有这个兜底机制。

注意:仲裁机制要写入每个 Agent 的系统提示词里。Agent 需要知道当自己和其他 Agent 冲突时,应该走什么流程,而不是自行其是。

4.4 冲突预防:比解决更重要

最好的冲突解决是不让冲突发生。我在项目里总结了几个预防措施:

统一数据源:所有 Agent 从同一个数据源获取信息,避免信息冲突。如果必须用多个数据源,给每个数据源标注可信度等级。

明确接口契约:Agent 之间的输入输出格式必须严格定义,用 JSON Schema 或者 TypeScript 类型来约束。接口变了要同步更新所有相关 Agent。

设置资源锁:对于共享资源,用锁机制来避免竞争。比如文件写入前先获取锁,写完释放。锁的粒度要细,避免一个 Agent 长时间占用资源。

定期同步状态:协调者定期向所有 Agent 广播当前全局状态,包括已完成的任务、正在执行的任务、待处理的任务。这样每个 Agent 都知道自己在整体中的位置。

5. 实操落地:从零搭建一个多智能体协作系统

5.1 技术选型与框架对比

动手之前先选框架。目前主流的多智能体框架有 AutoGen、CrewAI、AgentScope、LangGraph 等。每个框架的设计哲学不同,适合的场景也不同。

AutoGen 的优势是对话驱动,Agent 之间通过消息传递来协作,适合需要频繁交互的场景。CrewAI 的优势是角色定义清晰,内置了任务分配和流程管理,适合流程固定的场景。AgentScope 的优势是分布式支持好,适合大规模部署。LangGraph 的优势是图结构灵活,适合复杂编排逻辑。

我的建议是:如果你刚开始做多智能体,从 CrewAI 入手,它的抽象层次高,上手快。如果你需要精细控制通信过程,用 AutoGen。如果你要部署到生产环境,考虑 AgentScope 或者自研编排层。

5.2 一个完整的多智能体协作案例

我拿一个实际做过的项目来演示:搭建一个“技术调研报告生成系统”。系统包含四个 Agent:协调者、信息采集者、技术分析者、报告撰写者。

协调者的系统提示词核心部分是这样的:

COORDINATOR_PROMPT = """ 你是一个技术调研团队的协调者。你的职责是: 1. 接收用户的调研需求,拆解为具体任务 2. 将任务分配给合适的团队成员 3. 跟踪任务进度,处理异常 4. 汇总最终结果 团队成员及能力: - 信息采集者:擅长从公开资料中检索技术信息 - 技术分析者:擅长对比技术方案、分析优劣 - 报告撰写者:擅长将分析结果整理为结构化报告 任务分配规则: - 信息采集任务优先分配给信息采集者 - 分析任务必须等待信息采集完成后才能开始 - 报告撰写必须等待分析完成后才能开始 """

信息采集者的提示词里会强调输出格式:

COLLECTOR_PROMPT = """ 你是一个信息采集者。你的任务是收集指定技术主题的公开信息。 输出格式要求: { "topic": "技术主题", "sources": [ {"url": "来源链接", "title": "标题", "key_points": ["要点1", "要点2"]} ], "summary": "信息摘要" } 约束: - 至少收集 5 个来源 - 每个来源至少提取 2 个关键要点 - 不得编造信息,所有内容必须来自实际检索结果 """

技术分析者的提示词里会定义分析框架:

ANALYZER_PROMPT = """ 你是一个技术分析者。基于提供的信息,对比分析技术方案。 分析维度: 1. 核心原理与架构 2. 性能表现 3. 生态成熟度 4. 学习曲线 5. 适用场景 输出格式: { "comparison": [ {"dimension": "维度名", "analysis": "分析内容", "conclusion": "结论"} ], "recommendation": "推荐方案及理由" } 约束: - 每个维度的分析必须有信息采集者提供的数据支撑 - 如果信息不足,明确标注"信息不足,无法判断" """

5.3 编排层的核心逻辑实现

编排层负责调度所有 Agent,我用伪代码展示核心逻辑:

class MultiAgentOrchestrator: def __init__(self): self.agents = { "coordinator": CoordinatorAgent(), "collector": CollectorAgent(), "analyzer": AnalyzerAgent(), "writer": WriterAgent() } self.task_queue = [] self.completed_tasks = [] self.conflict_log = [] def run(self, user_request): # 第一步:协调者拆解任务 plan = self.agents["coordinator"].decompose(user_request) self.task_queue = plan.tasks # 第二步:按依赖顺序执行任务 while self.task_queue: task = self.task_queue.pop(0) # 检查依赖是否满足 if not self.dependencies_met(task): self.task_queue.append(task) continue # 分配任务给对应 Agent agent = self.agents[task.assignee] result = agent.execute(task) # 检查结果是否有效 if not self.validate_result(result, task): self.handle_invalid_result(task, result) continue # 检查是否有冲突 conflicts = self.detect_conflicts(result) if conflicts: resolved = self.resolve_conflicts(conflicts) if not resolved: self.request_human_intervention(conflicts) return self.completed_tasks.append(task) # 第三步:汇总结果 final_output = self.agents["coordinator"].summarize( self.completed_tasks ) return final_output

5.4 运行监控与日志记录

多智能体系统跑起来之后,你必须能监控它的运行状态。我在每个 Agent 的执行前后都加了日志记录,包括:输入、输出、耗时、token 消耗、异常信息。

日志格式我用的是结构化 JSON,方便后续分析:

{ "timestamp": "2024-01-15T10:30:00Z", "agent": "collector", "task_id": "task_001", "input": {"topic": "多智能体框架对比"}, "output": {"sources": [...], "summary": "..."}, "duration_ms": 3200, "tokens_used": 1500, "status": "success" }

监控面板上我重点关注三个指标:任务完成率平均执行时间冲突发生率。任务完成率低于 90% 说明目标设定或角色分配有问题;平均执行时间突然上升说明某个 Agent 遇到了瓶颈;冲突发生率上升说明通信机制或约束条件需要调整。

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

6.1 Agent 陷入无限循环怎么办

这是多智能体系统最常见的问题。两个 Agent 互相觉得对方输出有问题,反复要求对方修改,陷入死循环。

排查思路:先看日志,找到循环的起点。通常是某个 Agent 的输出没有满足另一个 Agent 的期望,但期望本身可能就不合理。比如审查者要求“所有结论必须有三个以上数据支撑”,但信息采集者只能找到两个数据点。

解决办法:设置最大迭代次数。我在编排层设置了每个任务最多修改 3 次,超过 3 次就强制通过或者上报协调者。同时,审查者的标准要可量化,不能是“足够好”这种模糊表述。

6.2 Agent 输出格式不一致怎么处理

不同 Agent 用不同模型时,输出格式很容易跑偏。比如一个 Agent 输出 JSON,另一个输出 Markdown 表格。

解决办法:在编排层加一个格式标准化模块。所有 Agent 的输出先经过这个模块,转换成统一的内部格式,再传递给下一个 Agent。格式标准化模块可以用规则引擎实现,也可以用一个小模型来做格式转换。

6.3 协调者成为瓶颈怎么优化

当 Agent 数量增多时,所有通信都经过协调者会导致协调者负载过高。

优化方案:引入分级协调。设置一个主协调者和多个子协调者,每个子协调者管理 2-3 个执行者。主协调者只和子协调者通信,子协调者和管理范围内的执行者通信。这样通信路径缩短,协调者负载分散。

6.4 常见问题速查表

问题现象可能原因排查方法解决方案
Agent 无限循环审查标准模糊、缺少迭代上限查看循环起点的日志设置最大迭代次数、量化审查标准
输出格式不一致模型差异、提示词不统一对比不同 Agent 的输出加格式标准化模块、统一提示词模板
协调者负载高通信拓扑中心化过度监控协调者响应时间引入分级协调、允许直接通信
任务完成率低目标拆解不合理、角色能力不匹配分析失败任务的日志重新拆解目标、调整角色分配
冲突频繁发生信息源不统一、约束条件不足统计冲突类型和频率统一数据源、增加约束条件
Agent 执行超时任务过于复杂、模型响应慢查看任务耗时分布拆分任务、更换模型、设置超时

6.5 几个踩坑后总结的实操心得

第一个心得:不要追求一次到位。我刚开始做多智能体的时候,总想设计一个完美的系统,结果调了两周还没跑通。后来改成先跑通最小闭环,两个 Agent 能协作完成一个简单任务就行,然后再逐步增加角色和复杂度。这样迭代速度快很多。

第二个心得:提示词要版本管理。每个 Agent 的提示词改动都要记录版本,因为改了一个 Agent 的提示词可能会影响其他 Agent 的行为。我用 Git 管理提示词文件,每次改动都写清楚原因和影响范围。

第三个心得:留好人工介入的接口。无论系统多智能,总会有它处理不了的情况。我在编排层留了一个“暂停并请求人工”的接口,当冲突无法解决或者任务连续失败时,系统会暂停并通知人工处理。这个接口救过我很多次。

第四个心得:测试要覆盖异常路径。正常流程跑通不代表系统稳定。我专门设计了一组异常测试用例:给 Agent 提供矛盾信息、让 Agent 调用失败的工具、模拟网络超时。这些测试能暴露很多正常流程发现不了的问题。

7. 多智能体系统的扩展方向

这套管理框架跑通之后,可以往几个方向扩展。一个是引入记忆机制,让 Agent 能记住历史交互,避免重复犯错。另一个是动态角色分配,根据任务类型自动调整 Agent 的角色和数量。还有一个是跨系统协作,让多个多智能体系统之间能够互相调用。

我在实际项目里体会最深的一点是:多智能体系统的管理逻辑和人类组织管理是相通的。目标设定对应 OKR,角色分配对应岗位设计,冲突解决对应沟通机制。你在管理人类团队时积累的经验,大部分都能迁移过来。反过来,做好多智能体系统管理,也能帮你更好地理解人类组织的运作方式。

最后分享一个小技巧:每次系统跑完一个复杂任务后,让协调者 Agent 生成一份“复盘报告”,记录哪些环节顺利、哪些环节卡顿、哪些冲突发生了。这份报告是你优化系统的最好依据。我坚持做这个复盘,三个月下来系统的任务完成率从 70% 提升到了 95% 以上。

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

双目散斑结构光技术全解析:从原理到工程落地

双目散斑结构光,这词听起来挺硬核的,但实际在国内做3D视觉、做深度相机的圈子里,已经算是很常见的技术路线了。我之前带项目做近距离三维重建的时候,一开始用普通双目相机,结果一到白墙、桌面这类弱纹理场景就抓瞎&…

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

GitHub热点项目怎么选?Python环境配置与项目跑通实战指南

1. 从热搜词反推:大家到底在找什么先把这批热搜词摊开看一遍,会发现一个很明显的分层。表层是"github打不开""github官网进不去""github访问不了""github镜像""github镜像网站""github国内镜像&…

作者头像 李华
网站建设 2026/9/20 17:59:52

手写Agent核心:从零搭建可运行的AI Agent系统

简介:面向软件开发者和AI学习者的一套可运行Agent系统源码包,提供从零搭建Agent系统的完整实践,涵盖系统从离线版向联机版升级、AI搜索、报告生成与笔记自动记录等典型场景,适合希望结合RAG与Agent做自动化工作流的Python开发者。…

作者头像 李华
网站建设 2026/9/20 17:59:33

浏览器里的开源云原生 GIS:GeoLibre 免安装工作流指南

浏览器里的开源云原生 GIS:GeoLibre 免安装工作流指南 【免费下载链接】GeoLibre A lightweight, cloud-native GIS platform for visualizing, exploring, and analyzing geospatial data. It runs in the web browser, on the desktop, on mobile, and inside Jup…

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

enzyme ReactWrapper.filterWhere 方法详解:基于谓词函数的节点过滤

enzyme ReactWrapper.filterWhere 方法详解:基于谓词函数的节点过滤 【免费下载链接】enzyme JavaScript Testing utilities for React 项目地址: https://gitcode.com/gh_mirrors/en/enzyme .filterWhere(predicate) 是 enzyme 中用于按自定义条件过滤 wrap…

作者头像 李华
网站建设 2026/9/20 17:57:20

车载SOA架构入门:从信号导向到SOME/IP与Adaptive Platform实战

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

作者头像 李华