# Project Spec: Multi-Agent CRM Customer-Success System

## 1. Goal

Build a multi-agent system that observes customer behavior in a CRM, detects meaningful changes, investigates the cause using CRM data, assesses customer health, recommends the next best action, and executes approved actions.

This is not a chatbot with several prompts. It is one business process implemented as a coordinated set of specialized agents:

```text
Observe → Investigate → Reason → Decide → Act → Update
```

Example: a customer starts having delivery problems.

```text
Delivery problems → more support tickets → negative interactions → lower engagement
→ fewer orders → revenue decline → customer at risk → CRM event → investigation
→ recommended action → task → human approval → execution
```

No single column says "this customer will churn because of delivery problems". The agents must build that explanation from the evidence.

---

## 2. CRM data model

```text
Customer
   ├── Contacts
   ├── Opportunities
   ├── Orders
   │      └── Invoices
   ├── Interactions
   ├── Support Tickets
   ├── Tasks
   └── Business Events
```

| Table | Fields |
|---|---|
| customers | customer_id, company_name, industry, segment, customer_since, account_owner, status, baseline_monthly_revenue |
| contacts | contact_id, customer_id, name, role, email, phone |
| opportunities | opportunity_id, customer_id, created_at, stage, amount, probability, product_interest |
| orders | order_id, customer_id, order_date, amount, status, product |
| invoices | invoice_id, customer_id, order_id, issue_date, due_date, amount, paid_date, payment_status |
| interactions | interaction_id, customer_id, date, type (call, email, meeting, demo), channel, sentiment, summary |
| support_tickets | ticket_id, customer_id, created_at, category (delivery, service, billing, product_quality), priority, status, resolution_time, summary |
| tasks | task_id, customer_id, created_at, task_type, priority, due_date, status, owner, summary |
| business_events | event_id, customer_id, event_type, severity, trigger, created_at |
| ground_truth | customer_id, archetype, expected_state, causal_chain (evaluation only) |

Event types: `CUSTOMER_HEALTH_CHANGED`, `PAYMENT_RISK_DETECTED`, `EXPANSION_SIGNAL`, `NO_ACTION`.

A business event is a signal to start the workflow, not the final answer.

---

## 3. Synthetic data must be causal

Rows are not generated independently. Each customer has a hidden story (archetype) that drives a monthly latent state, and that state drives every table:

```text
Archetype → baseline → monthly latent state → revenue, orders, interactions,
tickets, payments → CRM records → observable business event
```

Example, `service_failure`:

```text
Month 1  normal service, orders, interactions
Month 2  small service problem
Month 3  more service tickets, more negative interactions
Month 4  engagement falls, orders decline
Month 5  revenue declines
Month 6  customer is at risk
```

### Archetypes

| Archetype | Pattern |
|---|---|
| healthy | stable revenue, orders, interactions; low support pressure; normal payments |
| service_failure | service problem → tickets up → negative sentiment → engagement down → orders down → revenue down |
| payment_problem | payment delays → overdue invoices → financial and commercial risk |
| silent_churn | no complaints; engagement, interactions, orders, and revenue decline |
| expansion | engagement up → orders up → revenue up → expansion opportunity |
| high_growth | stronger version of expansion |
| product_quality | quality complaints → tickets → negative interactions → orders and revenue down |
| competitive_threat | subtle signs of evaluating alternatives |
| seasonal_dip | temporary decline for contextual reasons, then recovery |
| recovery | past problems improving: fewer tickets, engagement, orders, and revenue recover |

### Size

50 customers, 6 months. Approximate volumes: 100 contacts, 50 opportunities, ~670 orders, ~670 invoices, ~1,100 interactions, ~300 tickets, ~300 tasks, 50 business events. Relational consistency matters more than exact counts.

### Hidden ground truth

The generator stores each customer's archetype, expected state, and causal chain in `ground_truth`. Agents must never see it. It exists only for evaluation.

---

## 4. Agents

| # | Agent | Question | Output |
|---|---|---|---|
| 1 | Event Detector | Did something important happen? | BusinessEvent (type, severity, trigger) |
| 2 | Research | What is going on with this customer? | EvidencePack |
| 3 | Analyst | Why is this happening? | Diagnosis (hypotheses, evidence for/against, primary cause, confidence) |
| 4 | Customer Health | What state is the customer in? | HealthAssessment (state, temporary vs structural, rationale) |
| 5 | Next Best Action | What should we do? | ActionProposal (action, priority, owner, message draft, risk level) |

Health states: `HEALTHY`, `GROWING`, `EXPANSION_OPPORTUNITY`, `AT_RISK`, `PAYMENT_RISK`, `RECOVERING`.

Example actions:

- Service problem: high-priority customer-success task for the account owner, recommended call, follow-up message draft.
- Payment problem: finance follow-up, prioritize overdue invoices, notify the account owner.
- Expansion: expansion task, relevant product or opportunity, account-review recommendation.
- Healthy: no action.

The Event Detector does not investigate. The Research agent does not diagnose. Each agent has one responsibility, specific tools, structured input and output, and limited authority.

---

## 5. Pipeline

