Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/geremyjampiersalasgarcia-eng/Caso_Practico_Semillero_IA/llms.txt

Use this file to discover all available pages before exploring further.

Mesa de Ayuda IA is structured as a layered, production-style system. A request originates in the browser, travels to the Next.js frontend, crosses to the FastAPI backend over a single HTTP endpoint (POST /api/v1/chat), and enters a LangGraph StateGraph orchestrator that classifies intent, routes the query to one or more specialized agents, and consolidates their responses before returning a structured JSON reply. All persistent state lives in two complementary stores: ChromaDB holds the vectorized knowledge bases used for semantic retrieval, while PostgreSQL records conversation history, CRM opportunities, and audit telemetry.

High-level flow

The following diagram shows the complete data path from browser to response:
Browser ──► Web UI (Next.js)  │  TypeScript + Tailwind + Shadcn


         HTTP (POST /api/v1/chat)


┌───────────────────────────────────────────────────────────────┐
│  FastAPI  (app.main)                                          │
│                                                               │
│  ┌─────────────────────────────────────────────────────────┐  │
│  │  LangGraph StateGraph (orchestrator.py)                 │  │
│  │                                                         │  │
│  │  START                                                  │  │
│  │   └► classify (Gemini, temp=0)                          │  │
│  │       ├► catalogo_precios   → Agente Catálogo      ──┐  │  │
│  │       ├► politicas_comerc   → Agente Políticas     ──┤  │  │
│  │       ├► proceso_ventas     → Agente Proc. Ventas  ──┤  │  │
│  │       ├► multimodal         → Agente Imagen        ──┤  │  │
│  │       ├► accion_registro    → Agente Acción        ──┤  │  │
│  │       └► mixta              → 3 agentes RAG        ──┤  │  │
│  │                                                      │  │  │
│  │                                    consolidate ◄─────┘  │  │
│  │                                        │                │  │
│  │                                       END               │  │
│  └─────────────────────────────────────────────────────────┘  │
│                                                               │
│  ChromaDB (3 colecciones: col_catalogo, col_politicas,        │
│            col_proceso_ventas)                                │
│  PostgreSQL (historial + auditoría)                           │
└───────────────────────────────────────────────────────────────┘

Request lifecycle

Each query passes through the following ten inference steps:
  1. User submits a question (optionally with an attached image) via the Next.js frontend.
  2. The frontend sends an HTTP POST to /api/v1/chat with the question, an optional Base64-encoded image, and an optional confirmation flag (used by the Action Agent for multi-turn registration flows).
  3. FastAPI validates the request payload (input length, regex pattern check, JSON format) before the message reaches the orchestrator.
  4. The classifier node — a Gemini LLM call at temperature 0.0 for full determinism — reads the question and assigns one of six intent labels: catalogo_precios, politicas_comerciales, proceso_ventas, multimodal, accion_registro, or mixta.
  5. A conditional router in the LangGraph graph reads the intent label and directs execution to one or more agent nodes. If an image was attached, the router overrides the label and always routes to the multimodal agent.
  6. One or more specialized agents are invoked. For mixta queries, the Catalog, Policies, and Sales Process agents run to cover all knowledge domains.
  7. Each RAG agent queries its ChromaDB collection using cosine-similarity search (top-k = 4 fragments), constructs a prompt from the retrieved context and the user question, and calls Gemini at temperature 0.1 to generate a grounded, source-cited response.
  8. The Action Agent uses LangChain Function Calling (@tool decorator + bind_tools()) to invoke registrar_oportunidad_crm when all required CRM fields are present and the user has confirmed.
  9. The consolidate node integrates partial responses from all invoked agents into a single, coherent final answer.
  10. FastAPI returns a JSON response containing the final answer, the list of agents invoked, the source documents referenced, and any warnings (for example, if a discount exceeds the auto-approval threshold).

Security guardrails

The system enforces security at four independent layers, so a breach of one layer does not compromise the others.

Layer 1 — FastAPI input validation

The first gate is a FastAPI dependency (validar_input) injected on the /api/v1/chat endpoint. It enforces a 2,000-character length limit on the user question and scans it against a set of regex patterns for known malicious phrases. Requests that exceed the length limit or match a prohibited pattern are rejected with HTTP 400 before they touch any AI component. Requests whose body does not conform to the Pydantic ChatRequest schema are automatically rejected with HTTP 422 by FastAPI’s built-in validation.

Layer 2 — Prompt hardening

