Structured Generation with DAG for LLM Code and Long-Form Writing

    This article explains how to use a Directed Acyclic Graph (DAG) orchestration approach to split complex generation tasks—such as code completion and long-form fiction writing—into manageable, dependency-aware nodes. It covers node configuration, prompt templates, context backfilling, retry logic, validation schemas, and practical evaluation methods for ensuring logical consistency and reducing output drift in large language models.

    Large language models are not uniformly “strong” across tasks. A model that performs reliably in code completion may struggle with long-form descriptive writing. A more dependable approach is to build task-specific evaluation sets, fix prompts and parameters, log model versions, and use process-level constraints to shape the output. This article describes a DAG-based orchestration method that reduces setting drift and logical breaks—though it does not replace manual sampling and review.

    Common Difficulties in Code and Long-Form Generation

    Both code generation and novel writing require three capabilities: maintaining logical consistency between reasoning steps, keeping track of long-distance context, and ensuring details match predefined rules. The failure modes are also similar. If the model forgets a previously defined function signature or character identity, subsequent output cascades into errors. Therefore, evaluation should measure these three abilities independently, not just rely on an aggregate brand impression.

    Splitting Generation Tasks with a DAG

    A Directed Acyclic Graph (DAG) consists of directed nodes and dependency relationships with no cycles. Execution follows the dependency order: nodes that are depended on run first, and downstream nodes read upstream outputs. In a fiction scenario, an upstream node outputs the global setting, and a downstream node generates chapters based on that setting.

    After splitting, each node must declare three things: where its input comes from, what output structure it should produce, and how failures are handled. Here is a configuration example:

    1. {
    2. "nodes": {
    3. "worldview_setup": {
    4. "description": "Generate worldview, historical timeline, and faction distribution",
    5. "dependencies": [],
    6. "input_schema": {"genre": "string", "chapter_count": "integer"},
    7. "output_schema": {
    8. "regions": "array",
    9. "power_system": "object",
    10. "factions": "array",
    11. "timeline": "array"
    12. },
    13. "max_retries": 2,
    14. "validators": ["schema_check", "unique_names"]
    15. },
    16. "character_relation": {
    17. "description": "Define character factions and relationships based on worldview",
    18. "dependencies": ["worldview_setup"],
    19. "output_schema": {"characters": "array", "relations": "array"},
    20. "max_retries": 2,
    21. "validators": ["schema_check", "faction_ref_exists"]
    22. },
    23. "chapter_generation": {
    24. "description": "Generate chapter plots based on settings and character relations",
    25. "dependencies": ["worldview_setup", "character_relation"],
    26. "output_schema": {"chapter_no": "integer", "summary": "string", "text": "string"},
    27. "max_retries": 2,
    28. "validators": ["schema_check", "no_forbidden_terms"]
    29. }
    30. }
    31. }

    The runner first executes worldview_setup, then character_relation, and then loops chapter_generation by chapter number. Field names are kept in English for programmatic parsing.

    Prompt Templates and Context Backfilling

    Each node uses a fixed template with placeholders for variables. The worldview node template looks like:

    1. You are a novel worldbuilding assistant. Generate a worldview according to the parameters below. Output strict JSON without extra fields.
    2. Genre: {genre}
    3. Chapter count: {chapter_count}
    4. Requirements:
    5. 1. Define the number of tiers and upgrade conditions for the power system.
    6. 2. For each faction, provide a name, stance, and core resources.
    7. 3. Keep all names unique across the whole text.
    8. Output structure: {output_schema}

    When generating a chapter, the prompt includes three parts: the full setting block, the current character states, and summaries of the previous two chapters. If the context window is insufficient, truncate in this order: first remove older chapter content, then remove secondary character descriptions. The setting block and the current chapter requirement are always preserved.

    After each chapter is generated, only that chapter’s summary is written to the shared state; the next chapter reads that state. Do not backfill entire chapter text, as token consumption grows quickly and irrelevant details can interfere with the model.

    Failure Retry and Consistency Validation

    Each node’s output is checked as follows:

    1. Check whether the output conforms to the output schema. On failure, append the error message to the prompt and retry up to max_retries times.
    2. Run dedicated validation functions to check for duplicate names, references to non‑existent factions, and timeline regressions.
    3. If all checks pass, write to the state. If consecutive failures occur, roll back to the last valid output, log the issue, and hand it to a human.

    Do not overwrite already‑validated state on failure; keep every valid version. Validation functions can only check whether rules are satisfied—they cannot judge writing quality. Therefore, it is recommended to manually sample key settings every five chapters.

    Checklist: World, Characters, and Plot

    Module Acceptance Criteria Common Failure Mode
    World Tier count and upgrade conditions are explicit; geography and faction positions do not conflict Tier names are inconsistent; a location hosts factions with unclear stances
    Character Relations Every character has a faction, a motive, and at least one relationship; relationships can be cross‑checked in both directions Character faction changes without explanation; relationships exist only one‑way
    Plot Conflict Conflict has a cause, a cost, and a resolution; turns are derivable from earlier text Antagonist switches sides suddenly; a resource‑scarce setting is ignored later
    Timeline Event order aligns with chapter numbers; time spans are recorded Events are reversed; seasons or ages contradict each other

    Test Methods for Detailed Description

    The biological description example mentioned earlier can illustrate the texture of model output, but it is a single sample and cannot be used as a basis for ranking models. When comparing models, fix the following conditions: identical prompts, identical temperature parameters, at least five generations per model, and blind evaluation by reviewers who do not know the model source.

    Dimension Measurement Method Notes
    Sensory dimension Count paragraphs containing visual, tactile, olfactory, and auditory descriptions Multi‑sensory description usually increases immersion
    Concrete noun density Number of specific nouns per 100 characters Adjective‑heavy text tends to score low
    Action coherence Manual scoring from 1 to 5 Check if action order and causality are reasonable
    Repetition rate Count occurrences of identical phrases Excessive repetition indicates template reuse
    Setting consistency Cross‑check against a setting table Check whether appearance, abilities, and locations stay consistent

    Common Questions

    How to Choose a General‑Purpose Model

    First break down the task requirements. Code tasks focus on test pass rates and dependency compatibility; long‑form tasks focus on setting consistency and detail density. After selecting candidate models, test them with the same evaluation set and record the model version, parameters, and test date. Results may change after model updates, so re‑testing is necessary.

    Common Mistakes to Avoid

    • Setting drift: Later text modifies rules defined earlier, e.g., changing the number of power tiers.
    • Name confusion: Two character names are similar, and the model starts swapping them.
    • Timeline errors: Event order is reversed, or character ages contradict earlier statements.
    • Generating the entire text in one pass: Paragraph styles break apart, making it hard to unify.

    What to Watch for in Long‑Text Generation

    • Copyright: Do not have the model reproduce large portions of copyrighted works.