Skip to content

VT-IanCardenas/public-agentia-pnl-params

Repository files navigation

🧠 Query Params Agent API

Query Params Agent es una API basada en FastAPI que utiliza un modelo de lenguaje (LLM) para convertir instrucciones en lenguaje natural en parámetros de búsqueda (queryParams) para endpoints REST.
Este proyecto fue diseñado como una demostración práctica de cómo integrar agentes de IA en servicios backend, aplicando buenas prácticas de diseño, validación JWT y soporte multi-proveedor de modelos.


🚀 Finalidad del proyecto

En muchos sistemas, los usuarios o agentes deben construir filtros complejos (por ejemplo, ?status=APPROVED&createdAfter=2025-09-20T00:00:00).
Sin embargo, esto requiere conocer los nombres exactos de los parámetros y su formato.

Este servicio soluciona ese problema permitiendo consultas en lenguaje natural como:

“Muéstrame las propuestas aprobadas entre el 20 y el 22 de septiembre del 2025”

Y devuelve automáticamente:

?status=APPROVED&createdAfter=2025-09-20T00:00:00&createdBefore=2025-09-22T23:59:59

🧩 Cómo lo resuelve

  • Utiliza LangChain para orquestar un modelo conversacional (OpenAI, Anthropic u Ollama).
  • Aplica prompt engineering para guiar al modelo a generar únicamente cadenas válidas de queryParams.
  • Exponen un único endpoint /proposal/generate-query protegido con JWT, que convierte una instrucción en texto en una cadena de consulta.
  • Usa modelos Pydantic para validar la entrada y salida de forma tipada.

🧱 Arquitectura general

graph TD
A[Usuario / Frontend] -->|Texto natural| B[FastAPI /proposal/generate-query]
B -->|Prompt + Query| C[LangChain Model]
C -->|Output String| B
B -->|JSON Response| A
Loading

⚙️ Configuración del entorno

Clona el repositorio y crea un entorno virtual:

git clone https://github.com/VT-IanCardenas/public-agentia-pnl-params.git
cd public-agentia-pnl-params

rm -rf .venv 
python3 -m venv .venv
source .venv/bin/activate 

pip install -r requirements.txt

Archivo .env

Crea un archivo .env en la raíz del proyecto con tus variables de configuración:

# Proveedor del modelo (ollama, openai o anthropic)
CHAT_PROVIDER=ollama

# Modelo por defecto según proveedor
CHAT_MODEL=gemma:2b
TEMPERATURE_MODEL=0.5

# API key requerida si usas OpenAI o Anthropic
API_KEY_MODEL=

# Dirección del modelo (solo para Ollama)
CHAT_URL=http://localhost:11434

# Secreto compartido para validar JWT
JWT_SECRET=un_secreto_seguro

▶️ Ejecución del proyecto

🧱 Opción 1 — Docker con archivo .env

Primero construye la imagen Docker:

docker build -t query-params-agent:latest .

Luego ejecútala cargando automáticamente las variables de entorno desde el archivo .env:

docker run -d \
  --name query-agent \
  --env-file .env \
  -p 8000:8000 \
  query-params-agent:latest

👉 La API quedará disponible en:
http://localhost:8000/docs


⚙️ Opción 2 — Docker pasando variables manualmente

También puedes pasar las variables directamente con -e:

docker run -d \
  --name query-agent \
  -e CHAT_PROVIDER=openai \
  -e CHAT_MODEL=gpt-4o-mini \
  -e TEMPERATURE_MODEL=0.5 \
  -e API_KEY_MODEL=sk-proj-xxxxxxx \
  -e CHAT_URL=http://localhost:11434 \
  -e JWT_SECRET=un_secreto_seguro \
  -p 8000:8000 \
  query-params-agent:latest

⚡ Opción 3 — Ejecución local (sin Docker)

uvicorn app:app --reload --port 8000

🔒 Autenticación JWT

Este servicio requiere un token JWT firmado con el mismo secreto (JWT_SECRET).

