M8 · 大模型推理
A cloud LLM inside your graph, minus the key leak
- skill
- image
- audio
- text
An LLM in the graph is a tool, not an encoder. It's not the T5 or Qwen3 inside your checkpoint doing the forward pass - it's a node you bolt on that rewrites a rough idea into a structured prompt, or turns a caption into tags, before the text ever reaches the sampler. M8 · LLM Inference is the API half of that idea: any OpenAI-compatible endpoint, your key, your call.
Why you'd wire an LLM into a workflow at all
Because the 2026 architecture rewards it. When the checkpoint's text encoder is itself a language model reading an instruction, having a second language model write that instruction is a translation between two things that speak the same language. The job is short structured rewriting, which is why you want something small and obedient - not a reasoning model that deliberates and leaks its scratch-work into your prompt. The honest split in this pack: this node for a frontier endpoint you'll pay for, M8 · Local LLM Inference for a local GGUF that's free per call and won't refuse anything.
How it works
Plain OpenAI chat-completions. You pick a provider - deepseek, openai, openrouter, siliconflow, ollama, custom - and it fills that provider's default base_url and its thinking options. Default is DeepSeek. The model dropdown is empty until you hit Refresh models, which asks the endpoint for its list; you can also type a model name by hand, which is what you do for Ollama or a model released after the list was fetched.
Two prompt boxes:
system_prompt- persona, tone, output formatuser_prompt- this turn's actual question, and it can be converted to an input socket (right-click) so an upstream node's text feeds it
thinking runs off/low/medium/high. It's a provider-specific parameter, and if the endpoint rejects it the node drops the field and retries once rather than dying - the log tells you it happened. show_thinking renders the model's reasoning in the panel only; it never leaves the node. That's the right call: wire reasoning text into a prompt encoder and you've fed it a monologue.
The output is exactly one thing, text (STRING). temperature defaults to 1.0 - drop it to 0.3–0.6 for prompt writing, which is steady work, not creative work. max_tokens is a cap, not a target. timeout defaults to 120 seconds; if you're using a thinking model, give it 300 or more or you'll be timing out on answers that were about to arrive.
Skills, images, audio, and the escape hatch
Wire M8 · Skill Loader into skill and its text is appended after the system prompt, wrapped so the model can tell instructions from reference material. You can also type / in the prompt box to reference an uploaded skill by name - the backend injects it only when the reference resolves to exactly one skill. Ambiguous or unmatched means nothing gets injected, which is deliberate: guessing wrong dumps the wrong reference into your context, which is worse than omitting it. URLs, drive paths and things like 3/4 aren't treated as references.
skill_auto (off by default) injects every uploaded skill and lets the model pick. Leave it off unless your library is tiny - every turn then carries a few irrelevant packs and burns tokens on them.
image and audio are optional multimodal inputs; audio gets converted to WAV. Feed them to a model that supports them or the endpoint returns 400 (M8-LLM-010). extra_params takes a JSON object merged straight into the request body - {"top_p": 0.9}, or any vendor-specific field this pack doesn't know about.
The key handling is the good part
Two ways to give it a key, and they are not equivalent. Typing it on the node works, and gets written into the workflow file - hand that workflow to someone and you've handed them your key. The other button saves it server-side into m8/data/credentials.json, clears the field, and leaves the workflow clean.
There's a guardrail worth knowing about: the stored key is only sent when base_url matches that provider's default or saved address. A shared workflow can set base_url to someone else's server with the key field blank, and the node will refuse with M8-LLM-021 rather than post your credential to a stranger's endpoint.
Install and the errors you'll meet
Same as the rest of the pack - ComfyUI Manager, or git clone https://github.com/chenr5934-tech/ComfyUI-M8nodes.git into custom_nodes and restart. No pip step.
When something's wrong you get a code, not a shrug: M8-LLM-004 for a non-200 response (401 means key, 402 balance, 404 wrong address, 429 rate limit), M8-LLM-001 for no key configured, M8-LLM-013 when the request body is too big - usually too many images or a fat skill pack, and the node warns in the log when a pack passes 20,000 characters. M8-LLM-005 means the endpoint answered but the response carried no text, which almost always means the model name is wrong or the endpoint isn't really OpenAI-compatible.
One last thing, and it isn't paranoia. An API node holds a credential and calls the network by design, which is why the worst security incident in this ecosystem's history was an LLM-vision node that shipped credential-stealing malware. Prefer keys saved server-side over keys baked into the workflow.
Inputs (16)
| Name | Type | Default | Description |
|---|---|---|---|
| provider | COMBO | deepseek | 选择供应商。改这个会自动带出对应的默认 base_url 和思考参数;换成别的服务商就选「自定义」自己填地址。 |
| base_url | STRING | https://api.deepseek.com/v1 | 接口地址。默认 DeepSeek 的 https://api.deepseek.com/v1,改掉就能接任何 OpenAI 兼容端点。 |
| api_key | STRING | 留空就用服务端已保存的密钥(推荐:点「保存密钥」存到服务端,工作流文件里就不会带明文)。填在这里只对当前节点生效,并且会写进工作流。 | |
| model | COMBO | 填好地址和密钥后点「刷新模型」拉取,或直接手输模型名。 | |
| system_prompt | STRING | 系统提示词:定模型的人格、语气、输出格式。留空则只发对话提示词。 | |
| user_prompt | STRING | 这次要问的事。可以接别的节点的文本输出。 | |
| thinking | COMBO | off | 思考强度。关=不额外要求;越高越让模型多想。供应商不支持该参数时会自动去掉它重试。 |
| show_thinking | BOOLEAN | false | 是否把模型的思考过程显示在节点面板上(默认关:思考内容通常很长)。只影响显示,不影响 text 输出。 |
| temperature | FLOAT | 1.000–2 | 随机性。写提示词这类要稳的活儿调低,创意类的调高。 |
| max_tokens | INT | 819216–131072 | 回答长度上限。注意这是上限不是目标。 |
| timeout | INT | 1205–3600 | 单次请求超时秒数。长思考的模型建议给到 300 以上。 |
| skillopt | M8_SKILL | 从 M8 · Skill 装载 接进来。内容会附在系统提示词后面当参考资料。 | |
| skill_autoopt | BOOLEAN | false | 打开后把服务端已上传的 skill 一起注入,由模型自己判断该用哪个。默认关:库里内容一多,每轮都会带上几份用不上的,白烧 token。 |
| imageopt | IMAGE | 接图片给能看图的模型。多张会一起发。 | |
| audioopt | AUDIO | 接音频给能听音频的模型(转成 WAV 发出去)。 | |
| extra_paramsopt | STRING | 额外的请求参数,JSON 对象格式,会合并进请求体。 |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| text | STRING | — |