```text
CRM database
  → Event Detector → BusinessEvent
  → Research → EvidencePack
  → Analyst → Diagnosis
  → Customer Health → HealthAssessment
  → Next Best Action → ActionProposal
  → Human approval / policy
  → Execution tools
  → CRM updated → next event
```

---

## 6. Tools

Agents access the CRM only through tools, never directly.

Read tools:

```text
get_customer(customer_id)
get_contacts(customer_id)
get_orders(customer_id, start_date, end_date)
get_invoices(customer_id, status=None)
get_interactions(customer_id, start_date, end_date)
get_support_tickets(customer_id, status=None)
get_opportunities(customer_id)
get_tasks(customer_id)
```

Analytics tools:

```text
calculate_revenue_trend()
calculate_order_frequency()
calculate_customer_engagement()
calculate_support_pressure()
calculate_payment_risk()
compare_periods()
```

Execution tools:

```text
create_task()
update_task()
create_note()
prepare_customer_message()
update_customer_status()
send_email()
```

### Selective retrieval

Do not send the whole database to the LLM. The agent decides what it needs based on the event. For `PAYMENT_RISK_DETECTED`, it should prioritize invoices, orders, and account history over every interaction and ticket.

### SQL vs LLM

SQL/code computes: monthly revenue, order count, average order value, ticket count and growth, interaction count, overdue invoice count, percentage changes.

The LLM reasons about: what the pattern means, plausible causes, which evidence supports each hypothesis, whether the change is temporary or structural, and what to do next.

---

## 7. Reasoning requirements

### Causal hypothesis from correlated evidence

```text
Observed: revenue −28%, orders −23%, interactions −31%, tickets +190%,
delivery tickets +250%, negative sentiment up, overdue invoices = 0

Payment problem?   No, invoices are normal.
Lack of demand?    Possible, but support pressure is unusually high.
Delivery tickets and negative interactions rose sharply.
→ Likely service/delivery deterioration.

Diagnosis: at risk, primarily due to service deterioration.
Action: account manager contacts the customer to resolve the delivery issue.
```

### Avoid false positives

A revenue drop alone does not mean churn. It may be seasonality, a purchasing cycle, or an inventory adjustment. Decisions must combine multiple signals and consider the trajectory, not only current values.

---

## 8. Human approval and autonomy

| Level | Behavior |
|---|---|
| 1 | Recommend only |
| 2 | Create internal CRM tasks and notes automatically |
| 3 | Prepare customer messages; sending requires approval |
| 4 | Execute low-risk actions automatically; high-risk actions still require approval |

Email modes: `dry_run` (log only), `redirect` (all emails go to one test inbox), `live` (send to the contact). Default is `dry_run`.

---

## 9. Evaluation

Ground truth enables measurement:

| Dimension | Question |
|---|---|
| Event detection | Were the important customers flagged? |
| Diagnosis | Is the primary cause correct or plausible? |
| Evidence quality | Did the agent use the right CRM evidence? |
| State classification | Healthy, at-risk, growth, payment-risk, recovering: correct? |
| Action quality | Is the action appropriate for the situation? |
| Tool efficiency | How many unnecessary tool calls? |
| Execution correctness | Was the right task or update created? |

Diagnosis is scored by meaning, not string equality. "Delivery/service deterioration" matches `service_failure`.

---

## 10. Build stages

1. CRM data model and synthetic data
2. Single agent with tools ("What is happening with customer C017?")
3. Multiple read and analytics tools
4. Event-driven trigger
5. Multi-agent pipeline
6. Execution tools
7. Human approval and autonomy levels
8. Evaluation against ground truth

Reference scenario: a previously healthy customer becomes at risk. The system detects it, investigates, diagnoses service deterioration with evidence, classifies the customer as `AT_RISK`, proposes a high-priority follow-up, waits for approval, creates the task, and the new CRM state becomes part of the customer's history.

---

## 11. Out of scope

Authentication, complex frontend, real company integrations, production-scale database, full CRM UI, real customer emails, large datasets, complex ML models, GNNs, RAG over large document sets, fine-tuning.

---

## 12. Technical architecture

```text
SQLite (replaceable by PostgreSQL or a CRM API)
  → Tool layer
  → Orchestrator
  → Event Detector, Research, Analyst, Customer Health, Next Best Action
  → Approval / policy
  → Execution tools
```

Stack: Python (FastAPI, pydantic, SQLite), AvalAI (OpenAI-compatible LLM API), Resend (email), minimal Next.js approval UI.

---

## 13. Core concepts

- **Agent vs LLM:** an agent is LLM + tools + state + instructions + a decision loop.
- **Tool calling:** agents read and change data only through explicit tools.
- **Structured data reasoning:** deterministic numbers from SQL/code; the LLM interprets them.
- **Specialization:** each agent has one responsibility.
- **Event-driven agents:** triggered by business events, not only by user prompts.
- **Orchestration:** structured outputs passed between agents.
- **State:** customer history matters.
- **Guardrails and human-in-the-loop:** not every action runs automatically.
- **Evaluation:** measured against ground truth, not "the answer looks good".
