ComfyUI 全面技术教程:节点式Stable Diffusion工作流完全指南

ComfyUI 全面技术教程:节点式Stable Diffusion工作流完全指南

前言

ComfyUI 是由 Comfy-Org 社区维护的开源项目(GitHub 星标数超过 112,000),代表了当前 AI 图像生成领域最具工程深度和灵活性的用户界面范式。与传统的一键式图形界面不同,ComfyUI 采用节点图(Node Graph)架构,将 Stable Diffusion 及其他扩散模型的每一个计算步骤抽象为独立节点,用户通过连线组合这些节点来构建完整的工作流。这种设计赋予了 ComfyUI 几乎无限的可定制性,同时也对用户提出了更高的技术理解要求。本文将深入解析 ComfyUI 的核心概念、工作流系统、模型管理机制、与其他主流 SD 界面的横向对比、自定义节点开发以及 API 程序化调用,力求为读者提供一份具有工程视角的技术参考。

一、节点图架构与核心概念详解
1.1 有向无环图与数据流

ComfyUI 的核心是节点图引擎。每一个节点代表一个独立的计算单元,具有输入端口(Input)和输出端口(Output)。数据(张量、图像、文本、条件向量等)沿连线从上游节点流向下游节点,形成一个有向无环图(DAG)。这种架构天然地契合扩散模型的分步采样过程——噪声添加、UNet 去噪、潜空间操作、VAE 编解码等各个环节均对应独立的节点。

理解 DAG 的运作机制对掌握 ComfyUI 至关重要。当用户点击 “Queue Prompt” 时,ComfyUI 的执行引擎从没有输入依赖的节点(即图中入度为 0 的节点,如 CheckpointLoader 和 EmptyLatentImage)开始执行,按照拓扑顺序依次激活各节点。每个节点完成计算后,结果通过连线传递给下游节点。这一机制确保了计算顺序的正确性,同时也天然支持并行执行——没有数据依赖关系的节点可以同时在不同的线程或进程中运行。

1.2 核心节点类型全面解析

ComfyUI 内置了数百种基础节点,涵盖以下核心类别:

采样器节点(Samplers) 是工作流的核心动力单元。KSampler 是最常用的采样器,它接受模型(model)、正面提示词条件(positive)、负面提示词条件(negative)、_latent(潜空间图像)、步数(steps)、CFG 引导强度、Sampler 名称和调度器参数,输出处理后的 _latent 对象。不同的采样算法——Euler、Euler Ancestral、DPM++ 2M Karras、DPM++ 2M SDE、DPM++ 3M SDE、DDIM、LCM 等——代表了不同的噪声调度策略,各有其收敛速度和生成质量特性。LCM(Latent Consistency Model)采样器是近年来的重要突破,能够在 4-8 步内完成高质量生成,速度比传统 Euler 需要 20-30 步快数倍。

KSamplerAdvanced 提供了更精细的控制,包括降噪计划(denoise_schedule)的自定义设置。启用 “return_with_leave” 选项可以在采样中途输出中间结果,这对于需要渐进式预览的教学和调试场景非常有用。

模型加载节点(Loaders) 负责将预训练权重注入工作流。CheckpointLoader 从 .safetensors 或 .ckpt 文件加载完整模型(包含 UNet、VAE、CLIP 文本编码器),输出为包含 modelclipvae 三个键的复合字典。CLIPLoader 和 VAELoader 则可单独加载特定组件,这在需要替换默认编码器或使用自定义 VAE 时尤为重要。例如,当处理某些对 VAE 敏感的图像内容时,使用 Stability AI 官方发布的 VAE 而非模型内置的 VAE 往往能获得更好的重建质量。

条件与提示词节点(Conditioning) 处理文本到向量的编码过程。CLIPTextEncode 是文生图工作流中不可或缺的核心节点,它将自然语言编码为条件向量,供 KSampler 在去噪过程中参考。CLIPSetLastLayer 用于控制编码的层级深度——使用倒数第二层而非最后一层有时能获得更语义化的表示。CLIPVisionEncode 和 CLIPVision影像条件化节点则处理图像输入,用于 IP-Adapter、ControlNet 等需要图像参考的场景。

