Prompt
I want to build a lead-routing agent that can read from our CRM and send Slack alerts, but only after a human approves risky actions. What's the best approach?
Latest observation
The best approach is to build this as a human-in-the-loop workflow agent, not a fully autonomous agent.
Recommended pattern
1) Separate “read”, “decide”, and “act”
Design the system in three stages:
- Read: pull lead data from the CRM
- Decide: classify the action as safe vs risky
- Act: only perform the action after approval when it’s risky
This keeps the agent useful while preventing it from taking sensitive actions on its own.
2) Define what counts as “risky”
Create policy rules for when approval is required. For example:
Safe actions
- Read lead records
- Tag or score leads
- Draft Slack messages
- Suggest routing recommendations
Risky actions
- Sending Slack alerts to external or executive channels
- Changing ownership on high-value leads
- Updating CRM fields that affect sales assignment
- Sending customer-facing messages
- Bulk actions
- Actions involving sensitive data or VIP accounts
A good rule: if the action could create customer impact, compliance risk, or operational disruption, require approval.
3) Use an approval gate
When the agent wants to take a risky action:
- It generates a proposed action
- It sends a concise approval request to a human reviewer
- The reviewer approves or rejects
- Only then does the system execute the action
For Slack alerts, this could mean:
- The agent drafts the message
- Human approves the draft
- System posts it to Slack after approval
4) Give the agent narrow tools
Don’t let the agent freely access everything. Expose only controlled functions like:
get_leads(query)evaluate_routing_rules(lead)draft_slack_alert(lead, reason)request_approval(action)send_slack_alert(message)— only callable after approvalupdate_crm_owner(lead_id, owner)— only after approval for risky cases
The key is to enforce approval in the tool layer, not just in the prompt.
5) Make approval state machine-based
Use an explicit workflow state machine, such as:
NEWREVIEW_NEEDEDAPPROVEDREJECTEDEXECUTEDFAILED
This helps with:
- auditability
- retries
- preventing duplicate sends
- preserving who approved what and when
6) Log everything
For compliance and debugging, store:
- lead ID
- source CRM data used
- reason for action
- risk classification
- proposed action
- approver identity
- timestamp
- final execution result
This is especially important if the agent routes leads differently based on rules or model output.
7) Start with deterministic rules, then add AI
A practical implementation is:
- Phase 1: rules-based routing
- Phase 2: AI-assisted classification and message drafting
- Phase 3: limited autonomy for low-risk actions only
This reduces failure modes and makes it easier to trust the system.
8) Keep the human approval experience simple
Approvals should be easy to review. Show:
- lead name
- account size / priority
- proposed action
- why the agent thinks it’s risky
- suggested Slack message
- buttons: Approve / Reject
If approvals are cumbersome, people will ignore them or rubber-stamp them.
A solid architecture
CRM → Lead Processor → Risk Classifier → Approval Queue → Human Reviewer → Execution Worker → Slack/CRM
Key properties:
- The agent can read and suggest
- It cannot execute risky actions directly
- Execution worker only runs after approval token is present
Implementation tips
- Use webhooks or polling from CRM
- Use a message queue for pending approvals
- Make approvals idempotent
- Restrict Slack permissions to specific channels
- Rate-limit actions
- Use secrets management for API tokens
- Keep a fallback for manual routing if the agent or approval flow fails
Short answer
The best approach is to build a workflow agent with mandatory human approval for risky actions, enforced by the application logic/tooling layer, not just by prompt instructions.
If you want, I can sketch a concrete architecture diagram or provide a sample implementation in Python/Node using CRM + Slack + approval workflow.
Brands