Inicio / Artículos / Dividir un agente de soporte en nodos de intake, knowledge y support

Dividir un agente de soporte en nodos de intake, knowledge y support

Por qué el agente de soporte de LEPA es un grafo de especialistas y no una gran función, cómo LangGraph conecta los relevos mediante un estado compartido y qué significa aquí multiagente.

792 palabras

A estas alturas el agente de soporte de LEPA ya sabe enrutar una solicitud, buscar en la documentación y recordar el hilo de una conversación. Lo que queda por ver es cómo se organiza el trabajo en sí. En lugar de una función gigante que lo hace todo, las responsabilidades se reparten entre unos pocos especialistas y LangGraph los coordina.

Piense en la construcción de una casa

"Multiagente" puede sonar a ciencia ficción. Una imagen más útil es la de una obra en la que varios gremios trabajan en el mismo proyecto:

Electrician
Plumber
Painter
Inspector

Tareas distintas, habilidades distintas, una sola casa. Un flujo de soporte se puede dividir de la misma manera:

Someone understands the request
Someone finds the handbook page
Someone writes the reply

Esa división solo tiene sentido cuando las tareas son realmente distintas. Añadir cajas a un diagrama de una presentación no cuenta.

El grafo de este proyecto

El grafo compilado funciona así:

START
  → intake
  → classify
  → conditional
        ├─ ask_clarification → END
        └─ knowledge → support → END

En la estructura del proyecto, intake, knowledge y support se llaman agentes porque cada uno tiene una tarea clara. Classify y el paso de pedir aclaraciones están en una carpeta nodes/, que es la misma idea de grafo con otra forma de nombrar las carpetas. Aquí "multiagente" significa nodos especializados dentro de un único StateGraph compilado. No significa servicios desplegados por separado ni agentes que discuten entre sí. Los nombres de las carpetas importan menos que la separación de responsabilidades.

Qué hace cada especialista

Intake

Intake toma el último mensaje del usuario y produce un user_role:

"I'm a teacher — how do I take attendance?"
        ↓
user_role = teacher

No busca en la documentación ni escribe la respuesta final. Lo único que hace es preparar el contexto para el enrutamiento.

Classify y la rama de aclaración

Classify decide el tema y si se sabe lo suficiente para continuar:

"help" → ask for the LEPA area
"How do I enter grades?" → continue to knowledge

Esa rama es la orquestación: el mismo sistema, pero con un especialista distinto a continuación.

Knowledge

Knowledge nunca conversa con el usuario. Solo recupera documentos:

query + issue_category
        ↓
search_knowledge_impl  (keyword Markdown search)
        ↓
retrieved_documents

En el mismo módulo hay un envoltorio @tool llamado search_knowledge para experimentos futuros, pero el grafo llama directamente a la implementación de fondo.

Support

Support nunca recorre el sistema de archivos. Lee retrieved_documents y genera final_answer, a partir de una plantilla por defecto y, si hay un LLM configurado, pulida por él de forma opcional.

Cómo LangGraph mantiene el orden

Ningún LLM gestor decide libremente quién habla después. Las conexiones son explícitas:

graph.add_edge(START, "intake")
graph.add_edge("intake", "classify")
graph.add_conditional_edges("classify", route_after_classify, {...})
graph.add_edge("knowledge", "support")

Dicho de forma sencilla, LangGraph es el camarero y cada nodo es una estación de la cocina. Técnicamente, las aristas definen el camino por defecto, las aristas condicionales definen las ramas que dependen del estado, y un SupportState compartido es la forma en que los especialistas se pasan el trabajo sin llamarse entre sí. Esa última propiedad es la que de verdad cuenta:

Intake does not call Support.
Knowledge does not call Classify.
They write to state.
The graph decides the next node.

¿Por qué no un solo agente?

Se podría haber hecho con una sola función:

def handle(message):
    detect role
    classify
    maybe clarify
    search docs
    write answer

Para una demo diminuta funciona, pero en un sistema de aprendizaje oculta las costuras. Dividir el grafo facilita varias cosas:

  • Probar la clasificación sin que intervenga la búsqueda de documentos
  • Depurar una respuesta equivocada por separado de una ruta equivocada
  • Sustituir más adelante un paso, como un clasificador con LLM o una mejor recuperación, sin reescribirlo todo
  • Explicar el sistema con un diagrama sencillo

La claridad es la verdadera ventaja del diseño multiagente en este caso.

Lo que no es

Para ser claros, estos especialistas no son servicios desplegados por separado, no discuten entre ellos y no son empresas autónomas de agentes. Son nodos de grafo con una tarea concreta y contratos claros, orquestados por LangGraph. Para entender la idea basta con eso, y es una descripción honesta de lo que hace el proyecto.

La idea en tres líneas

La orquestación multiagente en el agente de soporte de LEPA se reduce a esto:

Specialize the jobs.
Share state.
Let the graph choose the next job.

Intake, knowledge y support están separados porque sus responsabilidades son distintas, y LangGraph hace visibles los relevos. El siguiente concepto relacionado es human-in-the-loop, que todavía no está implementado como puntos de aprobación reales y no es lo mismo que pedir aclaraciones.