A demo AI-powered customer support assistant built in Python. It shows how an LLM provider (Anthropic or OpenAI) can be wrapped in a clean, testable application layer to automate repetitive customer-support conversations.
یک دستیار پشتیبانی مشتری مبتنی بر AI (نسخه دمو) که با پایتون ساخته شده. نشان میدهد چطور یک provider مدل زبانی (Anthropic یا OpenAI) میتواند در یک لایه اپلیکیشن تمیز و قابلتست بستهبندی شود تا مکالمات تکراری پشتیبانی مشتری را خودکار کند.
⚠️ This is a portfolio / educational project, not a production support platform. It uses a small, fictional demo knowledge base and has no connection to any real company, database, or customer data.این یک پروژه نمونهکار / آموزشی است، نه یک پلتفرم پشتیبانی production. از یک دانشپایه فرضی و کوچک استفاده میکند و هیچ اتصالی به شرکت، دیتابیس یا داده مشتری واقعی ندارد.
EN: Customer support teams often handle a high volume of repetitive questions — shipping times, refund policies, order status, address changes. This project demonstrates a small, working pipeline for automating first-line responses to such questions using an LLM, grounded in a fixed knowledge base and constrained by an explicit system prompt.
FA: تیمهای پشتیبانی مشتری معمولاً حجم بالایی از سؤالات تکراری را پاسخ میدهند — زمان ارسال، سیاست بازگشت وجه، وضعیت سفارش، تغییر آدرس. این پروژه یک pipeline کوچک و کارآمد برای خودکارسازی پاسخهای خط اول به این سؤالات با استفاده از LLM را نشان میدهد؛ پاسخها بر پایه یک دانشپایه ثابت و محدود به یک system prompt صریح هستند.
EN: Repetitive support questions consume human agent time that could be spent on complex cases. Manually scripted chatbots are brittle and can't handle natural phrasing.
FA: سؤالات تکراری پشتیبانی زمان agent های انسانی را میگیرد، در حالی که میتوانست صرف موارد پیچیدهتر شود. چتباتهای اسکریپتشده دستی شکنندهاند و نمیتوانند با جملهبندی طبیعی کار کنند.
EN: This project sends the customer's message — along with conversation history and a curated demo knowledge base — to an LLM through a clean provider abstraction. The system prompt explicitly instructs the model to stay grounded in the given facts, avoid inventing policies, and avoid claiming actions it can't actually perform.
FA: این پروژه پیام مشتری را همراه با تاریخچه مکالمه و یک دانشپایه دموی مشخص، از طریق یک لایه انتزاعی provider به یک LLM ارسال میکند. system prompt بهصراحت به مدل دستور میدهد که به دادههای دادهشده پایبند بماند، سیاست جدید اختراع نکند و ادعای انجام کاری که واقعاً نمیتواند انجام دهد را نکند.
Customer Message
↓
CLI / Python API
↓
SupportAssistant (orchestrator)
↓
Conversation history + System prompt + Demo knowledge base
↓
AIService (provider abstraction)
↓
Provider API (Anthropic / OpenAI)
↓
Assistant Response → Customer
flowchart TD
A[Customer Message] --> B[CLI / Python API]
B --> C[SupportAssistant]
C --> D[Conversation History]
C --> E[System Prompt]
C --> F[Demo Knowledge Base]
D --> G[AIService]
E --> G
F --> G
G --> H[Provider API<br/>Anthropic / OpenAI]
H --> I[Assistant Response]
I --> J[Customer]
See docs/architecture.md for a module-by-module
breakdown (bilingual).
EN (implemented only):
- Customer message input via interactive CLI or Python API
- AI response generation through Anthropic or OpenAI's chat APIs
- Multi-turn conversation history (in-memory, per session, sliding window)
- Explicit, reviewable system prompt controlling assistant behavior
- Provider abstraction (
AIService) isolating the external API - Centralized configuration loaded from environment variables
- Full error handling: missing/invalid key, timeout, connection failure, rate limiting, malformed response, empty input
- Logging that never logs secrets or raw sensitive payloads
- Small fictional demo knowledge base
- Unit test suite (32 tests) with all external calls mocked
FA (فقط موارد پیادهسازیشده):
- ورودی پیام مشتری از طریق CLI تعاملی یا API پایتون
- تولید پاسخ AI از طریق API چت Anthropic یا OpenAI
- تاریخچه مکالمه چندنوبتی (در حافظه، per session، پنجرهای)
- system prompt صریح و قابلبازبینی برای کنترل رفتار دستیار
- انتزاع provider (
AIService) که API خارجی را ایزوله میکند - پیکربندی متمرکز بارگذاریشده از environment variables
- مدیریت کامل خطا: کلید گمشده/نامعتبر، timeout، خطای اتصال، rate limit، پاسخ نامعتبر، ورودی خالی
- logging که هرگز secret یا داده حساس خام را لاگ نمیکند
- دانشپایه دموی فرضی کوچک
- مجموعه تست یونیت (۳۲ تست) با mock کامل فراخوانیهای خارجی
- Python 3.9+
requests— HTTP calls to the AI providerpython-dotenv— loading.envfilespytest/pytest-mock— testing- Anthropic Messages API or OpenAI Chat Completions API (your choice, via
AI_PROVIDER)
No web framework, database, or vector store is included — see Limitations and Future Improvements.
ai-customer-support-assistant/
├── README.md
├── LICENSE
├── .gitignore
├── .env.example
├── requirements.txt
├── requirements-dev.txt
├── pyproject.toml
├── FINAL_CHECKLIST.md
│
├── src/ai_support_assistant/
│ ├── __init__.py
│ ├── config.py # environment-based settings + validation
│ ├── logger.py # safe, centralized logging
│ ├── exceptions.py # InvalidInputError, AIProviderError
│ ├── prompts.py # system prompt / assistant behavior
│ ├── knowledge_base.py # loads DEMO knowledge base
│ ├── conversation.py # in-memory conversation history
│ ├── ai_service.py # provider abstraction (Anthropic / OpenAI)
│ ├── assistant.py # SupportAssistant orchestrator
│ ├── cli.py # interactive command-line interface
│ └── data/knowledge_base.json # fictional demo company data
│
├── examples/
│ ├── basic_usage.py # runnable example (needs a real API key)
│ └── sample_conversation.md # static example, no API key needed
│
├── tests/ # pytest suite, all external calls mocked
│
└── docs/
├── architecture.md
├── configuration.md
└── development.md
(No assets/ directory is included — this project has no screenshots or
images to ship, and an empty folder wasn't kept just to pad the structure.)
git clone <your-fork-url>
cd ai-customer-support-assistant
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env
# then edit .env and add your own AI_API_KEYSee .env.example and
docs/configuration.md for the full list. At
minimum:
AI_API_KEY=your_api_key_here
AI_PROVIDER=anthropic
Never commit a real API key. .env is already in .gitignore.
PYTHONPATH=src python -m ai_support_assistant.cliCustomer: How can I change my delivery address?
Assistant: You can change your delivery address as long as the order
hasn't entered "Processing" status yet...
Type reset to clear conversation history, exit/quit to leave.
from ai_support_assistant.assistant import SupportAssistant
assistant = SupportAssistant()
reply = assistant.ask("How can I change my delivery address?")
print(reply)See examples/basic_usage.py for a runnable
script and examples/sample_conversation.md
for a static example that doesn't require an API key.
Customer: "How can I change my delivery address?"
Assistant: Answers grounded only in the fictional demo knowledge base
(src/ai_support_assistant/data/knowledge_base.json) for "Northwind
Supplies" — not a real company. See
examples/sample_conversation.md for a
full sample.
PYTHONPATH=src python -m pytest tests/ -vAll 32 tests pass without a real API key — external HTTP calls are mocked.
EN:
- Anthropic integration: verified against the real Anthropic API endpoint using a controlled invalid-key test. The request format, headers/payload structure, and 401 error handling were confirmed to work correctly against the live endpoint (no valid key was used or required).
- OpenAI integration: implemented and covered by mocked unit tests only. It has not been verified against the live OpenAI API endpoint.
FA:
- اتصال Anthropic: با یک تست کنترلشده و کلید نامعتبر، در برابر endpoint واقعی Anthropic تأیید شد. فرمت request، ساختار headers/payload، و مدیریت خطای 401 در برابر endpoint زنده بهدرستی کار میکنند (هیچ کلید معتبری استفاده یا لازم نبود).
- اتصال OpenAI: پیادهسازی شده و با unit test های mock پوشش داده شده، ولی در برابر endpoint واقعی OpenAI تأیید نشده است.
EN:
- Requires a real API key from an external AI provider to generate live responses (Anthropic or OpenAI).
- The knowledge base is a small, fictional JSON file — not a real, searchable knowledge system.
- Conversation history is in-memory only and is lost when the process exits; there is no persistence layer.
- Not connected to any real customer database, order system, or CRM.
- Response quality and accuracy depend entirely on the configured LLM provider/model, which this project does not control or evaluate.
- Not a production support platform as-is — it has no auth, rate limiting for end users, multi-tenant isolation, or monitoring.
FA:
- برای تولید پاسخ زنده به یک کلید API واقعی از یک provider خارجی (Anthropic یا OpenAI) نیاز دارد.
- دانشپایه یک فایل JSON کوچک و فرضی است — یک سیستم دانش واقعی و قابلجستجو نیست.
- تاریخچه مکالمه فقط در حافظه است و با پایان پردازش از بین میرود؛ لایه persistence وجود ندارد.
- به هیچ دیتابیس مشتری، سیستم سفارش یا CRM واقعی متصل نیست.
- کیفیت و دقت پاسخ کاملاً به provider/مدل LLM پیکربندیشده بستگی دارد که این پروژه کنترل یا ارزیابی نمیکند.
- بههمینشکل یک پلتفرم پشتیبانی production نیست — احراز هویت، rate limiting برای کاربر نهایی، ایزولهسازی multi-tenant یا مانیتورینگ ندارد.
- Persist conversation history (e.g. SQLite/Postgres) per session.
- Replace the static JSON knowledge base with a retrieval system (vector search) over real documentation.
- Add a lightweight web API (e.g. FastAPI) as an alternative to the CLI.
- Add streaming responses for a more interactive feel.
- Add authentication and per-user rate limiting for any networked deployment.
- Add more providers behind the same
AIServiceabstraction.
EN: API keys and other secrets must always be provided via environment
variables (.env, excluded by .gitignore) — never hardcoded or committed.
Logging is designed to avoid printing secrets or raw sensitive payloads
(see src/ai_support_assistant/logger.py). Before publishing any fork,
re-scan the repository for accidentally committed credentials.
FA: کلیدهای API و سایر secret ها همیشه باید از طریق environment
variables (.env، که در .gitignore مستثنا شده) فراهم شوند — هرگز
hardcode یا commit نشوند. logging طوری طراحی شده که secret یا داده حساس
خام چاپ نکند (به src/ai_support_assistant/logger.py نگاه کنید). قبل از
انتشار هر fork، ریپازیتوری را دوباره برای credential های تصادفاً
commitشده اسکن کنید.
MIT — see LICENSE.