> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fibonacci.today/llms.txt
> Use this file to discover all available pages before exploring further.

# CriticNode

> Node for evaluating output from another node against criteria

The `CriticNode` class evaluates the output of a target node against a list of criteria. It is automatically added as a dependent of the target node so it always runs after the node it evaluates.

## Constructor

```python theme={null}
from fibonacci import CriticNode

node = CriticNode(
    id="evaluate_report",
    name="Evaluate Report Quality",
    target_node="generate_report",
    criteria=["clarity", "completeness", "accuracy"]
)
```

### Parameters

| Parameter      | Type        | Default                                      | Description                                                               |
| -------------- | ----------- | -------------------------------------------- | ------------------------------------------------------------------------- |
| `id`           | `str`       | Required                                     | Unique node identifier (lowercase letters, numbers, underscores, hyphens) |
| `name`         | `str`       | Required                                     | Human-readable node name                                                  |
| `target_node`  | `str`       | Required                                     | ID of the node whose output will be evaluated                             |
| `criteria`     | `list[str]` | `["quality", "correctness", "completeness"]` | Evaluation criteria labels                                                |
| `dependencies` | `list[str]` | auto                                         | `target_node` is automatically added; add extras here if needed           |
| `enable_retry` | `bool`      | `False`                                      | Retry the critic node on failure                                          |
| `max_retries`  | `int`       | `3`                                          | Maximum retry attempts (used when `enable_retry=True`)                    |
| `retry_delay`  | `float`     | `1.0`                                        | Initial delay in seconds between retries                                  |

<Note>
  The `target_node` is automatically added to `dependencies`. You do not need to list it manually.
</Note>

## Basic Usage

```python theme={null}
from fibonacci import Workflow, LLMNode, CriticNode

wf = Workflow(name="quality-assured")

# Content generator
writer = LLMNode(
    id="writer",
    name="Write Email",
    instruction="Write a professional email about: {{input.topic}}"
)

# Quality evaluator
critic = CriticNode(
    id="critic",
    name="Evaluate Email Quality",
    target_node="writer",
    criteria=[
        "professional tone throughout",
        "clear and concise language",
        "proper grammar and spelling",
        "appropriate greeting and closing"
    ]
)

wf.add_nodes([writer, critic])
```

## Default Criteria

When you omit `criteria`, the node uses three built-in labels:

```python theme={null}
# These two are equivalent
critic_a = CriticNode(
    id="critic_a",
    name="Default Critic",
    target_node="writer"
)

critic_b = CriticNode(
    id="critic_b",
    name="Explicit Critic",
    target_node="writer",
    criteria=["quality", "correctness", "completeness"]
)
```

## Custom Criteria

Provide specific, measurable criteria for your use case:

### Content Writing

```python theme={null}
content_critic = CriticNode(
    id="content_critic",
    name="Content Quality Check",
    target_node="blog_writer",
    criteria=[
        "engaging opening hook",
        "clear value proposition",
        "actionable takeaways",
        "appropriate length for the audience"
    ]
)
```

### Code Review

```python theme={null}
code_critic = CriticNode(
    id="code_critic",
    name="Code Review",
    target_node="code_generator",
    criteria=[
        "syntactically correct",
        "follows best practices",
        "includes error handling",
        "is well-documented"
    ]
)
```

### Data Extraction

```python theme={null}
extraction_critic = CriticNode(
    id="extraction_critic",
    name="Extraction Accuracy Check",
    target_node="extractor",
    criteria=[
        "all required fields extracted",
        "values are in the correct format",
        "no hallucinated information"
    ]
)
```

## Writing Good Criteria

<AccordionGroup>
  <Accordion title="Be specific and measurable">
    ```python theme={null}
    # ✅ Good — specific, observable
    criteria=[
        "response is between 100 and 200 words",
        "includes at least one concrete example",
        "no grammatical errors"
    ]

    # ❌ Vague — hard to evaluate objectively
    criteria=[
        "good quality",
        "sounds nice"
    ]
    ```
  </Accordion>

  <Accordion title="Match criteria to the task">
    ```python theme={null}
    # For customer-facing content
    criteria=[
        "friendly and empathetic tone",
        "directly addresses the user's question",
        "offers a clear next step"
    ]

    # For internal analysis
    criteria=[
        "cites data from the source",
        "identifies at least 3 trends",
        "recommends concrete actions"
    ]
    ```
  </Accordion>
</AccordionGroup>

## Retry Configuration

```python theme={null}
critic = CriticNode(
    id="critic",
    name="Evaluator",
    target_node="writer"
).with_retry(max_retries=3, delay=1.0)
```

## YAML Configuration

```yaml theme={null}
nodes:
  - id: quality_check
    name: Quality Check
    type: critic
    target_node: writer
    evaluation_criteria:
      - professional tone
      - clear language
      - grammar and spelling
    dependencies:
      - writer
```

## Complete Example

```python theme={null}
from fibonacci import Workflow, LLMNode, CriticNode

wf = Workflow(name="blog-writer")

# Generate blog post
writer = LLMNode(
    id="writer",
    name="Write Blog Post",
    instruction="""
    Write a blog post about {{input.topic}}.

    Target audience: {{input.audience}}
    Desired length: approximately {{input.word_count}} words
    Tone: {{input.tone}}
    """,
    model="claude-sonnet-4-6"
)

# Evaluate quality
critic = CriticNode(
    id="quality_check",
    name="Editorial Quality Check",
    target_node="writer",
    criteria=[
        "engaging from the first paragraph",
        "well-researched and accurate",
        "writing style matches the target audience",
        "close to the requested word count",
        "tone is consistent throughout",
        "includes actionable takeaways",
        "compelling conclusion"
    ]
)

wf.add_nodes([writer, critic])

result = wf.run(input_data={
    "topic": "Introduction to Machine Learning",
    "audience": "business professionals",
    "word_count": 800,
    "tone": "informative yet approachable"
})

print(result.output_data["quality_check"])
```
