Back to Redis

Decision Tree Format Specification

for-ais-only/render_hook_docs/DECISION_TREE_FORMAT.md

latest9.2 KB
Original Source

Decision Tree Format Specification

Overview

Decision trees are structured YAML documents that guide users through a series of questions to reach a recommendation. They are rendered as interactive SVG diagrams with boxes, connecting lines, and Yes/No branch labels.

Basic Structure

yaml
```decision-tree {id="documents-tree"}
id: documents-tree
scope: documents
rootQuestion: root
questions:
    root:
        text: "Your question here?"
        whyAsk: "Explanation of why this question matters"
        answers:
            yes:
                value: "Yes"
                outcome:
                    label: "Recommendation"
                    id: outcomeId
            no:
                value: "No"
                nextQuestion: nextQuestionId
    nextQuestionId:
        text: "Follow-up question?"
        whyAsk: "Why this matters"
        answers:
            yes:
                value: "Yes"
                outcome:
                    label: "Recommendation"
                    id: outcomeId
            no:
                value: "No"
                outcome:
                    label: "Alternative recommendation"
                    id: altOutcomeId

## Fields

### Top-level

- **`id`** (required): Unique identifier for this decision tree (e.g., `documents-tree`, `collections-tree`). Used for discovery and referencing by AI agents.
- **`scope`** (required): Category or domain this tree applies to (e.g., `documents`, `collections`, `sequences`). Helps AI agents understand the tree's purpose and applicability.
- **`rootQuestion`** (required): The ID of the starting question
- **`questions`** (required): Object containing all questions, keyed by ID
- **`indentWidth`** (optional): Horizontal spacing in pixels between parent and child nodes. Default: 40. Use smaller values (e.g., 20-30) for deeply nested trees to reduce overall width. This is a rendering preference and does not affect the semantic metadata.

### Question Object

- **`text`** (required): The question text. Can span multiple lines using YAML's `|` literal block syntax
- **`whyAsk`** (required): Explanation of why this question matters. Helps AI agents understand the decision logic
- **`answers`** (required): Object with answer keys (can be `yes`/`no` for binary trees, or arbitrary keys for multiway branching)

### Answer Object

Each answer contains:

- **`value`** (required): Display text (e.g., "Yes", "No", "Python", "JavaScript", etc.)
- **`outcome`** (optional): Terminal recommendation
  - `label`: Text to display (e.g., "Use JSON")
  - `id`: Unique identifier for this outcome
- **`nextQuestion`** (optional): ID of the next question to ask

**Note**: Each answer must have either `outcome` or `nextQuestion`, not both.

### Multiway Branching

Instead of limiting answers to `yes` and `no`, you can use arbitrary answer keys for multiway branching:

```yaml
languageQuestion:
    text: What is your primary programming language?
    whyAsk: Different languages have different client libraries
    answers:
        python:
            value: Python
            nextQuestion: pythonUseCase
        javascript:
            value: JavaScript
            nextQuestion: javascriptOMQuestion
        java:
            value: Java
            nextQuestion: javaQuestion
        other:
            value: Other
            nextQuestion: otherLanguageQuestion

Benefits:

  • Reduces tree depth by allowing multiple branches from a single question
  • More natural for questions with 3+ distinct options
  • Cleaner than binary yes/no chains
  • Answers are stacked vertically in the diagram

Outcome Object

  • label (required): The recommendation text
  • id (required): Unique identifier (e.g., jsonOutcome, hashOutcome)
  • sentiment (optional): Indicates the nature of the outcome for visual styling
    • "positive": Renders with green styling (e.g., "Use this option")
    • "negative": Renders with red styling (e.g., "Don't use this option")
    • "indeterminate": Renders with yellow/amber styling (e.g., "Further analysis needed")
    • Omitted: Defaults to red (neutral/warning styling)

Note: The sentiment field is particularly useful for suitability trees (where outcomes are binary: suitable vs. unsuitable) as opposed to selection trees (where all outcomes are valid options). See Tree Types below.

Tree Types

Decision trees can serve different purposes, which affects how you structure outcomes:

Selection Trees

All paths lead to valid recommendations. Users choose between options.

  • Example: "Which data type should I use?" → JSON, Hash, or String (all valid)
  • Outcome styling: Typically all neutral (no sentiment field needed)
  • Use case: Helping users choose among alternatives

