AI_Qwen_skill
A Qwen chat model inside your graph, with your own skill files bolted on
- media
- media_1
- media_2
- media_3
- media_4
- media_5
- media_6
- media_7
- media_8
- media_9
- media_10
- media_11
- media_12
- media_13
- media_14
- media_15
- media_16
- media_17
- media_18
- media_19
- media_20
- result
Most custom nodes add a model to your GPU. This one adds a model to the internet. AI_Qwen_skill takes text - and optionally up to twenty images, videos or strings - sends it to Alibaba's DashScope (Bailian) endpoint, and hands back a single result string. Nothing downloads, nothing sits in VRAM, and every queue you hit costs a call.
So why would you reach for it? Because prompt writing is the part of the pipeline where a language model genuinely helps, and this one arrives inside the pack you already installed rather than as a separate Ollama server, GGUF file and unload dance. Feed it a rough idea, get back a structured prompt for a CLIP text encode. The @Image 1 / @Video 2 / @Text 1 references in the text box are what make it more than a text box: they point at whatever you've wired into media through the pack's media hub, so the model actually looks at the plate before it writes about it.
The skill folder is the real feature
Everyone bolts an LLM call onto ComfyUI. What's unusual here is the skill dropdown, which reads a folder the rest of the pack doesn't use: ComfyUI/models/skills. Drop a .md, .txt, .json, .yaml, .yml or .rst file in there and it appears as an option; drop in a folder and it shows as foldername/, with skill.md sorted first and every text file in it concatenated in order. Whatever it finds gets pasted into the system message, ahead of your instructions and your conversation history.
It's an Anthropic-style agent skill applied to diffusion work: a checked-in file that says "for Flux prompts, output this shape, never tag soup, never (word:1.4)" - editable without touching Python. The default option, 不使用技能, means no skill, and picking an empty or missing one gives you an error rather than a silent no-op. The widget values, mode names and error strings are Chinese throughout; the pack's docs are bilingual, the node isn't.
Inputs and outputs that matter
text is your instruction, multiline. llm_model is a two-option dropdown - Qwen3.8-Max, or 自定义 ("custom"), which reveals custom_model for any other DashScope model name. api_key is the one to think about: leave it empty and the node falls back to the DASHSCOPE_API_KEY or aliyun_API_KEY environment variable, and only then to an ApiKey_AI_Qwen.txt file beside the node. Prefer one of those. A key typed into the widget gets serialized into your workflow JSON, which is how people hand out their billing credentials alongside a workflow.
output_mode decides what the output does. 实时输出 ("live") means result updates with every answer as you chat. 仅对话 ("conversation only") means result holds still until you hit 采用本轮 ("adopt this turn") in the node's own panel, which queues the graph with conversation_action set to adopt. That panel is what writes conversation_history, committed_result and conversation_action, so you never hand-edit those; the transcript caps at the last 12 turns and resets when you change the skill or model.
One output: result, a STRING. Wire it into a text encode node, a save-text, anything that eats a prompt.
Install
ComfyUI Manager, search "ComfyUI-Apt_Preset", or:
cd ComfyUI/custom_nodes
git clone https://github.com/cardenluo/ComfyUI-Apt_Preset.git
# then, with ComfyUI's own python:
pip install -r ComfyUI-Apt_Preset/requirements.txt
Restart ComfyUI. A blunt warning: this pack is huge, and its requirements.txt covers all of it - opencv-python-headless, onnxruntime, transparent-background, gguf, scenedetect. This node needs none of that; it runs on requests, numpy and Pillow, which base ComfyUI already has. On Windows the README sends you to the .bat, which is a copy-paste job from another project - it still prints "Installing TECHNONATOR IMAGE PADDING". Get a key from Alibaba Cloud Model Studio, set it in the environment, done.
Where people get burned
Errors don't crash your graph. The node catches its own exceptions and returns them as text - 执行失败:请填写 API Key and friends - or, in 仅对话 mode, quietly re-emits the last committed result. Nothing goes red, so an API failure lands in your conditioning as a literal error sentence. Check the node's conversation panel when output looks wrong.
Anything visual changes the endpoint, not the model name. Attach an image or video and the request goes to DashScope's multimodal-generation URL, with whatever name is in llm_model/custom_model still attached. Point that at a text-only model and the call fails - so if image input matters, pick a vision-capable one. Images are downscaled to 1536px and sent as JPEG; videos are sampled at 8 frames, so don't expect frame-accurate reads of a long clip.
Every queue is a billable call. The node isn't an output node, but it re-executes whenever the graph does. Chat iteratively in the panel with 仅对话 selected, adopt the turn you like, then generate.
For a pack whose whole pitch is collapsing dense graphs into clean Loader/Controller/Sampler stacks, this is the odd one out: a network call sitting in a local pipeline.
Inputs (30)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | — | |
| skill | COMBO | 不使用技能 | 1 options: 不使用技能 |
| llm_model | COMBO | Qwen3.8-Max | 2 options: Qwen3.8-Max, 自定义 |
| custom_model | STRING | — | |
| api_key | STRING | — | |
| output_mode | COMBO | 实时输出 | 2 options: 实时输出, 仅对话 |
| conversation_history | STRING | — | |
| committed_result | STRING | — | |
| conversation_action | STRING | send | — |
| mediaopt | IMAGE,VIDEO,STRING | — | |
| media_1opt | IMAGE,VIDEO,STRING | — | |
| media_2opt | IMAGE,VIDEO,STRING | — | |
| media_3opt | IMAGE,VIDEO,STRING | — | |
| media_4opt | IMAGE,VIDEO,STRING | — | |
| media_5opt | IMAGE,VIDEO,STRING | — | |
| media_6opt | IMAGE,VIDEO,STRING | — | |
| media_7opt | IMAGE,VIDEO,STRING | — | |
| media_8opt | IMAGE,VIDEO,STRING | — | |
| media_9opt | IMAGE,VIDEO,STRING | — | |
| media_10opt | IMAGE,VIDEO,STRING | — | |
| media_11opt | IMAGE,VIDEO,STRING | — | |
| media_12opt | IMAGE,VIDEO,STRING | — | |
| media_13opt | IMAGE,VIDEO,STRING | — | |
| media_14opt | IMAGE,VIDEO,STRING | — | |
| media_15opt | IMAGE,VIDEO,STRING | — | |
| media_16opt | IMAGE,VIDEO,STRING | — | |
| media_17opt | IMAGE,VIDEO,STRING | — | |
| media_18opt | IMAGE,VIDEO,STRING | — | |
| media_19opt | IMAGE,VIDEO,STRING | — | |
| media_20opt | IMAGE,VIDEO,STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| result | STRING | — |