---
title: "AI catalog search"
description: "Optional: Custom Data lookup in the same training bot without a separate Copilot."
level: optional
track: ai-catalog-search
prerequisites:
  - ../basic/use-case-01-faq-ai.md
  - ../basic/use-case-07-custom-data.md
  - ../advanced/use-case-10-tickets-categorizer.md
---

# AI catalog search

> **Optional track** — unlike [Use Case 12: Copilot](/en/learn/implementer/training/optional/use-case-12-copilot-cd-lookup.md), categorizer and lookup live in the **same** training bot. A separate Copilot bot is not required.

## Required permissions and access

| Module / setting | Why you need it |
|------------------|-----------------|
| **Scenario Builder** | FAQ + categorizer + CD lookup in one bot |
| **Fast Line Pro** | Categorizer or intent for the catalog |
| **Custom Data** | `products` model + seed |
| **Settings → Operator Panel** | Handoff to an operator (optional) |
| **Runs / Chat preview** | 5 control queries |

## Business context

The customer asks for a product or character from the training catalog. The bot replies from Custom Data and, if needed, hands the dialog to an operator. A typical pattern for e-commerce / reference bots without a Copilot architecture.

## Expected result

- Model `products` + seed [products-training.csv](/content/en/learn/implementer/training/scenarios/seed/products-training.csv)
- Categorizer or filter in CD after `action_fastline_pro`
- Handoff edge on “not found” or at the customer’s request
- **Not** a separate Copilot bot — everything in the training bot

## Architecture

```text
MessageKeyboard "Catalog" → WaitForInput (query)
   → action_fastline_pro (categorizer / intent)
   → Router (valid filters)
   → custom_modules__get / search
      ├─ found     → MessageKeyboard (result)
      ├─ not_found → clarification or handoff
      └─ error     → message + fallback

Optionally: "Operator" → connect (Use Case 3)
```

## Step-by-step implementation

### Step 0. Custom Data — products

1. Create the **products** model (alias `products`).
2. Fields: `name`, `category`, `faction`, `price`.
3. Import [products-training.csv](/content/en/learn/implementer/training/scenarios/seed/products-training.csv).

→ [Custom Data set](/en/customdata/how-to/use-custom-modules-set.md)

---

### Step 1. Fast Line Pro — catalog categorizer

| Parameter | Value |
|-----------|-------|
| Type | **Chatbot** |
| Prompt | Catalog section in [categorizer-training.txt](/content/en/learn/implementer/training/scenarios/prompts/categorizer-training.txt) |
| Test | “spellcaster from north” → JSON filters |

---

### Step 2. Entry and categorizer in the scenario

| Node | Parameters |
|------|------------|
| MessageKeyboard | “What are you looking for in the catalog?” → WaitForInput |
| WaitForInput | outputVariable: `catalog_query` |
| action_fastline_pro | `user_input`: `{{catalog_query}}`, `save_response`: `catalog_filters` |

**Edges:** main → lookup; **fallback** → “Please rephrase your query.”

---

### Step 3. Lookup in Custom Data

| node_params (example) | Value |
|-----------------------|-------|
| `module_name` | `products` |
| filter by | `category`, `faction` from categorizer |

**Edges:**

| Edge | Message (example) |
|------|-------------------|
| found | “{{name}} — {{price}} gold” |
| not_found | “Not found in the catalog. Try differently or tap “Operator”.” |
| **error** | “Search error.” |

---

### Step 4. Handoff to an operator

On not_found or the “Operator” button:

```text
MessageKeyboard → operator_panel__connect_to_operator_with_msg
   (subject_alias from Use Case 3)
```

**Edges:** success / **limit** / **error** — required.

→ [Use Case 3](/en/learn/implementer/training/basic/use-case-03-handoff-to-operator.md)

---

### Step 5. Five control queries (self-check)

| # | Query | Expectation |
|---|-------|-------------|
| 1 | “Geralt” | found — warrior, north |
| 2 | “dragon from Mars” | not_found |
| 3 | “something cheap” | found or clarification (not silence) |
| 4 | “Operator” / handoff | connect edges |
| 5 | Unknown intent | categorizer fallback |

Each pass — a separate Run or reset state; record the edge in Runs.

## Troubleshooting

| Symptom | What to check |
|---------|----------------|
| Always not_found | Filters vs seed CSV; case of category/faction |
| AI “invents” a product | Lookup must come from CD, not only from LLM text |
| Endless clarifications | Retry limit → handoff |
| Handoff without limit edge | [Edge-driven flow](/en/learn/implementer/training/concepts.md#edge-driven-flow) |

## Self-check

- [ ] 5 control queries passed; results in the result template
- [ ] Found / not found / handoff / fallback — all with a message to the customer
- [ ] `module_name` = CD alias
- [ ] You understand the difference from [Use Case 12](/en/learn/implementer/training/optional/use-case-12-copilot-cd-lookup.md) (Copilot vs inline)

## Independent task

Add MessageKeyboard after found: “Search again” → loop to WaitForInput; “To menu” → capstone main menu.

## Reference links

- [Products seed CSV](/content/en/learn/implementer/training/scenarios/seed/products-training.csv)
- [Categorizer prompt](/content/en/learn/implementer/training/scenarios/prompts/categorizer-training.txt)
- [Categorizer pattern](/en/learn/implementer/training/concepts.md#categorizer-pattern)
- [Custom Data set](/en/customdata/how-to/use-custom-modules-set.md)
- [Fast Line Pro action](/en/fastlinepro/how-to/use-action-fastline-pro.md)