负面提示词通过独立编码路径与正面提示词在 KSampler 中合并,共同影响去噪方向。这一机制是引导模型避免生成特定元素(如低质量、变形、水印等)的核心手段。高级用法包括使用 AttentionCouple 节点或 String Function 节点实现局部的正面/负面条件控制——例如让”眼睛”这个概念在图像特定区域产生正面效果,而在其他区域产生负面效果。

潜空间操作节点(Latent) 在图像的潜空间表示上进行操作。EmptyLatentImage 创建初始纯噪声作为去噪起点;LatentComposite 将多个潜空间图像按 alpha 通道或位置坐标混合;LatentRotate、LatentFlip 执行几何变换;LatentUpscale 在潜空间进行上采样(通常配合 KSampler 的后续处理以提升细节);LatentCrop 裁剪潜空间区域。这些操作的计算代价远低于像素空间操作,是扩散模型高效处理高分辨率图像的技术基础。

图像编码/解码节点 桥接像素空间与潜空间。VAEDecode 将 KSampler 输出的 _latent 解码为可视图像;VAEEncode 执行反向操作(将真实图像编码为潜空间表示);VAEEncodeTiled 用于超大图像的分块编码以避免显存溢出;SaveImage 将张量序列化至磁盘;LoadImage 从文件系统读取图像。在 I/O 密集型工作流中,这些节点往往是性能瓶颈所在,优化存储 I/O 可以显著缩短整体处理时间。

1.3 张量数据类型与节点连接

理解节点的数据流本质至关重要。在 ComfyUI 中,节点之间传递的不是像素值,而是 PyTorch 张量——通常是形状为 (batch, channel, height, width) 的四维张量。在像素空间,图像张量形状为 (batch, 3, H, W);在潜空间下采样 8 倍后为 (batch, 4, H/8, W/8),这正是大多数 SD 模型的原生处理维度。

节点端口的类型通过字符串字面量标识:IMAGE(像素空间图像张量)、LATENT(潜空间张量)、MODEL(UNet 模型)、CLIP(文本编码器)、VAE(变分自编码器)、STRING(字符串)、INT(整数)、FLOAT(浮点数)、BOOLEAN(布尔值)、CONDITIONING(条件向量)。只有类型匹配的端口才能建立连接,这一约束在工程层面防止了类型错误,同时帮助用户理解数据转换的逻辑顺序。

二、工作流系统:复用、版本管理与高级特性
2.1 工作流的序列化和格式

ComfyUI 的工作流以 JSON 格式序列化,文件扩展名为 .json。一个工作流文件完整记录了图中所有节点的类型、参数值、节点位置(x, y 坐标)以及连接关系(通过 links 数组描述源节点、源端口、目标节点、目标端口)。这种自包含的序列化格式使得工作流可以被完整地版本化——将 .json 文件提交到 Git 仓库,即可持续追踪工作流的每一次修改。

点击右侧面板的 “Save” 按钮可将当前工作流导出为模板;”Load” 按钮则从文件或剪贴板恢复工作流。ComfyUI Manager 插件进一步提供了工作流的云端存储与分享机制,用户可以直接从 GitHub 或社区服务器拉取他人分享的工作流文件。社区平台如 OpenComfyUI 和 ComfyWorkflows.com 托管了大量预构建工作流,涵盖从简单的文生图到复杂的多阶段处理管线。

2.2 工作流的模块化与子工作流

工作流复用是 ComfyUI 的核心优势之一。一个经过调优的采样参数组合(Checkpoint + 采样器 + 步数 + CFG + 提示词)可以封装为一个可复用的模板。这意味着用户无需每次从头配置复杂参数,仅需调整输入提示词即可生成风格一致的作品。

ComfyUI 支持子工作流(Subgraph) 的概念,允许将一组节点打包为一个逻辑单元。通过第三方节点(如 pysss workflow group 或 comfyui-manager 提供的功能),用户可以创建可复用的节点组,并在多个工作流中引用。核心团队也在探索更原生的节点分组与封装机制,预计在未来版本中提供正式的工作流模块化支持。

2.3 版本兼容性与环境管理

工作流的版本兼容性是需要关注的工程问题。ComfyUI 核心库的 API 相对稳定,但第三方自定义节点可能随版本迭代引入 breaking change——新增或删除输入端口、改变数据类型、修改节点标识符等都会导致旧工作流无法正常加载。

