使用ComfyUI可视化工作流调用SiameseAOE模型1. 引言如果你对ComfyUI的可视化节点编程感兴趣并且正在寻找将文本分析能力集成到工作流中的新方法那么这篇文章就是为你准备的。我们这次不聊图像生成而是探索一个更“智能”的方向如何让ComfyUI理解并提取文本中的关键信息。想象一下你有一段用户评论、一篇产品描述或任何包含观点和属性的文本。手动从中找出“手机”这个实体以及“拍照清晰”、“电池耐用”这些观点不仅耗时还容易遗漏。SiameseAOE模型就是专门解决这个问题的它能自动从非结构化文本中抽取出结构化的“属性-观点”对。但模型本身通常通过API调用如何让它无缝融入你熟悉的ComfyUI拖拽式工作流呢这就是我们今天要动手实现的目标。我将带你一步步在ComfyUI中创建一个自定义节点这个节点能向部署好的SiameseAOE服务发送请求并把返回的、像{手机: [拍照清晰, 电池耐用]}这样的结构化结果直观地展示在ComfyUI的界面上甚至可以用图形化的方式呈现出来。整个过程不需要你写复杂的后端逻辑只需要一些基础的Python和HTTP知识。跟着做下来你就能拥有一个从文本输入到观点可视化的端到端工作流。2. 环境准备与核心概念在开始动手之前我们需要确保环境就绪并理解几个关键概念。2.1 环境与前提条件首先确保你的ComfyUI已经正常安装并可以运行。这是我们的“画布”。其次你需要有一个已经部署好的SiameseAOE模型服务。这个服务应该提供一个HTTP API接口能够接收文本并返回属性-观点对的JSON格式结果。你可以自己用Flask、FastAPI等框架部署也可以使用云服务提供的端点。本文假设你的服务地址是http://localhost:8000/extract。你需要准备的基本工具是一个代码编辑器如VSCode。对Python有基本了解知道如何定义函数和类。了解HTTP POST请求的基本概念。2.2 核心概念快速理解为了不让后续的步骤显得突兀我们先花一分钟搞懂两个核心东西。SiameseAOE模型是做什么的你可以把它想象成一个高度专注的“文本信息提取器”。给它一段话比如“这款手机拍照很清晰但电池不太耐用。”它能自动识别出“手机”是实体属性然后找出描述它的观点“拍照清晰”正面和“电池不太耐用”负面。最终输出是结构化的数据方便程序进一步处理。ComfyUI自定义节点是什么ComfyUI的强大之处在于其模块化。每个功能块如图像加载器、采样器都是一个“节点”。自定义节点就是你自己编写的、具备特定功能的模块。它像乐高积木一样可以和其他官方或社区的节点连接在一起扩展ComfyUI的能力边界。我们今天要做的就是一个能“发送文本并接收分析结果”的新积木。3. 创建自定义HTTP请求节点这是最核心的一步我们将编写一个Python类让它成为ComfyUI认识的一个新节点。3.1 创建节点文件在你的ComfyUI安装目录下找到custom_nodes文件夹。如果没有可以创建一个。然后我们在里面新建一个文件夹例如叫做siamese_aoe_node。在这个文件夹里创建一个Python文件命名为nodes.py。这个nodes.py文件将包含我们自定义节点的所有代码。3.2 编写节点核心代码打开nodes.py让我们开始编写代码。我会逐段解释你可以直接复制使用。首先导入必要的库import requests import json import torch import comfy.sd from comfy.sd import CLIP import comfy.utils import folder_paths import nodes这里requests库用于发送HTTP请求json用于处理返回的数据其他是ComfyUI开发常用的一些导入。接下来定义我们最主要的节点类class SiameseAOEProcessor: 一个用于调用SiameseAOE模型服务并处理结果的ComfyUI自定义节点。 def __init__(self): pass classmethod def INPUT_TYPES(cls): 定义节点的输入参数类型。 return { required: { text: (STRING, {multiline: True, default: 请输入需要分析的文本例如这家餐厅环境优雅服务热情但菜品口味偏咸。}), api_url: (STRING, {default: http://localhost:8000/extract, multiline: False}), }, } RETURN_TYPES (STRING,) # 定义节点输出一个字符串 RETURN_NAMES (aoe_result,) # 定义输出在UI中的名字 FUNCTION process # 指定执行的主函数名 CATEGORY custom_nodes/siamese_aoe # 定义节点在菜单中的分类 def process(self, text, api_url): 核心处理函数发送文本到API并返回处理结果。 # 准备请求数据 payload {text: text} headers {Content-Type: application/json} result_string 请求失败或未返回有效结果。 try: # 发送POST请求 response requests.post(api_url, jsonpayload, headersheaders, timeout10) response.raise_for_status() # 检查HTTP请求是否成功 # 解析返回的JSON result_data response.json() # 将结果格式化为更易读的字符串 if result_data and isinstance(result_data, dict): formatted_lines [] for attribute, opinions in result_data.items(): if opinions: # 只显示有观点的属性 formatted_lines.append(f【{attribute}】) for opinion in opinions: formatted_lines.append(f - {opinion}) if formatted_lines: result_string \n.join(formatted_lines) else: result_string 未从文本中提取到有效的属性-观点对。 else: result_string API返回的数据格式不符合预期。 except requests.exceptions.RequestException as e: result_string f网络请求错误: {e} except json.JSONDecodeError as e: result_string f解析API响应错误: {e} except Exception as e: result_string f处理过程中发生未知错误: {e} # 返回结果字符串 return (result_string,)代码要点解释INPUT_TYPES方法定义了节点有两个输入。text是一个多行字符串输入框用于粘贴待分析的文本。api_url是单行字符串用于填写你的SiameseAOE服务地址。RETURN_TYPES和RETURN_NAMES指定这个节点输出一个类型为STRING的结果在UI界面上显示的名字叫aoe_result。process方法这是节点的“大脑”。它接收前端传来的text和api_url构造一个HTTP POST请求发送出去。收到响应后尝试解析JSON并将结构化的字典如{环境: [优雅], 服务: [热情], 菜品口味: [偏咸]}格式化成更易读的文本。错误处理代码用try...except包裹了网络请求和JSON解析确保即使API服务出错或网络不通节点也不会导致ComfyUI崩溃而是返回友好的错误信息。3.3 注册节点并测试为了让ComfyUI在启动时发现并加载我们的节点需要在siamese_aoe_node文件夹下创建一个__init__.py文件两个下划线内容如下from .nodes import SiameseAOEProcessor NODE_CLASS_MAPPINGS { SiameseAOEProcessor: SiameseAOEProcessor } NODE_DISPLAY_NAME_MAPPINGS { SiameseAOEProcessor: SiameseAOE 文本分析器 }现在重启你的ComfyUI。如果一切顺利在节点菜单的custom_nodes分类下或者你定义的siamese_aoe子分类下你应该能看到一个名为“SiameseAOE 文本分析器”的新节点。把它拖到画布上在text输入框里粘贴一段中文文本确保api_url正确指向你的服务然后连接一个Preview Text节点到它的输出点击“Queue Prompt”。如果API服务正常你就能在预览窗口看到格式化好的分析结果了。4. 进阶将结果可视化呈现仅仅输出文本可能还不够直观。ComfyUI的优势在于可视化我们可以更进一步将提取出的属性-观点对用图形的方式展现出来。这里提供一个思路创建一个生成简单关系图的节点。4.1 创建可视化节点思路与示例这个节点的目标是接收上一个节点输出的格式化字符串解析它然后生成一张简单的示意图。我们可以利用PILPython Imaging Library来画图。首先确保安装了Pillow库pip install Pillow。然后在同一个nodes.py文件中添加一个新的节点类from PIL import Image, ImageDraw, ImageFont import io class AOEVisualizer: 将SiameseAOE分析结果可视化为简单关系图的节点。 def __init__(self): pass classmethod def INPUT_TYPES(cls): return { required: { aoe_text_result: (STRING, {forceInput: True}), # 强制从上游节点输入 }, optional: { image_width: (INT, {default: 512, min: 256, max: 1024}), image_height: (INT, {default: 512, min: 256, max: 1024}), } } RETURN_TYPES (IMAGE,) RETURN_NAMES (visualization,) FUNCTION visualize CATEGORY custom_nodes/siamese_aoe def visualize(self, aoe_text_result, image_width512, image_height512): # 创建一个白色背景的图片 image Image.new(RGB, (image_width, image_height), colorwhite) draw ImageDraw.Draw(image) # 尝试加载一个字体如果系统没有则使用默认字体 try: font ImageFont.truetype(arial.ttf, 20) except IOError: font ImageFont.load_default() # 解析输入的文本结果 # 简单解析逻辑寻找【属性】和随后的 - 观点 lines aoe_text_result.split(\n) attributes [] current_attribute None for line in lines: line line.strip() if line.startswith(【) and line.endswith(】): current_attribute line[1:-1] # 去掉括号 attributes.append({name: current_attribute, opinions: []}) elif line.startswith(-) and current_attribute is not None: opinion line[1:].strip() for attr in attributes: if attr[name] current_attribute: attr[opinions].append(opinion) break # 简单的绘图逻辑在图片上画属性框和观点连线 y_offset 30 for attr in attributes: # 画属性框 attr_bbox [50, y_offset, 150, y_offset40] draw.rectangle(attr_bbox, outlineblue, width2) draw.text((attr_bbox[0]10, attr_bbox[1]10), attr[name], fillblack, fontfont) # 画观点 op_x_start 200 for i, opinion in enumerate(attr[opinions]): op_y y_offset 20 op_x op_x_start i * 180 if op_x image_width - 100: draw.ellipse([op_x, op_y, op_x100, op_y30], outlinegreen, width2) draw.text((op_x10, op_y5), opinion[:10]... if len(opinion)10 else opinion, filldarkgreen, fontfont) # 画连线 draw.line([attr_bbox[2], attr_bbox[1]20, op_x, op_y15], fillgray, width1) y_offset 80 # 如果没有解析到内容显示提示 if not attributes: draw.text((50, 50), 未解析到可可视化的数据, fillred, fontfont) # 将PIL Image转换为ComfyUI兼容的IMAGE tensor格式 # 这里需要根据ComfyUI的utils进行转换以下为示例逻辑 image image.convert(RGB) import numpy as np image_np np.array(image).astype(np.float32) / 255.0 image_tensor torch.from_numpy(image_np)[None,] return (image_tensor,)这个节点做了什么输入它强制要求输入来自上一个SiameseAOEProcessor节点的aoe_result字符串。解析它尝试解析格式化的文本提取出属性和观点。绘图它在画布上用蓝色矩形代表“属性”用绿色椭圆代表“观点”并用灰色线条将它们连接起来。输出最终输出一个ComfyUI的IMAGE张量你可以把它连接到Save Image节点保存下来。现在你的工作流就可以串联起来了文本输入-SiameseAOEProcessor分析-AOEVisualizer绘图-Save Image保存。一个完整的文本分析到可视化的流程就构建完成了。5. 构建完整工作流与实用技巧有了两个核心节点我们就可以在ComfyUI中搭建一个完整的一站式工作流。5.1 串联工作流在ComfyUI中首先拖入SiameseAOE 文本分析器节点。在节点的text输入框内粘贴或输入你想要分析的长文本。确保api_url正确无误。拖入AOE 结果可视化器节点如果你创建了的话。将分析器节点的aoe_result输出连接到可视化器节点的aoe_text_result输入。拖入一个Preview Text节点连接到分析器节点的输出用于查看原始文本结果。拖入一个Save Image节点连接到可视化器节点的visualization输出。点击 “Queue Prompt”等待处理完成。你既可以在预览窗口看到文本结果也可以在输出目录找到生成的关系图图片。5.2 一些实用技巧与问题排查API服务稳定性自定义节点依赖于外部HTTP服务。确保你的SiameseAOE服务稳定运行并且网络可达。在节点的错误处理中我们已经加入了超时和异常捕获但服务端错误仍需自行排查。结果格式化当前节点将API返回的字典简单格式化为文本。你可以根据喜好修改process方法中的格式化逻辑比如改成表格形式、添加情感极性标签等。性能考虑HTTP请求是I/O操作可能会成为工作流的瓶颈。如果处理大量文本可以考虑在节点内实现简单的请求队列或使用异步方式但这会增加复杂度。对于大多数轻量级应用当前方式已足够。字体问题可视化节点中使用了系统字体“arial.ttf”在Linux服务器或无此字体的环境下可能失败。ImageFont.load_default()会回退到基础字体但可能不支持中文。解决方案是指定一个绝对路径的字体文件如中文字体或者将字体文件放在插件目录内引用。节点调试如果节点没有出现检查custom_nodes文件夹结构是否正确以及__init__.py文件是否存在且格式正确。查看ComfyUI启动时的命令行输出通常会有加载自定义节点的日志信息。6. 总结通过这次实践我们把一个独立的文本分析API成功地“嫁接”到了ComfyUI这个强大的可视化工作流平台上。你不仅学会了一个创建自定义HTTP请求节点的方法更重要的是掌握了一种思路任何可以通过API调用的服务无论是AI模型、数据库查询还是其他Web服务都有潜力被集成到ComfyUI的可视化编程环境中。这个SiameseAOEProcessor节点只是一个起点。你可以基于这个模式开发出调用其他NLP模型如情感分析、关键词提取、摘要生成的节点甚至可以连接多个服务构建更复杂的文本处理流水线。ComfyUI的开放性为我们提供了无限的可能性将不同的AI能力像搭积木一样组合起来去解决更实际、更复杂的问题。动手试试吧从分析一段产品评论开始看看可视化出来的属性和观点是否和你理解的一致。在这个过程中你可能会对如何改进节点有新的想法比如增加批量处理功能或者美化可视化图表这正是开源和自定义的魅力所在。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。