atendentepro 0.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- atendentepro/README.md +890 -0
- atendentepro/__init__.py +215 -0
- atendentepro/agents/__init__.py +45 -0
- atendentepro/agents/answer.py +62 -0
- atendentepro/agents/confirmation.py +69 -0
- atendentepro/agents/flow.py +64 -0
- atendentepro/agents/interview.py +68 -0
- atendentepro/agents/knowledge.py +296 -0
- atendentepro/agents/onboarding.py +65 -0
- atendentepro/agents/triage.py +57 -0
- atendentepro/agents/usage.py +56 -0
- atendentepro/config/__init__.py +19 -0
- atendentepro/config/settings.py +134 -0
- atendentepro/guardrails/__init__.py +21 -0
- atendentepro/guardrails/manager.py +419 -0
- atendentepro/license.py +502 -0
- atendentepro/models/__init__.py +21 -0
- atendentepro/models/context.py +21 -0
- atendentepro/models/outputs.py +118 -0
- atendentepro/network.py +325 -0
- atendentepro/prompts/__init__.py +35 -0
- atendentepro/prompts/answer.py +114 -0
- atendentepro/prompts/confirmation.py +124 -0
- atendentepro/prompts/flow.py +112 -0
- atendentepro/prompts/interview.py +123 -0
- atendentepro/prompts/knowledge.py +135 -0
- atendentepro/prompts/onboarding.py +146 -0
- atendentepro/prompts/triage.py +42 -0
- atendentepro/templates/__init__.py +51 -0
- atendentepro/templates/manager.py +530 -0
- atendentepro/utils/__init__.py +19 -0
- atendentepro/utils/openai_client.py +154 -0
- atendentepro/utils/tracing.py +71 -0
- atendentepro-0.3.0.dist-info/METADATA +306 -0
- atendentepro-0.3.0.dist-info/RECORD +39 -0
- atendentepro-0.3.0.dist-info/WHEEL +5 -0
- atendentepro-0.3.0.dist-info/entry_points.txt +2 -0
- atendentepro-0.3.0.dist-info/licenses/LICENSE +25 -0
- atendentepro-0.3.0.dist-info/top_level.txt +1 -0
atendentepro/README.md
ADDED
|
@@ -0,0 +1,890 @@
|
|
|
1
|
+
# AtendentePro 🤖
|
|
2
|
+
|
|
3
|
+
**Sistema de Atendimento Inteligente com Múltiplos Agentes IA**
|
|
4
|
+
|
|
5
|
+
Uma biblioteca Python modular e independente para criar sistemas de atendimento automatizado usando múltiplos agentes de IA especializados baseados no OpenAI Agents SDK.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 📦 Instalação
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Ativar ambiente virtual
|
|
13
|
+
source venv/bin/activate
|
|
14
|
+
|
|
15
|
+
# Instalar a biblioteca
|
|
16
|
+
pip install -e .
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 🔑 Ativação (Obrigatório)
|
|
22
|
+
|
|
23
|
+
A biblioteca AtendentePro **requer um token de licença** para funcionar. Sem ativação, a biblioteca lançará um erro ao tentar criar agentes ou redes.
|
|
24
|
+
|
|
25
|
+
### Opção 1: Ativar via Código
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
from atendentepro import activate
|
|
29
|
+
|
|
30
|
+
# Ativar a biblioteca
|
|
31
|
+
activate("ATP_seu-token-aqui")
|
|
32
|
+
|
|
33
|
+
# ✅ Agora pode usar normalmente
|
|
34
|
+
from atendentepro import create_standard_network
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Opção 2: Variável de Ambiente
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Definir no terminal ou no .env
|
|
41
|
+
export ATENDENTEPRO_LICENSE_KEY="ATP_seu-token-aqui"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
# A biblioteca ativa automaticamente se encontrar a variável
|
|
46
|
+
from atendentepro import create_standard_network # ✅ Funciona automaticamente
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Opção 3: Arquivo .env
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# .env
|
|
53
|
+
ATENDENTEPRO_LICENSE_KEY=ATP_seu-token-aqui
|
|
54
|
+
OPENAI_API_KEY=sua-chave-openai
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
from dotenv import load_dotenv
|
|
59
|
+
load_dotenv()
|
|
60
|
+
|
|
61
|
+
from atendentepro import create_standard_network # ✅ Funciona automaticamente
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Verificar Status da Licença
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
from atendentepro import is_activated, get_license_info
|
|
68
|
+
|
|
69
|
+
# Verificar se está ativado
|
|
70
|
+
if is_activated():
|
|
71
|
+
info = get_license_info()
|
|
72
|
+
print(f"Organização: {info.organization}")
|
|
73
|
+
print(f"Expira em: {info.expiration or 'Sem expiração'}")
|
|
74
|
+
print(f"Features: {info.features}")
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Obter um Token
|
|
78
|
+
|
|
79
|
+
Entre em contato para obter seu token de licença:
|
|
80
|
+
- 📧 **Email:** contato@bemonkai.com
|
|
81
|
+
- 🌐 **Site:** https://bemonkai.com
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## ⚡ Início Rápido
|
|
86
|
+
|
|
87
|
+
### 1. Ativar + Configurar Variáveis de Ambiente
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# Token de licença
|
|
91
|
+
export ATENDENTEPRO_LICENSE_KEY="ATP_seu-token"
|
|
92
|
+
|
|
93
|
+
# Para OpenAI
|
|
94
|
+
export OPENAI_API_KEY="sua-chave-openai"
|
|
95
|
+
|
|
96
|
+
# Para Azure OpenAI (opcional)
|
|
97
|
+
export OPENAI_PROVIDER="azure"
|
|
98
|
+
export AZURE_API_KEY="sua-chave-azure"
|
|
99
|
+
export AZURE_API_ENDPOINT="https://seu-endpoint.openai.azure.com"
|
|
100
|
+
export AZURE_API_VERSION="2024-02-15-preview"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 2. Uso Programático
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
from pathlib import Path
|
|
107
|
+
from atendentepro import activate, create_standard_network
|
|
108
|
+
from agents import Runner
|
|
109
|
+
import asyncio
|
|
110
|
+
|
|
111
|
+
# 1. Ativar (ou use variável de ambiente)
|
|
112
|
+
activate("ATP_seu-token")
|
|
113
|
+
|
|
114
|
+
async def main():
|
|
115
|
+
# 2. Criar rede com template específico
|
|
116
|
+
network = create_standard_network(
|
|
117
|
+
templates_root=Path("./client_templates"),
|
|
118
|
+
client="meu_cliente"
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
# 3. Executar conversa
|
|
122
|
+
result = await Runner.run(
|
|
123
|
+
network.triage,
|
|
124
|
+
[{"role": "user", "content": "Olá, preciso de ajuda"}]
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
print(result.final_output)
|
|
128
|
+
|
|
129
|
+
asyncio.run(main())
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## 🏗️ Arquitetura
|
|
135
|
+
|
|
136
|
+
### Analogia: O Restaurante Inteligente 🍽️
|
|
137
|
+
|
|
138
|
+
Imagine o **AtendentePro** como um **restaurante sofisticado** onde cada funcionário tem uma função específica:
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
142
|
+
│ 🍽️ RESTAURANTE ATENDENTEPRO │
|
|
143
|
+
├─────────────────────────────────────────────────────────────────────────┤
|
|
144
|
+
│ │
|
|
145
|
+
│ 👤 CLIENTE chega e é recebido pelo: │
|
|
146
|
+
│ │
|
|
147
|
+
│ 🚪 RECEPCIONISTA (Triage Agent) │
|
|
148
|
+
│ └─ "Boa noite! Você quer jantar, fazer reserva ou tirar dúvida?" │
|
|
149
|
+
│ Ele IDENTIFICA a intenção e DIRECIONA para o setor certo. │
|
|
150
|
+
│ │
|
|
151
|
+
│ ┌────────────────┬────────────────┬────────────────┬───────────────┐ │
|
|
152
|
+
│ │ │ │ │ │ │
|
|
153
|
+
│ ▼ ▼ ▼ ▼ ▼ │
|
|
154
|
+
│ │
|
|
155
|
+
│ 📋 MAITRE 📚 SOMMELIER ✅ CONFIRMA ❓ CONCIERGE │
|
|
156
|
+
│ (Flow Agent) (Knowledge) (Confirmation) (Usage) │
|
|
157
|
+
│ "Temos 3 "Nosso vinho "Confirma a "Deixa eu │
|
|
158
|
+
│ opções de premiado é reserva para te explicar │
|
|
159
|
+
│ menu hoje" o Malbec 2019" 2 pessoas?" como funciona" │
|
|
160
|
+
│ │
|
|
161
|
+
│ │ │
|
|
162
|
+
│ ▼ │
|
|
163
|
+
│ │
|
|
164
|
+
│ 📝 GARÇOM (Interview Agent) │
|
|
165
|
+
│ └─ Coleta as informações: "Quantas pessoas? Alguma alergia?" │
|
|
166
|
+
│ │
|
|
167
|
+
│ │ │
|
|
168
|
+
│ ▼ │
|
|
169
|
+
│ │
|
|
170
|
+
│ 🍳 CHEF (Answer Agent) │
|
|
171
|
+
│ └─ Prepara a resposta final com todas as informações │
|
|
172
|
+
│ │
|
|
173
|
+
│ │ │
|
|
174
|
+
│ ▼ │
|
|
175
|
+
│ │
|
|
176
|
+
│ 🎉 PRATO ENTREGUE (Resposta ao usuário) │
|
|
177
|
+
│ │
|
|
178
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**Traduzindo para o código:**
|
|
182
|
+
|
|
183
|
+
| Restaurante | AtendentePro | Função |
|
|
184
|
+
|-------------|--------------|--------|
|
|
185
|
+
| 🚪 Recepcionista | **Triage Agent** | Identifica necessidade e direciona |
|
|
186
|
+
| 📋 Maître | **Flow Agent** | Apresenta opções disponíveis |
|
|
187
|
+
| 📝 Garçom | **Interview Agent** | Coleta informações necessárias |
|
|
188
|
+
| 🍳 Chef | **Answer Agent** | Prepara a resposta final |
|
|
189
|
+
| 📚 Sommelier | **Knowledge Agent** | Consulta base de conhecimento |
|
|
190
|
+
| ✅ Confirmador | **Confirmation Agent** | Valida com sim/não |
|
|
191
|
+
| ❓ Concierge | **Usage Agent** | Explica como funciona |
|
|
192
|
+
| 🆕 Recepção VIP | **Onboarding Agent** | Cadastra novos clientes |
|
|
193
|
+
| 🚫 Segurança | **Guardrails** | Define o que pode/não pode ser feito |
|
|
194
|
+
| 📖 Menu/Cardápio | **YAML Configs** | Configurações de cada "funcionário" |
|
|
195
|
+
|
|
196
|
+
**E os módulos do código?**
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
atendentepro/ # 🍽️ O RESTAURANTE
|
|
200
|
+
├── config/ # ⚙️ Regras gerais (horário, API keys)
|
|
201
|
+
├── agents/ # 👥 Funcionários (fabricas de agentes)
|
|
202
|
+
├── prompts/ # 📜 Scripts de atendimento
|
|
203
|
+
├── guardrails/ # 🚫 Políticas de segurança
|
|
204
|
+
├── templates/ # 📋 Carrega cardápios personalizados
|
|
205
|
+
├── models/ # 📦 Formatos de dados
|
|
206
|
+
├── utils/ # 🔧 Utilitários
|
|
207
|
+
└── network.py # 🔗 Como os funcionários se conectam
|
|
208
|
+
|
|
209
|
+
client_templates/ # 📖 CARDÁPIOS DIFERENTES
|
|
210
|
+
├── standard/ # Menu básico
|
|
211
|
+
├── restaurante_italiano/ # Menu italiano
|
|
212
|
+
└── sushi_bar/ # Menu japonês
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Fluxo típico de uma conversa:**
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
1. Cliente: "Quero fazer um pedido"
|
|
219
|
+
└─> Recepcionista (Triage) identifica: "É um pedido!"
|
|
220
|
+
|
|
221
|
+
2. Recepcionista passa para Maître (Flow)
|
|
222
|
+
└─> "Temos pizza, massa ou sobremesa. O que prefere?"
|
|
223
|
+
|
|
224
|
+
3. Cliente: "Pizza"
|
|
225
|
+
└─> Maître passa para Garçom (Interview)
|
|
226
|
+
|
|
227
|
+
4. Garçom: "Qual sabor? Borda recheada?"
|
|
228
|
+
└─> Cliente responde as perguntas
|
|
229
|
+
|
|
230
|
+
5. Garçom passa para Chef (Answer)
|
|
231
|
+
└─> "Perfeito! Sua pizza de calabresa com borda recheada
|
|
232
|
+
será entregue em 30 minutos. Valor: R$ 45,00"
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
### Fluxograma Geral
|
|
238
|
+
|
|
239
|
+
```mermaid
|
|
240
|
+
flowchart TB
|
|
241
|
+
subgraph ENTRADA["ENTRADA"]
|
|
242
|
+
USER[("Usuario")]
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
subgraph CORE["ATENDENTEPRO CORE"]
|
|
246
|
+
subgraph CONFIG["Configuracao"]
|
|
247
|
+
ENV[".env"]
|
|
248
|
+
OPENAI["OpenAI Client"]
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
subgraph TEMPLATES["Template Manager"]
|
|
252
|
+
YAML["Arquivos YAML"]
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
subgraph NETWORK["AGENT NETWORK"]
|
|
257
|
+
TRIAGE["Triage Agent<br/>Classificacao inicial"]
|
|
258
|
+
FLOW["Flow Agent<br/>Apresenta opcoes"]
|
|
259
|
+
INTERVIEW["Interview Agent<br/>Coleta informacoes"]
|
|
260
|
+
ANSWER["Answer Agent<br/>Resposta final"]
|
|
261
|
+
KNOWLEDGE["Knowledge Agent<br/>Consulta dados/RAG"]
|
|
262
|
+
CONFIRMATION["Confirmation Agent<br/>Validacao"]
|
|
263
|
+
USAGE["Usage Agent<br/>Ajuda"]
|
|
264
|
+
ONBOARDING["Onboarding Agent<br/>Cadastro"]
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
subgraph TOOLS["TOOLS"]
|
|
268
|
+
RAG["RAG/Embeddings"]
|
|
269
|
+
CSV["CSV/Database"]
|
|
270
|
+
CUSTOM["Custom Tools"]
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
subgraph GUARDRAILS["GUARDRAILS"]
|
|
274
|
+
SCOPE["Validacao Escopo"]
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
subgraph OUTPUT["SAIDA"]
|
|
278
|
+
RESPONSE[("Resposta")]
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
USER --> TRIAGE
|
|
282
|
+
ENV --> OPENAI --> NETWORK
|
|
283
|
+
YAML --> TEMPLATES --> NETWORK
|
|
284
|
+
|
|
285
|
+
TRIAGE -->|"consulta"| KNOWLEDGE
|
|
286
|
+
TRIAGE -->|"opcoes"| FLOW
|
|
287
|
+
TRIAGE -->|"confirmacao"| CONFIRMATION
|
|
288
|
+
TRIAGE -->|"ajuda"| USAGE
|
|
289
|
+
TRIAGE -->|"cadastro"| ONBOARDING
|
|
290
|
+
|
|
291
|
+
FLOW -->|"coletar"| INTERVIEW
|
|
292
|
+
FLOW -->|"voltar"| TRIAGE
|
|
293
|
+
INTERVIEW -->|"responder"| ANSWER
|
|
294
|
+
ANSWER -->|"nova pergunta"| TRIAGE
|
|
295
|
+
|
|
296
|
+
KNOWLEDGE --> TRIAGE
|
|
297
|
+
CONFIRMATION --> TRIAGE
|
|
298
|
+
USAGE --> TRIAGE
|
|
299
|
+
ONBOARDING --> TRIAGE
|
|
300
|
+
|
|
301
|
+
KNOWLEDGE --> RAG & CSV & CUSTOM
|
|
302
|
+
GUARDRAILS --> NETWORK
|
|
303
|
+
|
|
304
|
+
ANSWER --> RESPONSE
|
|
305
|
+
KNOWLEDGE --> RESPONSE
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Fluxo de Handoffs
|
|
309
|
+
|
|
310
|
+
```mermaid
|
|
311
|
+
flowchart LR
|
|
312
|
+
T["Triage"]
|
|
313
|
+
F["Flow"]
|
|
314
|
+
I["Interview"]
|
|
315
|
+
A["Answer"]
|
|
316
|
+
K["Knowledge"]
|
|
317
|
+
C["Confirmation"]
|
|
318
|
+
U["Usage"]
|
|
319
|
+
O["Onboarding"]
|
|
320
|
+
|
|
321
|
+
T --> F & K & C & U & O
|
|
322
|
+
F --> I & T
|
|
323
|
+
I --> A
|
|
324
|
+
A --> T & I
|
|
325
|
+
K --> T
|
|
326
|
+
C --> T
|
|
327
|
+
U --> T
|
|
328
|
+
O --> T
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Estrutura de Componentes
|
|
332
|
+
|
|
333
|
+
```mermaid
|
|
334
|
+
graph TB
|
|
335
|
+
subgraph LIB["atendentepro/"]
|
|
336
|
+
CFG["config/"]
|
|
337
|
+
AGENTS["agents/"]
|
|
338
|
+
MODELS["models/"]
|
|
339
|
+
PROMPTS["prompts/"]
|
|
340
|
+
GUARDS["guardrails/"]
|
|
341
|
+
TEMPS["templates/"]
|
|
342
|
+
UTILS["utils/"]
|
|
343
|
+
NET["network.py"]
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
subgraph CLI["client_templates/"]
|
|
347
|
+
STD["standard/"]
|
|
348
|
+
CUSTOM["meu_cliente/"]
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
subgraph EX["examples/"]
|
|
352
|
+
RUN["run_*.py"]
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
LIB --> CLI --> EX
|
|
356
|
+
|
|
357
|
+
CFG --> AGENTS
|
|
358
|
+
TEMPS --> AGENTS
|
|
359
|
+
GUARDS --> AGENTS
|
|
360
|
+
PROMPTS --> AGENTS
|
|
361
|
+
MODELS --> AGENTS
|
|
362
|
+
AGENTS --> NET
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### Estrutura da Biblioteca
|
|
366
|
+
|
|
367
|
+
```
|
|
368
|
+
atendentepro/
|
|
369
|
+
├── __init__.py # API publica principal
|
|
370
|
+
├── config/ # Configuracoes globais
|
|
371
|
+
├── models/ # Modelos Pydantic
|
|
372
|
+
├── agents/ # Fabricas de agentes
|
|
373
|
+
├── prompts/ # Prompts modulares
|
|
374
|
+
├── guardrails/ # Validacao de escopo
|
|
375
|
+
├── templates/ # Gerenciamento de templates
|
|
376
|
+
├── utils/ # Utilitarios
|
|
377
|
+
└── network.py # Configuracao de rede
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### Templates de Clientes (Externos)
|
|
381
|
+
|
|
382
|
+
Os templates de clientes ficam **fora** da biblioteca principal, na pasta `client_templates/`:
|
|
383
|
+
|
|
384
|
+
```
|
|
385
|
+
client_templates/
|
|
386
|
+
├── standard/ # Template base/genérico
|
|
387
|
+
│ ├── triage_config.yaml
|
|
388
|
+
│ ├── flow_config.yaml
|
|
389
|
+
│ ├── interview_config.yaml
|
|
390
|
+
│ ├── answer_config.yaml
|
|
391
|
+
│ ├── knowledge_config.yaml
|
|
392
|
+
│ ├── confirmation_config.yaml
|
|
393
|
+
│ ├── onboarding_config.yaml
|
|
394
|
+
│ └── guardrails_config.yaml
|
|
395
|
+
└── meu_cliente/ # Template específico
|
|
396
|
+
├── __init__.py # (Opcional) Pacote Python
|
|
397
|
+
├── network.py # (Opcional) Rede específica
|
|
398
|
+
├── tools.py # (Opcional) Tools customizadas
|
|
399
|
+
├── *.yaml # Configurações
|
|
400
|
+
└── data/ # (Opcional) Dados
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
> ⚠️ **Importante**: Configurações específicas de clientes (como `network.py`, `tools.py`)
|
|
404
|
+
> ficam SEMPRE na pasta do cliente, não na biblioteca principal `atendentepro`.
|
|
405
|
+
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
## 🔧 Agentes Disponíveis
|
|
409
|
+
|
|
410
|
+
| Agente | Descrição |
|
|
411
|
+
|--------|-----------|
|
|
412
|
+
| **Triage** | Identifica necessidade e direciona para agente especializado |
|
|
413
|
+
| **Flow** | Identifica tópicos e apresenta opções ao usuário |
|
|
414
|
+
| **Interview** | Coleta informações através de perguntas estruturadas |
|
|
415
|
+
| **Answer** | Sintetiza respostas finais com dados coletados |
|
|
416
|
+
| **Knowledge** | Pesquisa em documentos (RAG) e dados estruturados |
|
|
417
|
+
| **Confirmation** | Valida hipóteses com respostas sim/não |
|
|
418
|
+
| **Usage** | Responde dúvidas sobre uso do sistema |
|
|
419
|
+
| **Onboarding** | Acolhe novos usuários e guia cadastro |
|
|
420
|
+
|
|
421
|
+
---
|
|
422
|
+
|
|
423
|
+
## 📝 Criando Agentes Individuais
|
|
424
|
+
|
|
425
|
+
```python
|
|
426
|
+
from atendentepro import (
|
|
427
|
+
create_triage_agent,
|
|
428
|
+
create_flow_agent,
|
|
429
|
+
create_interview_agent,
|
|
430
|
+
)
|
|
431
|
+
|
|
432
|
+
# Criar agente de triagem customizado
|
|
433
|
+
triage = create_triage_agent(
|
|
434
|
+
keywords_text="- vendas: 'preço', 'comprar'\n- suporte: 'problema', 'erro'",
|
|
435
|
+
)
|
|
436
|
+
|
|
437
|
+
# Criar agente de fluxo com tópicos específicos
|
|
438
|
+
flow = create_flow_agent(
|
|
439
|
+
flow_template="1. Vendas\n2. Suporte\n3. Dúvidas",
|
|
440
|
+
flow_keywords="- Vendas: 'preço'\n- Suporte: 'erro'",
|
|
441
|
+
)
|
|
442
|
+
|
|
443
|
+
# Configurar handoffs
|
|
444
|
+
triage.handoffs = [flow]
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
---
|
|
448
|
+
|
|
449
|
+
## 🛠️ Criando Seu Próprio Client Template
|
|
450
|
+
|
|
451
|
+
### Passo 1: Criar a Pasta do Cliente
|
|
452
|
+
|
|
453
|
+
```bash
|
|
454
|
+
mkdir -p client_templates/meu_cliente
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
### Passo 2: Criar os Arquivos de Configuração YAML
|
|
458
|
+
|
|
459
|
+
Copie do `standard/` e customize:
|
|
460
|
+
|
|
461
|
+
```bash
|
|
462
|
+
cp client_templates/standard/*.yaml client_templates/meu_cliente/
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### Passo 3: Configurar o Triage (triage_config.yaml)
|
|
466
|
+
|
|
467
|
+
Define as palavras-chave para identificar a intenção do usuário:
|
|
468
|
+
|
|
469
|
+
```yaml
|
|
470
|
+
agent_name: "Triage Agent"
|
|
471
|
+
|
|
472
|
+
keywords:
|
|
473
|
+
- agent: "Flow Agent"
|
|
474
|
+
keywords:
|
|
475
|
+
- "produto"
|
|
476
|
+
- "serviço"
|
|
477
|
+
- "preço"
|
|
478
|
+
|
|
479
|
+
- agent: "Knowledge Agent"
|
|
480
|
+
keywords:
|
|
481
|
+
- "documentação"
|
|
482
|
+
- "manual"
|
|
483
|
+
|
|
484
|
+
- agent: "Usage Agent"
|
|
485
|
+
keywords:
|
|
486
|
+
- "como usar"
|
|
487
|
+
- "ajuda"
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
### Passo 4: Configurar o Flow (flow_config.yaml)
|
|
491
|
+
|
|
492
|
+
Define os tópicos/opções que o usuário pode escolher:
|
|
493
|
+
|
|
494
|
+
```yaml
|
|
495
|
+
agent_name: "Flow Agent"
|
|
496
|
+
|
|
497
|
+
topics:
|
|
498
|
+
- id: 1
|
|
499
|
+
label: "Vendas"
|
|
500
|
+
keywords:
|
|
501
|
+
- "preço"
|
|
502
|
+
- "comprar"
|
|
503
|
+
|
|
504
|
+
- id: 2
|
|
505
|
+
label: "Suporte Técnico"
|
|
506
|
+
keywords:
|
|
507
|
+
- "erro"
|
|
508
|
+
- "problema"
|
|
509
|
+
|
|
510
|
+
- id: 3
|
|
511
|
+
label: "Financeiro"
|
|
512
|
+
keywords:
|
|
513
|
+
- "pagamento"
|
|
514
|
+
- "fatura"
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
### Passo 5: Configurar o Interview (interview_config.yaml)
|
|
518
|
+
|
|
519
|
+
Define as perguntas para coletar informações:
|
|
520
|
+
|
|
521
|
+
```yaml
|
|
522
|
+
agent_name: "Interview Agent"
|
|
523
|
+
|
|
524
|
+
questions:
|
|
525
|
+
Vendas:
|
|
526
|
+
- "Qual produto você tem interesse?"
|
|
527
|
+
- "Qual a quantidade desejada?"
|
|
528
|
+
|
|
529
|
+
Suporte Técnico:
|
|
530
|
+
- "Qual o erro que está aparecendo?"
|
|
531
|
+
- "Em qual dispositivo ocorre o problema?"
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
### Passo 6: Configurar Guardrails (guardrails_config.yaml)
|
|
535
|
+
|
|
536
|
+
Define limites de escopo para cada agente:
|
|
537
|
+
|
|
538
|
+
```yaml
|
|
539
|
+
global:
|
|
540
|
+
out_of_scope_message: "Desculpe, não posso ajudar com isso."
|
|
541
|
+
|
|
542
|
+
agents:
|
|
543
|
+
Triage Agent:
|
|
544
|
+
scope:
|
|
545
|
+
- "vendas"
|
|
546
|
+
- "suporte"
|
|
547
|
+
forbidden:
|
|
548
|
+
- "política"
|
|
549
|
+
- "religião"
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
### Passo 7: Configurar Knowledge (Opcional)
|
|
553
|
+
|
|
554
|
+
O Knowledge Agent suporta **múltiplas fontes de dados**:
|
|
555
|
+
- 📄 **Documentos** - RAG com embeddings (PDF, TXT, MD)
|
|
556
|
+
- 📊 **Dados Estruturados** - CSV, banco de dados, APIs
|
|
557
|
+
|
|
558
|
+
#### Apenas Documentos (RAG)
|
|
559
|
+
|
|
560
|
+
```yaml
|
|
561
|
+
agent_name: "Knowledge Agent"
|
|
562
|
+
|
|
563
|
+
about: "Base de conhecimento"
|
|
564
|
+
|
|
565
|
+
embeddings_path: "knowledge_documentos/embedding/embeddings.pkl"
|
|
566
|
+
|
|
567
|
+
documents:
|
|
568
|
+
- name: "Manual"
|
|
569
|
+
path: "docs/manual.pdf"
|
|
570
|
+
- name: "FAQ"
|
|
571
|
+
path: "docs/faq.md"
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
#### Apenas Dados Estruturados
|
|
575
|
+
|
|
576
|
+
```yaml
|
|
577
|
+
agent_name: "Knowledge Agent"
|
|
578
|
+
|
|
579
|
+
about: "Consulta de dados"
|
|
580
|
+
|
|
581
|
+
data_sources:
|
|
582
|
+
- type: "csv"
|
|
583
|
+
path: "data/produtos.csv"
|
|
584
|
+
columns:
|
|
585
|
+
- name: "codigo"
|
|
586
|
+
description: "Código do produto"
|
|
587
|
+
- name: "nome"
|
|
588
|
+
description: "Nome do produto"
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
#### Ambos (Documentos + Dados)
|
|
592
|
+
|
|
593
|
+
```yaml
|
|
594
|
+
agent_name: "Knowledge Agent"
|
|
595
|
+
|
|
596
|
+
about: "Base de conhecimento e dados"
|
|
597
|
+
|
|
598
|
+
# Documentos
|
|
599
|
+
embeddings_path: "knowledge_documentos/embedding/embeddings.pkl"
|
|
600
|
+
documents:
|
|
601
|
+
- name: "Manual"
|
|
602
|
+
path: "docs/manual.pdf"
|
|
603
|
+
|
|
604
|
+
# Dados estruturados
|
|
605
|
+
data_sources:
|
|
606
|
+
- type: "csv"
|
|
607
|
+
path: "data/produtos.csv"
|
|
608
|
+
columns:
|
|
609
|
+
- name: "codigo"
|
|
610
|
+
description: "Código do produto"
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
### Passo 8: Criar Tools Customizadas (Opcional)
|
|
614
|
+
|
|
615
|
+
Se precisar de consultas a dados estruturados:
|
|
616
|
+
|
|
617
|
+
```python
|
|
618
|
+
# client_templates/meu_cliente/tools.py
|
|
619
|
+
from agents import function_tool
|
|
620
|
+
import csv
|
|
621
|
+
from pathlib import Path
|
|
622
|
+
|
|
623
|
+
@function_tool
|
|
624
|
+
def buscar_produto(codigo: str = "", nome: str = "") -> str:
|
|
625
|
+
"""Busca produto na base de dados."""
|
|
626
|
+
csv_path = Path(__file__).parent / "data" / "produtos.csv"
|
|
627
|
+
|
|
628
|
+
resultados = []
|
|
629
|
+
with open(csv_path, "r", encoding="utf-8") as f:
|
|
630
|
+
reader = csv.DictReader(f)
|
|
631
|
+
for row in reader:
|
|
632
|
+
if codigo and row.get("codigo") == codigo:
|
|
633
|
+
resultados.append(row)
|
|
634
|
+
elif nome and nome.lower() in row.get("nome", "").lower():
|
|
635
|
+
resultados.append(row)
|
|
636
|
+
|
|
637
|
+
if not resultados:
|
|
638
|
+
return "Nenhum produto encontrado."
|
|
639
|
+
|
|
640
|
+
return "\n".join([f"- {r['nome']} (Cód: {r['codigo']})" for r in resultados])
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
### Passo 9: Criar Rede Específica (Opcional)
|
|
644
|
+
|
|
645
|
+
Se precisar de lógica customizada:
|
|
646
|
+
|
|
647
|
+
```python
|
|
648
|
+
# client_templates/meu_cliente/network.py
|
|
649
|
+
from pathlib import Path
|
|
650
|
+
from atendentepro import AgentNetwork, create_standard_network
|
|
651
|
+
|
|
652
|
+
from .tools import buscar_produto
|
|
653
|
+
|
|
654
|
+
def create_meu_cliente_network(templates_root: Path) -> AgentNetwork:
|
|
655
|
+
"""Rede específica para Meu Cliente."""
|
|
656
|
+
|
|
657
|
+
return create_standard_network(
|
|
658
|
+
templates_root=templates_root,
|
|
659
|
+
client="meu_cliente",
|
|
660
|
+
custom_tools={
|
|
661
|
+
"knowledge": [buscar_produto],
|
|
662
|
+
},
|
|
663
|
+
)
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
```python
|
|
667
|
+
# client_templates/meu_cliente/__init__.py
|
|
668
|
+
from .network import create_meu_cliente_network
|
|
669
|
+
__all__ = ["create_meu_cliente_network"]
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
### Passo 10: Usar o Template
|
|
673
|
+
|
|
674
|
+
**Opção A - Rede Padrão:**
|
|
675
|
+
|
|
676
|
+
```python
|
|
677
|
+
from pathlib import Path
|
|
678
|
+
from atendentepro import create_standard_network
|
|
679
|
+
|
|
680
|
+
network = create_standard_network(
|
|
681
|
+
templates_root=Path("./client_templates"),
|
|
682
|
+
client="meu_cliente"
|
|
683
|
+
)
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
**Opção B - Rede Customizada (handoffs diferentes):**
|
|
687
|
+
|
|
688
|
+
```python
|
|
689
|
+
from atendentepro import create_custom_network
|
|
690
|
+
|
|
691
|
+
network = create_custom_network(
|
|
692
|
+
templates_root=Path("./client_templates"),
|
|
693
|
+
client="meu_cliente",
|
|
694
|
+
network_config={
|
|
695
|
+
"triage": ["flow", "knowledge"],
|
|
696
|
+
"flow": ["interview"],
|
|
697
|
+
"interview": ["answer"],
|
|
698
|
+
"answer": ["triage"],
|
|
699
|
+
},
|
|
700
|
+
)
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
**Opção C - Rede Específica do Cliente:**
|
|
704
|
+
|
|
705
|
+
```python
|
|
706
|
+
import sys
|
|
707
|
+
from pathlib import Path
|
|
708
|
+
|
|
709
|
+
sys.path.insert(0, str(Path("./client_templates")))
|
|
710
|
+
|
|
711
|
+
from meu_cliente import create_meu_cliente_network
|
|
712
|
+
|
|
713
|
+
network = create_meu_cliente_network(
|
|
714
|
+
templates_root=Path("./client_templates")
|
|
715
|
+
)
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
### Estrutura Final do Template
|
|
719
|
+
|
|
720
|
+
```
|
|
721
|
+
client_templates/meu_cliente/
|
|
722
|
+
├── __init__.py # (Opcional) Pacote Python
|
|
723
|
+
├── network.py # (Opcional) Rede específica
|
|
724
|
+
├── tools.py # (Opcional) Tools customizadas
|
|
725
|
+
├── triage_config.yaml # ✅ Obrigatório
|
|
726
|
+
├── flow_config.yaml # ✅ Recomendado
|
|
727
|
+
├── interview_config.yaml # ✅ Recomendado
|
|
728
|
+
├── answer_config.yaml # Opcional
|
|
729
|
+
├── knowledge_config.yaml # Opcional
|
|
730
|
+
├── confirmation_config.yaml # Opcional
|
|
731
|
+
├── onboarding_config.yaml # Opcional
|
|
732
|
+
├── guardrails_config.yaml # ✅ Recomendado
|
|
733
|
+
├── data/ # Opcional (dados estruturados)
|
|
734
|
+
│ └── produtos.csv
|
|
735
|
+
└── knowledge_documentos/ # Opcional (RAG)
|
|
736
|
+
├── docs/
|
|
737
|
+
│ └── manual.pdf
|
|
738
|
+
└── embedding/
|
|
739
|
+
└── embeddings.pkl
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
---
|
|
743
|
+
|
|
744
|
+
## 🌐 Redes Pré-configuradas
|
|
745
|
+
|
|
746
|
+
### Rede Standard
|
|
747
|
+
|
|
748
|
+
```python
|
|
749
|
+
from atendentepro import create_standard_network
|
|
750
|
+
|
|
751
|
+
network = create_standard_network(
|
|
752
|
+
templates_root=Path("./client_templates"),
|
|
753
|
+
client="meu_cliente"
|
|
754
|
+
)
|
|
755
|
+
```
|
|
756
|
+
|
|
757
|
+
Configuração padrão de handoffs:
|
|
758
|
+
- Triage → Flow, Confirmation, Knowledge, Usage
|
|
759
|
+
- Flow → Interview, Triage
|
|
760
|
+
- Interview → Answer
|
|
761
|
+
- Answer → Triage, Interview
|
|
762
|
+
- Confirmation → Triage
|
|
763
|
+
- Knowledge → Triage
|
|
764
|
+
- Usage → Triage
|
|
765
|
+
|
|
766
|
+
### Rede Customizada
|
|
767
|
+
|
|
768
|
+
```python
|
|
769
|
+
from atendentepro import create_custom_network
|
|
770
|
+
|
|
771
|
+
network = create_custom_network(
|
|
772
|
+
templates_root=Path("./client_templates"),
|
|
773
|
+
client="meu_cliente",
|
|
774
|
+
network_config={
|
|
775
|
+
"triage": ["flow", "knowledge"],
|
|
776
|
+
"flow": ["interview"],
|
|
777
|
+
"interview": ["answer"],
|
|
778
|
+
"answer": ["triage"],
|
|
779
|
+
},
|
|
780
|
+
)
|
|
781
|
+
```
|
|
782
|
+
|
|
783
|
+
---
|
|
784
|
+
|
|
785
|
+
## 📚 Exemplo Completo
|
|
786
|
+
|
|
787
|
+
```python
|
|
788
|
+
import asyncio
|
|
789
|
+
from pathlib import Path
|
|
790
|
+
from atendentepro import create_standard_network
|
|
791
|
+
from agents import Runner
|
|
792
|
+
|
|
793
|
+
async def main():
|
|
794
|
+
# 1. Criar rede de agentes
|
|
795
|
+
network = create_standard_network(
|
|
796
|
+
templates_root=Path("./client_templates"),
|
|
797
|
+
client="meu_cliente"
|
|
798
|
+
)
|
|
799
|
+
|
|
800
|
+
# 2. Conversa interativa
|
|
801
|
+
messages = []
|
|
802
|
+
|
|
803
|
+
while True:
|
|
804
|
+
user_input = input("Você: ")
|
|
805
|
+
if user_input.lower() == "sair":
|
|
806
|
+
break
|
|
807
|
+
|
|
808
|
+
messages.append({"role": "user", "content": user_input})
|
|
809
|
+
|
|
810
|
+
result = await Runner.run(network.triage, messages)
|
|
811
|
+
|
|
812
|
+
print(f"Assistente: {result.final_output}")
|
|
813
|
+
messages.append({"role": "assistant", "content": str(result.final_output)})
|
|
814
|
+
|
|
815
|
+
if __name__ == "__main__":
|
|
816
|
+
asyncio.run(main())
|
|
817
|
+
```
|
|
818
|
+
|
|
819
|
+
---
|
|
820
|
+
|
|
821
|
+
## 🔒 Guardrails (Validação de Escopo)
|
|
822
|
+
|
|
823
|
+
```python
|
|
824
|
+
from atendentepro import get_guardrails_for_agent, set_guardrails_client
|
|
825
|
+
from pathlib import Path
|
|
826
|
+
|
|
827
|
+
# Configurar guardrails para um cliente
|
|
828
|
+
set_guardrails_client(
|
|
829
|
+
client_key="meu_cliente",
|
|
830
|
+
templates_root=Path("./client_templates")
|
|
831
|
+
)
|
|
832
|
+
|
|
833
|
+
# Obter guardrails para um agente
|
|
834
|
+
guardrails = get_guardrails_for_agent("Triage Agent")
|
|
835
|
+
```
|
|
836
|
+
|
|
837
|
+
---
|
|
838
|
+
|
|
839
|
+
## 🔗 Dependências
|
|
840
|
+
|
|
841
|
+
- `openai-agents>=0.3.3` - OpenAI Agents SDK
|
|
842
|
+
- `openai>=1.107.1` - OpenAI Python SDK
|
|
843
|
+
- `pydantic>=2.0.0` - Validação de dados
|
|
844
|
+
- `PyYAML>=6.0` - Configurações YAML
|
|
845
|
+
- `python-dotenv>=1.0.0` - Variáveis de ambiente
|
|
846
|
+
- `numpy>=1.24.0` - Operações vetoriais (RAG)
|
|
847
|
+
- `scikit-learn>=1.3.0` - Similaridade coseno (RAG)
|
|
848
|
+
|
|
849
|
+
---
|
|
850
|
+
|
|
851
|
+
## 📁 Estrutura do Projeto
|
|
852
|
+
|
|
853
|
+
```
|
|
854
|
+
monkai_atendentepro/
|
|
855
|
+
├── atendentepro/ # Biblioteca principal (genérica)
|
|
856
|
+
│ ├── __init__.py
|
|
857
|
+
│ ├── agents/
|
|
858
|
+
│ ├── config/
|
|
859
|
+
│ ├── guardrails/
|
|
860
|
+
│ ├── models/
|
|
861
|
+
│ ├── prompts/
|
|
862
|
+
│ ├── templates/
|
|
863
|
+
│ ├── utils/
|
|
864
|
+
│ ├── network.py
|
|
865
|
+
│ └── README.md
|
|
866
|
+
├── client_templates/ # Templates de clientes (específicos)
|
|
867
|
+
│ ├── standard/ # Template base
|
|
868
|
+
│ └── meu_cliente/ # Templates customizados
|
|
869
|
+
├── examples/ # Exemplos de uso
|
|
870
|
+
├── venv/ # Ambiente virtual
|
|
871
|
+
├── pyproject.toml
|
|
872
|
+
├── requirements.txt
|
|
873
|
+
└── setup.py
|
|
874
|
+
```
|
|
875
|
+
|
|
876
|
+
---
|
|
877
|
+
|
|
878
|
+
## 📄 Licença
|
|
879
|
+
|
|
880
|
+
MIT License - BeMonkAI
|
|
881
|
+
|
|
882
|
+
---
|
|
883
|
+
|
|
884
|
+
## 🤝 Contribuindo
|
|
885
|
+
|
|
886
|
+
1. Fork o repositório
|
|
887
|
+
2. Crie sua branch (`git checkout -b feature/nova-feature`)
|
|
888
|
+
3. Commit suas mudanças (`git commit -m 'Adiciona nova feature'`)
|
|
889
|
+
4. Push para a branch (`git push origin feature/nova-feature`)
|
|
890
|
+
5. Abra um Pull Request
|