建议在生产环境中采用以下策略:首先,通过 ComfyUI Manager 的版本锁定功能,固定核心库和所有已安装自定义节点的 git commit;其次,在工作流 JSON 文件的元数据区域(nodes 字典的元信息字段)记录 ComfyUI 版本、自定义节点版本、关键模型信息等;第三,建立工作流的变更记录,通过 Git 分支管理不同版本的工作流资产。这套实践在团队协作环境中尤为重要——确保所有成员加载同一版本的工作流,避免”在我的机器上能跑”的环境差异问题。

三、模型管理:目录结构、加载机制与高级配置
3.1 标准的目录组织

ComfyUI 采用约定优于配置的文件组织策略。模型文件默认存放在 ComfyUI/models/ 目录下的多个子目录中,每个子目录对应一类模型资产:

ComfyUI/models/
├── checkpoints/      # 基础模型(SD 1.5, SDXL, SD 3, etc.)
├── vae/               # VAE 模型文件(通常为 .safetensors 或 .pt 格式)
├── loras/             # LoRA(Low-Rank Adaptation)权重文件
├── controlnet/        # ControlNet 模型(控制网络条件化)
├── clip/              # 独立文本编码器模型
├── embeddings/        # Textual Inversion 词嵌入文件(.pt 或 .safetensors)
├── upscale_models/    # 超分辨率模型(如 ESRGAN、SwinIR 系列)
└── diffusers/         # HuggingFace Diffusers 格式模型目录

3.2 模型加载流程与性能考量

模型发现机制依赖目录扫描和元数据缓存。ComfyUI 在启动时遍历各子目录,建立可用模型清单(名称、路径、大小、修改时间)并缓存在内存中。当 CheckpointLoader 节点指定某个模型名称时,系统在 models/checkpoints/ 目录中定位对应的 .safetensors 或 .ckpt 文件并通过 safetensors 库(或 PyTorch 的 torch.load)加载。

.safetensors 格式相比传统 .ckpt 有三个显著优势:第一,安全性更高——safetensors 仅包含张量数据,不支持序列化任意 Python 对象,因此不可能携带恶意代码;第二,内存映射支持——safetensors 支持无需完整加载即可按需读取张量片段,大幅减少初始加载时间和内存占用;第三,加载速度更快——safetensors 的二进制布局针对现代存储设备优化,I/O 效率显著优于 pickle 格式。

模型预热(Warmup) 是一个常被忽视但对交互体验影响显著的因素。首次加载某个 Checkpoint 到 GPU 显存需要数秒至数十秒不等(取决于模型规模:SD 1.5 约 2-4GB,SDXL 约 6-8GB,SD 3 约 8-12GB)。这对于需要频繁切换模型的创作流程是显著的效率瓶颈。解决方案包括:预先在后台加载常用模型(ComfyUI 支持同时加载多个 Checkpoint 到显存池);使用 –preload-models 参数在启动时自动加载指定模型;或者使用模型缓存插件实现 LRU 策略的模型复用。

3.3 自定义路径与共享模型库

对于需要共享模型库的多实例部署场景,可通过启动参数 –extra-model-paths 或配置文件 extra_model_paths.yaml 指定额外搜索路径:

# extra_model_paths.yaml 示例
shared_models:
  base: /mnt/storage/stable-diffusion/models
  checkpoints: checkpoints
  vae: vae
  loras: loras
  controlnet: controlnet

这一配置在团队环境或服务器部署中非常有用——所有 ComfyUI 实例可以共享同一个模型目录,避免重复存储,同时确保不同用户使用相同的模型版本。

对于 HuggingFace Diffusers 格式的模型,ComfyUI 提供了 DiffusersLoader 节点,可直接从 Hub(需要网络访问)或本地目录加载 Diffusers 格式的模型工件。这为使用社区微调模型(如 Run Diffusion、Xlabs、Civitai 导出的 Diffusers 版本等)提供了便利。

3.4 半精度与显存优化

ComfyUI 支持通过启动参数 –force-fp16 或 –fp16 将模型权重预转换为半精度(FP16)格式。FP16 精度对绝大多数生成任务影响微乎其微,但可以将显存占用减半(SDXL 从约 8GB 降至约 4GB),同时提升矩阵运算吞吐量。对于显存受限的消费级显卡(如 8GB VRAM 的 RTX 3070/4060 Ti),强制启用 –lowvram 模式可将完整模型分块驻留,按需调度到 GPU——代价是增加数据在 CPU-GPU 之间的拷贝开销,生成速度可能降低 20-40%。

