feat: Add docs
This commit is contained in:
345
docs/QUICK_START.py
Normal file
345
docs/QUICK_START.py
Normal file
@@ -0,0 +1,345 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
QUICK START: Cómo crear tu primera herramienta en 5 minutos
|
||||
|
||||
Este archivo es un tutorial paso a paso que puedes ejecutar.
|
||||
"""
|
||||
|
||||
# ============================================================================
|
||||
# PASO 1: Entender la estructura
|
||||
# ============================================================================
|
||||
|
||||
"""
|
||||
El patrón Registry funciona así:
|
||||
|
||||
1. DEFINIR una herramienta (en tools.py):
|
||||
- Crear una clase que herede de BaseTool
|
||||
- Implementar: name, description, args_schema, invoke()
|
||||
|
||||
2. REGISTRAR la herramienta:
|
||||
- Crear ToolRegistry()
|
||||
- Llamar registry.register(MiHerramienta())
|
||||
|
||||
3. USAR las herramientas:
|
||||
- Pasar registry.get_all_tools_as_langchain() al Agent
|
||||
- El Agent ahora puede usar tus tools
|
||||
"""
|
||||
|
||||
# ============================================================================
|
||||
# PASO 2: Crear tu primera herramienta
|
||||
# ============================================================================
|
||||
|
||||
"""
|
||||
Abre: src/naliiabot/bot/tools/tools.py
|
||||
|
||||
Y pega este código (reemplaza el contenido):
|
||||
"""
|
||||
|
||||
EJEMPLO_HERRAMIENTA = '''
|
||||
"""
|
||||
Implementaciones concretas de herramientas del agente.
|
||||
"""
|
||||
|
||||
from typing import Any, Dict
|
||||
from .tool_registry import BaseTool
|
||||
|
||||
|
||||
class ObtenerHoraActualTool(BaseTool):
|
||||
"""
|
||||
Herramienta simple que retorna la hora actual.
|
||||
|
||||
El LLM puede usar esto para responder: "¿Qué hora es?"
|
||||
"""
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return "obtener_hora"
|
||||
|
||||
@property
|
||||
def description(self) -> str:
|
||||
return "Retorna la hora actual del sistema."
|
||||
|
||||
@property
|
||||
def args_schema(self) -> Dict[str, Any]:
|
||||
return {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"formato": {
|
||||
"type": "string",
|
||||
"enum": ["12h", "24h"],
|
||||
"description": "Formato de hora deseado",
|
||||
"default": "24h"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
}
|
||||
|
||||
def invoke(self, **kwargs) -> str:
|
||||
from datetime import datetime
|
||||
|
||||
formato = kwargs.get("formato", "24h")
|
||||
ahora = datetime.now()
|
||||
|
||||
if formato == "12h":
|
||||
return ahora.strftime("%I:%M %p")
|
||||
else:
|
||||
return ahora.strftime("%H:%M:%S")
|
||||
|
||||
|
||||
class SaludarTool(BaseTool):
|
||||
"""
|
||||
Herramienta para saludar al usuario.
|
||||
"""
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return "saludar"
|
||||
|
||||
@property
|
||||
def description(self) -> str:
|
||||
return "Saluda al usuario de forma amable."
|
||||
|
||||
@property
|
||||
def args_schema(self) -> Dict[str, Any]:
|
||||
return {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"nombre": {
|
||||
"type": "string",
|
||||
"description": "Nombre de la persona a saludar"
|
||||
}
|
||||
},
|
||||
"required": ["nombre"]
|
||||
}
|
||||
|
||||
def invoke(self, **kwargs) -> str:
|
||||
nombre = kwargs.get("nombre", "Usuario")
|
||||
return f"¡Hola {nombre}! 👋 Bienvenido a Naliia"
|
||||
'''
|
||||
|
||||
# ============================================================================
|
||||
# PASO 3: Usar tus herramientas
|
||||
# ============================================================================
|
||||
|
||||
"""
|
||||
En tu código principal (ejemplo en main.py):
|
||||
"""
|
||||
|
||||
EJEMPLO_USO = '''
|
||||
from src.naliiabot.bot.tools import ToolRegistry
|
||||
from src.naliiabot.bot.tools.tools import ObtenerHoraActualTool, SaludarTool
|
||||
from src.naliiabot.bot.agent.agent import Agent
|
||||
from langchain_anthropic import ChatAnthropic
|
||||
|
||||
# 1. Crear el modelo LLM
|
||||
modelo = ChatAnthropic(model="claude-3-5-sonnet-20241022")
|
||||
|
||||
# 2. Crear el registry de tools
|
||||
registry = ToolRegistry()
|
||||
|
||||
# 3. Registrar las herramientas
|
||||
registry.register(ObtenerHoraActualTool())
|
||||
registry.register(SaludarTool())
|
||||
|
||||
# 4. Crear el agente con las tools
|
||||
agent = Agent(
|
||||
model=modelo,
|
||||
tools=registry.get_all_tools_as_langchain()
|
||||
)
|
||||
|
||||
# 5. Usar el agente
|
||||
from langchain_core.messages import HumanMessage
|
||||
|
||||
resultado = agent.invoke({
|
||||
"messages": [
|
||||
HumanMessage(content="Hola, ¿qué hora es?")
|
||||
]
|
||||
})
|
||||
|
||||
print(resultado)
|
||||
'''
|
||||
|
||||
# ============================================================================
|
||||
# PASO 4: Verificar que funciona
|
||||
# ============================================================================
|
||||
|
||||
"""
|
||||
Ejecuta en la terminal:
|
||||
|
||||
cd /home/aserrador/Desktop/01-OneCluster/02-Desarrollo/03-Naliia/NaliiaBot
|
||||
python -m pytest tests/test_naliia_agent_tools.py -v
|
||||
|
||||
Deberías ver los tests pasando.
|
||||
"""
|
||||
|
||||
# ============================================================================
|
||||
# PASO 5: Crear herramientas más complejas
|
||||
# ============================================================================
|
||||
|
||||
"""
|
||||
Para herramientas con lógica real:
|
||||
|
||||
1. Conectar a base de datos:
|
||||
- Importa el cliente de tu BD
|
||||
- En invoke(), haz la consulta
|
||||
- Retorna el resultado como string
|
||||
|
||||
2. Manejar errores:
|
||||
- Try/except en invoke()
|
||||
- Retorna un mensaje de error claro
|
||||
|
||||
3. Validar argumentos:
|
||||
- Usa el args_schema para definir requerimientos
|
||||
- El LLM sabe qué argumentos necesita
|
||||
|
||||
Ejemplo con BD:
|
||||
"""
|
||||
|
||||
EJEMPLO_CON_BD = '''
|
||||
from typing import Any, Dict
|
||||
from .tool_registry import BaseTool
|
||||
from tu_modulo.database import get_db
|
||||
|
||||
class ObtenerClienteTool(BaseTool):
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return "obtener_cliente"
|
||||
|
||||
@property
|
||||
def description(self) -> str:
|
||||
return "Obtiene información de un cliente por ID"
|
||||
|
||||
@property
|
||||
def args_schema(self) -> Dict[str, Any]:
|
||||
return {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"cliente_id": {
|
||||
"type": "string",
|
||||
"description": "ID del cliente"
|
||||
}
|
||||
},
|
||||
"required": ["cliente_id"]
|
||||
}
|
||||
|
||||
def invoke(self, **kwargs) -> str:
|
||||
cliente_id = kwargs.get("cliente_id")
|
||||
|
||||
try:
|
||||
db = get_db()
|
||||
cliente = db.clientes.find_one({"_id": cliente_id})
|
||||
|
||||
if not cliente:
|
||||
return f"Cliente {cliente_id} no encontrado"
|
||||
|
||||
return f"Nombre: {cliente['nombre']}, Email: {cliente['email']}"
|
||||
|
||||
except Exception as e:
|
||||
return f"Error al obtener cliente: {str(e)}"
|
||||
'''
|
||||
|
||||
# ============================================================================
|
||||
# TIPS Y BUENAS PRÁCTICAS
|
||||
# ============================================================================
|
||||
|
||||
TIPS = """
|
||||
✅ BUENAS PRÁCTICAS:
|
||||
|
||||
1. **Nombres claros**: "obtener_agenda" mejor que "get_agenda_info"
|
||||
|
||||
2. **Descripciones detalladas**: El LLM las lee para decidir cuándo usar la tool
|
||||
|
||||
3. **Args schema completo**:
|
||||
- Describe qué es cada parámetro
|
||||
- Especifica si es requerido
|
||||
- Usa enum para valores limitados
|
||||
- Añade ejemplos en description
|
||||
|
||||
4. **Manejo de errores**: Siempre captura excepciones en invoke()
|
||||
|
||||
5. **Retorna strings**: invoke() debe retornar texto plano, no objetos
|
||||
|
||||
6. **Validación**: Valida argumentos en invoke() antes de usarlos
|
||||
|
||||
7. **Logging**: Usa logging para debugging en producción
|
||||
|
||||
8. **Tests**: Crea tests unitarios para cada tool
|
||||
|
||||
❌ ERRORES COMUNES:
|
||||
|
||||
- No retornar string desde invoke()
|
||||
- Olvidar el args_schema completo
|
||||
- No manejar excepciones
|
||||
- Nombres de tools con espacios o caracteres especiales
|
||||
- Tools que hacen demasiadas cosas (una responsabilidad)
|
||||
|
||||
🔍 DEBUGGING:
|
||||
|
||||
# Ver todas las tools registradas
|
||||
print(registry.list_tool_names())
|
||||
|
||||
# Ver schema de una tool
|
||||
herramienta = registry.get_tool("mi_herramienta")
|
||||
print(herramienta.args_schema)
|
||||
|
||||
# Ver descripción
|
||||
print(registry.get_tool_description("mi_herramienta"))
|
||||
"""
|
||||
|
||||
# ============================================================================
|
||||
# ESTRUCTURA FINAL
|
||||
# ============================================================================
|
||||
|
||||
ESTRUCTURA = """
|
||||
Después de seguir estos pasos, tu proyecto tendrá:
|
||||
|
||||
src/naliiabot/bot/tools/
|
||||
├── __init__.py
|
||||
│ └── Exporta: ToolRegistry, BaseTool
|
||||
├── tool_registry.py
|
||||
│ └── Contiene: BaseTool (clase abstracta), ToolRegistry (registro)
|
||||
└── tools.py
|
||||
└── TUS herramientas (ObtenerHoraActualTool, SaludarTool, etc.)
|
||||
|
||||
tests/
|
||||
└── test_naliia_agent_tools.py
|
||||
└── Tests para las tools (ya creado)
|
||||
|
||||
src/naliiabotapi/
|
||||
└── main.py
|
||||
└── Crea el registry, inicializa el agent, lanza el API
|
||||
|
||||
DOCUMENTACIÓN:
|
||||
├── TOOLS_GUIDE.md ← Lee primero
|
||||
├── AGENDA_TOOLS_EXAMPLE.py ← Ejemplos reales
|
||||
├── REGISTRY_IMPLEMENTATION_SUMMARY.md ← Resumen
|
||||
├── CHANGES_SUMMARY.md ← Qué cambió
|
||||
└── QUICK_START.md (este archivo) ← Tutorial
|
||||
"""
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("=" * 80)
|
||||
print("QUICK START: Patrón Registry para Tools en NaliiaBot")
|
||||
print("=" * 80)
|
||||
print("\n📖 PASOS:")
|
||||
print("\n1️⃣ CREA tu primera herramienta")
|
||||
print(" → Abre: src/naliiabot/bot/tools/tools.py")
|
||||
print(" → Pega el código de EJEMPLO_HERRAMIENTA\n")
|
||||
|
||||
print("2️⃣ REGISTRA la herramienta")
|
||||
print(" → Crea ToolRegistry()")
|
||||
print(" → Llama registry.register(MiHerramienta())\n")
|
||||
|
||||
print("3️⃣ USA con el Agent")
|
||||
print(" → Pasa registry.get_all_tools_as_langchain() a Agent\n")
|
||||
|
||||
print("4️⃣ TESTA tus tools")
|
||||
print(" → python -m pytest tests/test_naliia_agent_tools.py -v\n")
|
||||
|
||||
print("5️⃣ LEE la documentación")
|
||||
print(" → TOOLS_GUIDE.md - Guía completa")
|
||||
print(" → AGENDA_TOOLS_EXAMPLE.py - Ejemplos reales\n")
|
||||
|
||||
print("=" * 80)
|
||||
print("¡Listo! Ya tienes todo lo que necesitas para empezar 🚀")
|
||||
print("=" * 80)
|
||||
Reference in New Issue
Block a user