Ejemplo en Python para generar un token válido:

import jwt, time

payload = {
    "sub": "test-user",
    "email": "test@example.com",
    "roles": ["admin"],
    "iat": int(time.time()),
    "exp": int(time.time()) + 3600,
}

token = jwt.encode(payload, "un_secreto_seguro", algorithm="HS256")
print(token)

🧠 Ejemplo de uso con cURL

curl --location 'http://localhost:8000/proposal/generate-query' --header 'Content-Type: application/json' --header 'Authorization: Bearer <TU_TOKEN_JWT>' --data '{
    "pnl_query": "Filtrar las propuestas con mínimo 6 líneas creadas desde el 20 de septiembre de este año"
}'

Respuesta:

{
  "query_params": "?minLines=6&status=CREATED&createdAfter=2025-09-20T00:00:00"
}

🧪 Pruebas rápidas

Puedes probar la API directamente desde Swagger UI:

http://localhost:8000/docs

O mediante HTTPie:

http POST http://localhost:8000/proposal/generate-query   Authorization:"Bearer <TU_TOKEN_JWT>"   pnl_query="Muéstrame las propuestas aprobadas entre el 1 y el 5 de octubre"

🔧 Estructura del proyecto

.
├── app.py                      # Punto de entrada FastAPI
├── auth_jwt.py                 # Validación de tokens JWT HS256
├── chat_model.py               # Carga dinámica del modelo según proveedor
├── schemas.py                  # Modelos Pydantic de entrada/salida
├── config.py                   # Variables de configuración y entorno
├── services/
│   ├── query-params-agent.py   # Lógica del agente y generación de queryParams
└── requirements.txt

🧩 Ejemplo de resultados esperados

Instrucción natural Respuesta del agente
“Quiero todas las propuestas rechazadas con al menos 3 líneas” ?minLines=3&status=REJECTED
“Filtra las propuestas creadas entre el 10 y el 12 de septiembre” ?status=CREATED&createdAfter=2025-09-10T00:00:00&createdBefore=2025-09-12T23:59:59

🪵 Logging estructurado y contextual

El proyecto utiliza un sistema de logging estructurado, diseñado para ser seguro, consistente y fácil de extender en otros módulos.
El formato puede configurarse tanto en texto plano (con campos extra) como en JSON, dependiendo del entorno o el destino.

Características principales

  • Registro estructurado con timestamp, nivel, logger, mensaje y campos contextuales dinámicos (input_query, query_params, tokens_used).
  • Filtrado automático: los logs internos de uvicorn o librerías externas no muestran extras, solo los del código del proyecto.
  • Compatible con rotación diaria de archivos (TimedRotatingFileHandler) en el directorio logs/.
  • Configurable mediante variables de entorno:
    • LOG_DIR: ruta donde se almacenan los logs (por defecto logs/).
    • LOG_LEVEL: nivel de detalle (INFO, DEBUG, WARNING, etc.).

Ejemplo de salida (modo texto plano)

2025-10-26 19:40:10 [INFO] services.query_params_agent: LLM query successfully processed | extras: tokens_used=235

Extensión en otros módulos

Para registrar eventos desde cualquier servicio:

import logging
logger = logging.getLogger(__name__)

logger.info("Procesando solicitud", extra={"input_query": "texto del usuario"})

El formateador detectará automáticamente los extra sin requerir configuración adicional.


🧰 Tecnologías utilizadas

  • FastAPI – Framework web rápido y moderno.
  • LangChain – Orquestación de agentes LLM.
  • Pydantic – Validación de modelos.
  • JWT HS256 – Autenticación segura.
  • Uvicorn – Servidor ASGI.
  • Ollama / OpenAI / Anthropic – Modelos conversacionales intercambiables.
  • Docker – Empaquetado reproducible para despliegue.

About

API FastAPI + LangChain que convierte lenguaje natural en query params REST

Topics

Resources

License

Stars

Watchers

Forks

Contributors