–normalvram 模式是介于 –fp16 和 –lowvram 之间的折中方案,将 VAE 等非核心组件始终保留在 GPU 显存中,仅在必要时卸载 UNet 到系统内存。

四、与其他主流 Stable Diffusion WebUI 的横向对比

当前主流的 Stable Diffusion 图形界面包括 Automatic1111 WebUI(简称 A1111)、SD WebUI Forge、以及 ComfyUI。以下从架构设计、工作流能力、性能表现和生态扩展性四个维度进行技术对比。

| 维度 | ComfyUI | Automatic1111 | SD WebUI Forge |

|——|———|—————|—————-|

| 架构范式 | 节点图(DAG) | 传统 Web 表单 | 基于 A1111 的优化分支 |

| 工作流复用 | 原生 JSON + 节点组合 | Prompt 模板 + 脚本 | 继承 A1111 生态 |

| 显存占用 | 最低(按需调度) | 较高(全模型常驻) | 中等(优化后略低) |

| 批处理能力 | 原生多 Latent 批处理 | 需启用高显存模式 | 继承 A1111 限制 |

| 扩展机制 | 自定义节点(Python) | 扩展脚本(Python) | 扩展脚本 + 优化 |

| API 支持 | 原生 REST + WebSocket | 提供(需启用) | 提供(需启用) |

| 上手门槛 | 最高 | 中等 | 中等 |

| 模型格式 | safetensors/ckpt/diffusers | safetensors/ckpt | safetensors/ckpt |

Automatic1111 的优势在于生态成熟度和即装即用的便捷性。其 ControlNet、百川等扩展生态经过多年打磨,UI 交互高度优化,适合快速原型和日常创作。A1111 的扩展(Extension)系统允许开发者通过 Python 脚本拦截请求、修改图像后处理流程,但扩展的加载时机和生命周期管理较为复杂,偶尔会出现依赖冲突。

A1111 的局限性在于其工作流本质上是线性脚本——用户通过填写表单配置参数,服务器按固定顺序执行”加载模型→编码提示词→采样→解码→保存图像”。这种模式缺乏对复杂多阶段生成流程的图形化表达。当需要构建包含多个分支、循环、条件判断的工作流时,A1111 需要借助 external script 或自定义脚本,代码与 UI 分离,调试和维护困难。

SD WebUI Forge 是 A1111 的性能优化分支,通过显存管理和计算调度层面的改进降低了硬件门槛。Forge 重新设计了模型切分策略,使 SDXL 能够在 6GB 显存环境下运行。Forge 还引入了注意力机制优化(xformers 的替代方案)和更激进的显存回收策略。然而,Forge 的本质仍是线性流程,与 A1111 共享扩展生态,不具备 ComfyUI 的节点化架构带来的深度定制能力。

ComfyUI 的核心差异化价值在于其架构的透明性和表达力。节点图不仅是一个 UI 交互方式,更是一种计算过程的文档化表达——打开一个陌生工作流文件,可以直观看到图像是如何从纯噪声经过一系列变换得到的。这种透明度在研究和生产场景中具有不可替代的价值:研究人员可以精确复现生成条件,工业流水线可以将工作流作为可版本化的生产工件,法官/律师可以用工作流作为生成证据的技术说明。

然而,ComfyUI 的高门槛是不可回避的现实。节点图的连线方式要求用户理解扩散模型的计算图结构,这比填写表单需要更系统的领域知识。建议初学者从简单的内置示例(如 SD 1.5 基础文生图)开始,逐步扩展到 ControlNet、IP-Adapter、LoRA、ComfyUI Manager 等高级功能。

五、自定义节点开发:从入门到进阶
5.1 节点开发基础

