--- title: "Model Stylesheets" description: "Assign LLM models to workflow nodes using CSS-like rules" --- Model stylesheets let you assign LLM models, providers, and settings to workflow nodes using a CSS-like syntax. Instead of hardcoding a model on every node, you write a set of rules that target nodes by ID, class, shape, or a universal wildcard — and Arc applies them by specificity. ## Defining a stylesheet Stylesheets are set in the `model_stylesheet` graph attribute: ```dot title="example.dot" digraph Example { graph [ goal="Build and review a utility function", model_stylesheet=" * { llm_model: claude-haiku-4-5; llm_provider: anthropic; } .coding { llm_model: claude-sonnet-4-5; reasoning_effort: high; } #review { llm_model: gemini-3.1-pro-preview; llm_provider: gemini; } " ] start [shape=Mdiamond, label="Start"] exit [shape=Msquare, label="Exit"] spec [label="Write Spec"] implement [label="Implement", class="coding"] test [label="Write Tests", class="coding"] review [label="Code Review"] start -> spec -> implement -> test -> review -> exit } ``` In this example: - **spec** gets Haiku (matches `*`) - **implement** and **test** get Sonnet with high reasoning (match `.coding`) - **review** gets Gemini Pro (matches `#review`) ## Selectors Each rule starts with a selector that determines which nodes it applies to: | Selector | Syntax | Matches | Specificity | |---|---|---|---| | Universal | `*` | All nodes | 0 | | Shape | `box`, `tab`, `hexagon`, etc. | Nodes with that Graphviz shape | 1 | | Class | `.classname` | Nodes with `class="classname"` | 2 | | ID | `#nodeid` | The node with that specific ID | 3 | ### Assigning classes Set the `class` attribute on a node to target it with class selectors. Multiple classes are space-separated: ```dot implement [label="Implement", class="coding critical"] ``` This node matches both `.coding` and `.critical` rules. ## Properties Stylesheets support four properties: | Property | Description | Example | |---|---|---| | `llm_model` | Model ID or alias | `claude-sonnet-4-5`, `opus`, `gemini-pro` | | `llm_provider` | Provider name | `anthropic`, `openai`, `gemini` | | `reasoning_effort` | Reasoning effort level | `low`, `medium`, `high` | | `backend` | Agent execution backend — `api` (default) runs Arc's own tool loop, `cli` delegates to an external CLI tool. See [Backends](/core-concepts/agents#backends). | `cli`, `api` | See [Models](/core-concepts/models) for the full list of model IDs and aliases. ## Specificity and cascading When multiple rules match the same node, the rule with the **highest specificity** wins. This follows the same principle as CSS: ``` * (0) < shape (1) < .class (2) < #id (3) ``` For example: ``` * { llm_model: claude-haiku-4-5; } .coding { llm_model: claude-sonnet-4-5; } #review { llm_model: gpt-5.2; } ``` A node with `id="review"` and `class="coding"` gets `gpt-5.2` because `#id` (specificity 3) beats `.class` (specificity 2). If two rules have the same specificity, the **last one** in the stylesheet wins. ## Explicit attributes override stylesheets A model set directly on a node attribute always takes precedence over stylesheets, regardless of specificity: ```dot implement [label="Implement", class="coding", llm_model="claude-opus-4-6"] ``` Even if `.coding` sets `llm_model: claude-sonnet-4-5`, this node uses Opus because the explicit attribute wins. ## Syntax reference The stylesheet syntax is a simplified subset of CSS: ``` selector { property: value; property: value; } ``` - Selectors: `*`, `shape`, `.class`, `#id` - Properties and values are separated by `:` - Declarations are separated by `;` - Whitespace is flexible — newlines and indentation are ignored - CSS comments (`/* ... */`) are not supported ### Full example ``` * { llm_model: claude-haiku-4-5; llm_provider: anthropic; reasoning_effort: low; } box { reasoning_effort: high; } tab { reasoning_effort: low; } .coding { llm_model: claude-sonnet-4-5; llm_provider: anthropic; reasoning_effort: high; } .review { llm_model: gemini-3.1-pro-preview; llm_provider: gemini; } #final_check { llm_model: claude-opus-4-6; llm_provider: anthropic; reasoning_effort: high; } ``` This stylesheet: - Defaults everything to Haiku with low reasoning - Overrides all agent nodes (`box` shape) to high reasoning - Keeps prompt nodes (`tab` shape) at low reasoning - Routes `.coding` nodes to Sonnet - Routes `.review` nodes to Gemini for independent critique - Routes the `final_check` node to Opus for maximum quality