Character Evidence Extractor
Character Evidence Extractor
- lmstudio_config
- chapter_selection
- character_evidence
- saved_file
If you've ever tried to turn a story you wrote into a video, you know where it dies. Not at the sampler - at the character bible. Scene one your protagonist has grey eyes, scene nine they've got green ones, and nobody notices until the clips are cut together. This node is the fix for that specific, boring, soul-crushing problem: it reads your chapters with a local LLM and spits out every physical description it can find, each one quoted from the source with a character offset.
It's the first real step in the MiniMax H3 Novel Pipeline, a small pack that takes prose → character profiles → scene prompts for MiniMax's 33B H3 video model. Fair warning: this is a one-person pack with basically no community footprint. Judge it on what it does, not on a bandwagon.
What it actually does
You point it at chapter files and it does retrieval, not vibes. In the default proper_names scope it scans every selected chapter for capitalised name candidates (with English/French sentence-start exclusions and lowercase-occurrence checks so "The" and "Meanwhile" don't become characters), indexes where each name appears across the whole novel, and batches the paragraphs around each hit - one paragraph either side - bounded by chunk_chars. Windows that overlap get merged. Pronouns don't drag the window wider forever, which is the detail that keeps this from ballooning into "the whole book is one chunk".
Then the LLM gets asked one small, constrained question per batch: pull the physical observations. Age, build, skin, hair, eyes, distinguishing features, clothing, accessories. Not personality, not plot, not "she is brave". Every observation has to come back with an exact quotation, and the node verifies that quotation as a literal substring of the source - with real character offsets and line numbers attached. That verification is the whole value proposition. A model's guess is worthless; a model's guess pinned to a line of your text is reviewable.
The scope switch matters. all_characters processes the full text including unnamed people and role labels, which is what you want if a character is described for pages before being named, or if the prose doesn't capitalise names the way English does. The author is honest about this in the README: the proper-name path is heuristics, not language-independent NER, and it can miss exactly those cases.
The inputs you'll actually touch
lmstudio_config and chapter_selection are both required wires - from LM Studio Configuration and Select Chapters respectively. Everything else has a usable default.
out_dir defaults to character_evidence inside the current run folder, and the file you care about is character_evidence.json there. chunk_chars (default 5500) is your main quality/cost dial: smaller batches mean tighter attention and more requests. character_scope is the proper_names / all_characters choice above. thinking defaults to true; the README suggests trying false for speed and comparing fidelity on your own model, which is the right instinct - reasoning tokens here buy you little, and quick local models leak them into structured output. force bypasses the cache, and resume_run takes a previous run folder name like 20261025154413 so a crashed 40-chapter extraction doesn't restart from zero. Keep the original settings when you use it, or the batch keys won't match.
Two outputs: character_evidence (the typed dictionary, wire it into Consolidate Character Profiles) and saved_file, a plain string path for logging or for feeding a loader later.
Install
ComfyUI Manager, search "MiniMax H3 Novel Pipeline". Or by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/yuyuki/ComfyUI-Minimax_H3_Novel_Pipeline
python -m pip install -r ComfyUI-Minimax_H3_Novel_Pipeline/requirements.txt
Use the interpreter that actually runs ComfyUI - the embedded one if you're on the portable build. Restart and refresh the browser. Python 3.10+. Dependencies are openai, httpx, pypdf and jsonschema (note: the README's prose lists three; requirements.txt is the truth). pypdf only matters for PDF chapters, and they need to be searchable - scanned images with no text layer will get you nothing.
Then LM Studio: start its local server, load a Qwen model, enter lm-studio as the API key in ComfyUI Settings → MiniMax H3 Novel → LM Studio, and put http://127.0.0.1:1234/v1 in the config node. If you use a non-default endpoint it must also be set as Trusted API URL in that settings panel - the pack only talks to allowlisted URLs.
Where people get burned
The node refuses anything but the Qwen family in lmstudio_config - you get a flat "requires Qwen" error, not a subtle failure. The README talks about Mistral support in general terms, but the extractor, consolidation and visual generator all hard-check model_family == "Qwen". Set it to Qwen and move on.
Second: this is slow in a way that surprises people. It's one request per batch, per chapter, plus repair calls. A full novel is hundreds of requests. Run a couple of chapters first to see whether your model's observations are worth scaling.
Third: caches. Completed batches live in <run>/.cache/character_evidence and get reused silently; if results didn't change when you expected them to, read character_evidence_diagnostics.json and character_evidence_review.json before assuming the node is broken. Invalid observations get up to correction_attempts repairs and are then kept, flagged, for you to look at - it never silently drops evidence, which means the reviewing is yours to do. Check it before you consolidate.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| lmstudio_config | MINIMAX_LMSTUDIO_CONFIG | — | |
| chapter_selection | MINIMAX_CHAPTER_SELECTION | — | |
| out_dir | STRING | character_evidence | — |
| chunk_chars | INT | 55001000–30000 | — |
| thinking | BOOLEAN | true | — |
| temperature | FLOAT | 0.150–2 | — |
| max_tokens | INT | 8192256–32768 | — |
| correction_attempts | INT | 20–10 | — |
| force | BOOLEAN | false | — |
| character_scope | COMBO | proper_names | 2 options: proper_names, all_characters |
| audit_thinkingopt | BOOLEAN | false | Enable reasoning for the semantic audit too. Slower; extraction keeps its own thinking setting. |
| resume_runopt | STRING | Previous run folder, e.g. 20261025154413. Reuse matching character evidence batches; leave empty for a fresh run. Keep the original settings and force disabled. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| character_evidence | MINIMAX_CHARACTER_EVIDENCE | — |
| saved_file | STRING | — |