Suitability Trees

Paths lead to binary outcomes: suitable or unsuitable for the use case.

  • Example: "Should I use RDI?" → Yes (good fit) or No (various reasons why not)
  • Outcome styling: Use sentiment: "positive" for suitable outcomes and sentiment: "negative" for unsuitable ones
  • Use case: Determining if a technology/approach is appropriate
  • Benefit: Visual distinction (green vs. red) helps users quickly understand if something is recommended

Multi-line Text

Use YAML's literal block syntax (|) for multi-line text:

yaml
text: |
    Do you need nested data structures
    (fields and arrays) or geospatial
    index/query with Redis Search?
whyAsk: |
    JSON is the only document type that supports
    deeply nested structures and integrates with
    Redis Search for those structures

Code Block Attributes

The code block fence supports the following attributes:

  • id (optional): Unique identifier for the tree. Should match the id field in the YAML. Used by Hugo to pass metadata to the render hook.

Example:

markdown
```decision-tree {id="documents-tree"}
id: documents-tree
scope: documents
# ...

## Best Practices

1. **Use descriptive IDs**: `root`, `hashQuestion`, `jsonOutcome` are clearer than `q1`, `q2`
2. **Keep questions concise**: Aim for 1-2 lines when possible
3. **Explain the rationale**: The `whyAsk` field helps users and AI agents understand the decision logic
4. **Reuse outcomes**: Multiple paths can lead to the same outcome (same `id`)
5. **Consistent naming**: Use camelCase for IDs, end question IDs with "Question"
6. **Match fence and YAML IDs**: The `id` in the code block fence should match the `id` field in the YAML for consistency
7. **Use meaningful scopes**: Choose scope values that clearly indicate the tree's domain (e.g., `documents`, `collections`, `sequences`)
8. **Add sentiment for suitability trees**: If your tree determines whether something is suitable (not just choosing between options), use `sentiment: "positive"` and `sentiment: "negative"` to provide visual feedback
9. **Be consistent with sentiment**: In a suitability tree, ensure all positive outcomes have `sentiment: "positive"` and all negative outcomes have `sentiment: "negative"` for clarity
10. **Control answer order**: The order of answers in the YAML controls the visual layout. For early rejection patterns, put negative outcomes first so they appear at the top of the diagram
11. **Adjust indent width for deeply nested trees**: If your tree has many levels and becomes too wide, use `indentWidth="25"` (or lower) in the code block fence to reduce horizontal spacing between parent and child nodes
12. **Use multiway branching for 3+ options**: Instead of chaining binary yes/no questions, use multiway branching with descriptive answer keys (e.g., `python`, `javascript`, `java`) to reduce tree depth and improve readability
13. **Keep answer values short**: Answer labels appear on connecting lines, so keep them concise (1-3 words) to fit neatly in the diagram

## Example: Redis Data Type Selection

See `content/develop/data-types/compare-data-types.md` for a complete example.

## Rendering

Decision trees are rendered as:
- **SVG diagram** for humans (with boxes, lines, and labels)
- **Normalized JSON** embedded for AI agents (accessible via `.html.md` URLs)
- **Raw YAML** preserved in `<pre>` element for accessibility

## AI Agent Compatibility

The format is designed to be easily parseable by AI agents:

### Metadata Embedding
- **Server-side JSON**: Each tree is embedded with metadata as `<script type="application/json" data-redis-metadata="decision-tree">` containing `id`, `scope`, and `type` fields
- **No JavaScript required**: Metadata is available in static HTML, accessible to AI agents that don't execute JavaScript
- **Discoverable**: The `id` and `scope` fields enable AI agents to identify and filter trees

### Content Accessibility
- **Raw YAML preserved**: The original YAML source is preserved in a `<pre class="decision-tree-source">` element for AI parsing
- **Clear hierarchical structure**: Explicit question IDs and outcome IDs
- **Reasoning context**: `whyAsk` field explains the decision logic
- **Normalized JSON**: Available for deterministic processing

### Example Metadata
```json
{
  "type": "decision-tree",
  "id": "documents-tree",
  "scope": "documents"
}

This metadata helps AI agents:

  • Identify the tree's purpose and domain
  • Filter trees by scope
  • Reference specific trees in recommendations
  • Understand the tree's applicability to different problems