Implementation of a voice AI bot for surveys and questionnaires. Voice surveys provide a 2-3 times higher response rate compared to SMS/email—people are more willing to talk than fill out forms. The AI bot conducts a structured survey, recognizing numerical ratings and detailed answers. ### Survey question types
from dataclasses import dataclass
from enum import Enum
class QuestionType(Enum):
NPS = "nps" # оценка 0-10
CSAT = "csat" # оценка 1-5
YESNO = "yesno" # да/нет
OPEN = "open" # развёрнутый ответ
CHOICE = "choice" # выбор из вариантов
@dataclass
class SurveyQuestion:
id: str
text: str
type: QuestionType
options: list[str] = None
next_question: dict = None # conditional branching
SURVEY_TEMPLATE = [
SurveyQuestion(
id="overall_satisfaction",
text="По шкале от 1 до 10, как бы вы оценили наш сервис?",
type=QuestionType.NPS,
next_question={
"low": "reason_low", # <7
"high": "recommend" # >=7
}
),
SurveyQuestion(
id="reason_low",
text="Что нам нужно улучшить? Расскажите своими словами.",
type=QuestionType.OPEN,
),
SurveyQuestion(
id="recommend",
text="Порекомендуете нас друзьям?",
type=QuestionType.YESNO,
),
]
```### Extracting Numerical Estimates```python
import re
async def extract_rating(text: str, scale: tuple = (1, 10)) -> int | None:
"""Извлекаем числовую оценку из текста"""
# Сначала пробуем прямое число
numbers = re.findall(r'\b([0-9]|10)\b', text)
if numbers:
rating = int(numbers[0])
if scale[0] <= rating <= scale[1]:
return rating
# Словесные оценки
rating_words = {
"отлично": 10, "замечательно": 9, "хорошо": 8,
"нормально": 6, "плохо": 4, "ужасно": 2, "единица": 1
}
for word, value in rating_words.items():
if word in text.lower():
return value
# Через LLM для сложных случаев
response = await client.chat.completions.create(
model="gpt-4o-mini",
messages=[{
"role": "user",
"content": f"Клиент сказал: '{text}'. Определи оценку от {scale[0]} до {scale[1]}. Только число или null."
}]
)
result = response.choices[0].message.content.strip()
return int(result) if result.isdigit() else None
```### Saving results```python
async def save_survey_result(phone: str, results: dict):
await db.survey_responses.insert_one({
"phone": phone,
"completed_at": datetime.utcnow(),
"scores": results.get("scores"),
"open_answers": results.get("open_answers"),
"nps_category": categorize_nps(results.get("scores", {}).get("overall")),
"duration_seconds": results.get("duration")
})
```Timeframe: 5-7 question survey – 2 weeks. Survey management system with analytics – 4-6 weeks.