ComfyUI 的可扩展性建立在 Python 节点开发框架之上。每一个自定义节点是一个 Python 类,通过 @register_node 装饰器注册到 ComfyUI 的节点注册表。节点需实现两个核心方法:

  • INPUT_TYPES(): 返回一个字典,定义该节点的输入端口配置,包括每个端口的类型、默认值、可选范围(min/max)、是否必需等
  • FUNCTION(): 执行实际计算逻辑,输入为 self 和从各端口接收的参数字典,返回值需匹配 OUTPUT_TYPES 中声明的输出
  • import torch
    from nodes import CoreNodes
    
    class CustomLatentMultiply:
        @classmethod
        def INPUT_TYPES(cls):
            return {
                "required": {
                    "latent": ("LATENT",),
                    "multiplier": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0}),
                }
            }
    
        RETURN_TYPES = ("LATENT",)
        FUNCTION = "multiply"
        CATEGORY = "custom/operations"
    
        def multiply(self, latent, multiplier):
            samples = latent["samples"]
            modified = samples * multiplier
            return ({"samples": modified},)

    将该文件放置在 ComfyUI/custom_nodes/ 目录下的独立包中(如 ComfyUI/custom_nodes/my_custom_nodes/__init__.py),重启后节点即出现在搜索面板中。

    5.2 类型系统与端口验证

    自定义节点的类型系统是保证节点图可验证的关键。ComfyUI 使用字符串字面量标记数据类型(IMAGE, LATENT, MODEL, CLIP, VAE, STRING, INT, FLOAT, BOOLEAN 等)。节点连线时,类型系统会实时验证上游输出与下游输入的兼容性,不匹配则拒绝连接并高亮显示错误。这在工程层面防止了运行时类型错误,是节点图系统稳定性的重要保障。

    对于复合类型(如 LATENT 实际上是包含 “samples” 键的字典),节点代码需要在 FUNCTION 中正确解包和重新组装。

    5.3 高级节点:外部依赖与 GPU 操作

    对于涉及第三方依赖(如 PyTorch 扩展、CUDA 自定义算子、OpenCV、SciPy 等)的节点,需要确保依赖在 ComfyUI 的 Python 环境中可用。推荐通过虚拟环境或 conda 环境隔离管理依赖,避免与系统包冲突。在节点代码中,应在模块顶部进行可选导入并提供有意义的错误提示:

    try:
        import cv2
    except ImportError:
        cv2 = None
    
    class OpenCVProcessor:
        @classmethod
        def INPUT_TYPES(cls):
            return {"required": {"image": ("IMAGE",)}}
    
        RETURN_TYPES = ("IMAGE",)
        FUNCTION = "process"
    
        def process(self, image):
            if cv2 is None:
                raise RuntimeError("OpenCV (cv2) is required for this node. Install with: pip install opencv-python")
            # ... actual processing

    涉及 GPU 计算的自定义节点应遵循以下最佳实践:使用 torch.cuda.is_available() 检测 CUDA 可用性;将张量显式移动到目标设备(tensor.to(device));在批量处理时优先使用向量化操作而非 Python 循环;使用 torch.inference_mode() 禁用梯度追踪以降低显存占用。

    六、API 程序化调用:REST、WebSocket 与批量处理
    6.1 REST API 核心端点

    ComfyUI 原生提供了完整的 REST API,默认运行在 http://localhost:8188。核心端点包括:

  • GET /system_stats — 查询 GPU 显存占用、当前队列状态和系统资源
  • GET /model_list — 列出可用模型清单(按类型分组)
  • GET /model_list/loaded — 仅列出当前已加载到显存的模型
  • POST /prompt — 提交新任务至生成队列,Request Body 为 JSON 格式的工作流对象
  • POST /prompt_interrupt — 中断当前正在执行的任务
  • GET /history — 获取最近任务历史(可指定范围)
  • GET /history/{prompt_id} — 查询特定任务的结果(包含输出图像路径、生成参数、执行时间)
  • GET /object_info — 获取所有节点类型的元数据(输入输出端口定义、默认值)
  • GET /object_info/{node_type} — 获取特定节点类型的元数据
  • 6.2 工作流对象的结构

    提交到 /prompt 的工作流对象是一个以节点 ID 为键的字典,每个节点包含 inputs(输入参数映射)和 class_type(节点类型)。连接关系通过特殊的 [“节点ID”, 端口索引] 数组形式表达——例如 clip: [“1”, 1] 表示从节点 1 的第 1 个输出端口连接到当前节点的 clip 输入。

    6.3 WebSocket 实时通知

    WebSocket 连接 ws://localhost:8188/ws 提供了任务执行过程中的实时事件流。服务器推送以下消息类型:

  • `executed` — 节点执行完成,包含节点 ID 和输出数据(对于 SaveImage 等节点包含文件路径)
  • `executing` — 节点开始执行,包含节点 ID
  • `progress` — 采样步数更新,包含当前步数和总步数
  • `mdistry` — 队列状态变更
  • `done` — 整个工作流执行完成
  • `error` — 执行过程中发生的错误
  • 客户端可据此实现近乎实时的进度条、中间结果预览(通过定时查询当前 latent 状态)和错误恢复机制。

    6.4 批量处理与队列管理

    API 层面的批量处理有两种策略:第一,提交包含多个独立分支的单个工作流(各分支共享相同的模型加载节点以避免重复加载),在一次请求中并行生成多张图像;第二,提交多个独立任务到队列(queue),利用 /queue 端点管理和排序任务优先级。ComfyUI 的队列支持任务取消和清空。

    6.5 安全最佳实践

    ComfyUI 本身不提供认证层,API 在默认配置下仅监听 localhost。在需要远程访问或公网暴露时,强烈建议通过反向代理(Nginx/Caddy)添加 HTTP Basic Auth 或 JWT 验证,配置 TLS 加密,并使用防火墙规则限制 API 端口仅对信任的网络段开放。避免在公网直接暴露未认证的 ComfyUI API 实例。

    七、性能优化与最佳实践
    7.1 显存优化的层次

    –lowvram 模式通过将 UNet 的不同组件(Encoder/Decoder/Model Parts)分块调度,在 CPU 和 GPU 之间按需传输,大幅降低峰值显存占用,但代价是增加数据拷贝开销和时间。对于 8GB 以下显存的显卡,强制启用 –lowvram 是运行 SDXL 的必要条件。在 –lowvram 模式下,VAE 也通常被卸载至系统内存,编码/解码操作会显著变慢。

    更高级的显存优化策略包括:使用半精度(FP16)模型权重;启用 –cpu(完全在 CPU 运行,速度极慢但显存需求最低);分离 VAE 处理以避免与 UNet 争抢显存。

    7.2 批处理最大化吞吐量

    在 EmptyLatentImage 节点设置 batch_size > 1,KSampler 会并行处理多个样本。GPU 在 batch 维度的并行计算效率通常很高——batch_size 从 1 增加到 4 的过程中,生成时间增加通常不超过 50%,等价于吞吐量提升超过 2 倍。批处理与 Latent 放大(Latent upscale)组合,可在单次生成中获得多张不同变体。

    7.3 缓存与预加载

    –preload-models 参数允许在启动时自动加载指定模型到显存,避免首次使用时的加载延迟。对于稳定的创作流程,可将常用模型常驻显存(忽略 –lowvram),代价是显存占用增加。模型缓存插件(如 ComfyUI Manager 中的模型缓存功能)提供了 LRU 策略的模型管理。

    7.4 异步队列与自动化

    ComfyUI 的队列支持任务排序和批量提交。将大量生图任务预先编排为工作流队列,通过 API 批量提交,可在夜间或空闲时段自动化执行。队列状态可通过 /history 和 /queue 端点查询和操控。结合 Python 的 asyncio 库和 httpx 的异步 HTTP 客户端,可以构建高性能的自动化生图流水线。

    八、总结

    ComfyUI 代表了 AI 图像生成工具的工程化方向:节点图架构提供了透明、可复用、可版本化的计算工作流;张量级的数据流抽象与现代深度学习框架无缝衔接;开放的节点扩展机制使社区生态得以快速迭代。在当前 SD 工具生态中,ComfyUI 是最能兼顾研究严谨性与生产实用性的选择。

    掌握 ComfyUI 不仅是学会一个工具的使用方法,更是深入理解扩散模型计算图结构的过程。从节点连接到工作流设计,从 API 集成到自定义节点开发,每一个环节都值得投入时间去系统学习。建议读者从本文的基础概念出发,在实践中逐步构建自己的节点知识库和工作流资产库,最终形成高效、可靠的个人创作或生产流水线。

    如果内容对您有帮助,欢迎打赏

    您的支持是我继续创作的动力

    前往打赏页面

    评论区

    发表回复

    您的邮箱地址不会被公开。 必填项已用 * 标注