← CookbookView source on GitHub ↗

Customer Support Resolution Agent

A SaaS-style customer support agent that answers product questions, looks up real order status, and escalates to a human ticket when it can't confidently resolve the issue.

Built with LangChain for the agent + tool-calling layer and Nebius Token Factory for both the LLM (Qwen/Qwen3-30B-A3B) and the embedding model (Qwen/Qwen3-Embedding-8B).

🚀 Features

🛠️ Tech Stack

🧰 The four tools

Tool What it does
lookup_order Order status, items, totals, tracking — gated on customer email
kb_search Semantic search across FAQ + policy docs
refund_policy_search Search restricted to the refund / returns policy
create_ticket Opens a human ticket and escalates the conversation

📦 Getting Started

Prerequisites

1. Install

cd agents/customer_support_resolution_agent
python -m venv .venv && source .venv/bin/activate
pip install -e .
# or with uv:
uv pip install -e .

2. Configure environment

cp env.example .env
# edit .env and add your NEBIUS_API_KEY

3. Build the knowledge base (one-time)

python ingest.py

This embeds the docs in data/*.md with Qwen/Qwen3-Embedding-8B and writes the FAISS index to kb_index/.

4. Run

Streamlit chat UI:

streamlit run app.py

Terminal CLI:

python main.py

💬 Demo prompts to try

Order Lookups

Policy & FAQ Questions

Escalation Scenarios

Combination Queries

📂 Project structure

customer_support_resolution_agent/
├── agent.py            # LangChain tool-calling agent + system prompt
├── tools.py            # lookup_order, kb_search, refund_policy_search, create_ticket
├── ingest.py           # Build / load FAISS index over data/*.md
├── app.py              # Streamlit chat UI
├── main.py             # Terminal CLI
├── data/
│   ├── faq.md
│   ├── refund_policy.md
│   ├── shipping_policy.md
│   ├── orders.json     # Sample order DB
│   └── tickets.json    # Tickets created by create_ticket
├── kb_index/           # FAISS index (created by ingest.py)
├── pyproject.toml
└── env.example

🧠 How escalation works

The agent's system prompt lists explicit conditions under which it must call create_ticket — low confidence from kb_search, customer asking for a human, damaged items, refund disputes, or any tool error it cannot resolve in one more step. When it escalates, it returns the ticket ID to the customer and the ticket is appended to data/tickets.json so you can see it in the Streamlit sidebar.

🔁 Extending it

📄 License

MIT — see the repo root LICENSE.