Every agent receives an immutable system prompt loaded from a dedicated Markdown file in app/prompts/. These prompts contain strict role instructions that tell the LLM exactly who it is, what it may and may not do, and that it must ignore any user instruction that tries to change its behavior. Because the system prompt is injected programmatically rather than concatenated from user input, it cannot be overwritten by message content.

Layer 3 — Server-side sandboxing (security.py)

Before a message reaches the LangGraph orchestrator, it passes through app/core/security.py. This module applies regex pattern matching to detect common prompt-injection attack signatures, including:
  • Instructions to ignore or forget rules (ignora instrucciones, olvida instrucciones, ignora reglas, ignora prompt, olvida prompt)
  • Role-change and impersonation attempts (actúa como, compórtate como, ahora eres, modo desarrollador)
  • DAN-style jailbreaks (the literal token DAN)
  • Prompt extraction attempts (repite prompt, revela prompt, dime reglas, cuáles instrucciones, imprime prompt)
If any pattern matches, the module returns False and the service short-circuits the pipeline, returning a fixed corporate response — the malicious message never reaches the LLM.

Layer 4 — Output validation

After the consolidate node produces a final answer, a validation step checks the response for signs of hallucination — for example, a response that invents product names, prices, or policies not present in the retrieved documents. Responses that fail this check are replaced with a conservative fallback that informs the user the requested information was not found in official documents.
The four guardrail layers correspond to the Seguridad pillar of the E-O-C-S (Evaluación, Observabilidad, Costos, Seguridad) framework implemented throughout the system.

Data stores

ChromaDB — vector knowledge base

ChromaDB is used exclusively for the RAG pipeline. Three isolated collections are populated by running python scripts/ingest.py from the backend/ directory:
CollectionSource documentUsed by
col_catalogo01_Catalogo_Productos_Precios.txtCatalog Agent, Multimodal Agent
col_politicas02_Politicas_Comerciales_Descuentos_Credito.txtPolicies Agent
col_proceso_ventas03_Proceso_Ventas_CRM.txtSales Process Agent
Documents are chunked by RecursiveCharacterTextSplitter (chunk size 1,000 characters, overlap 200 characters) and embedded using GoogleGenerativeAIEmbeddings with the models/gemini-embedding-001 model. At query time, each agent performs a cosine-similarity search and retrieves the top 4 most relevant fragments (RETRIEVAL_TOP_K=4). ChromaDB persists its data to the local filesystem at backend/data/chroma_db/. No external vector database service is required.

PostgreSQL — relational persistence

PostgreSQL (running as a Docker container on port 5433) stores all non-vector application state. Tables are created automatically by SQLAlchemy on first backend startup:
TableDescription
conversationsChat sessions — IDs and auto-generated titles
messagesIndividual turns — question, response, RAG sources, Base64 image attachments
oportunidadesCRM opportunity records created by the Action Agent via Function Calling
audit_logsPer-request telemetry — detected intent, agents invoked, latency in milliseconds
SQLite fallback: If the PostgreSQL container is not running when the backend starts, SQLAlchemy automatically falls back to a local SQLite database. This ensures the backend starts and serves requests without manual intervention, at the cost of losing multi-process durability.

Technology decisions

The table below summarizes the key architectural choices and their rationale, drawn directly from the project design documentation:
ComponentChoiceReason
LanguagePython 3.11Industry standard for AI/NLP. Robust ecosystem with LangChain and Google AI.
Web frameworkFastAPI + UvicornStrict typing, automatic Swagger docs, high async throughput.
Agent frameworkLangChainStandard framework for agents, tools, and chains.
OrchestrationLangGraph (StateGraph)Models the agent workflow as an explicit directed graph with conditional routing — deterministic, loop-safe, and easy to extend with new nodes.
Vector storeChromaDB (local)Persistent, fast, no external services required. One collection per agent for knowledge isolation.
LLM & EmbeddingsGoogle Gemini via langchain-google-genaiChatGoogleGenerativeAI for agents, GoogleGenerativeAIEmbeddings for vectors. Native multimodal vision support.
VisionGemini Vision (multimodal)Native multimodal capability for product image analysis — no separate vision service needed.
DatabasePostgreSQL + DockerRobust conversation history and audit trail with volume-backed persistence.
FrontendNext.js 14 + Tailwind CSS + Shadcn UIModern, responsive chat interface with TypeScript type safety.
ObservabilityArize Phoenix + OpenTelemetryFull distributed traces across all LangGraph nodes, token consumption, and cost estimation per query.

Build docs developers (and LLMs) love