Strona główna / Artykuły / Splitting a Support Agent into Intake, Knowledge and Support Nodes

Artykuł opublikowany po angielsku.

Splitting a Support Agent into Intake, Knowledge and Support Nodes

Why the LEPA support agent is a graph of focused specialists instead of one big function, how LangGraph wires the handoffs through shared state, and what multi-agent means here.

792 słów

By this stage the LEPA support agent can route a request, search documentation and remember a conversation thread. What's left to look at is how the work itself is shaped. Instead of one giant do-everything function, responsibilities go to a few specialists, and LangGraph orchestrates them.

Think of building a house

"Multi-agent" can sound like science fiction. A more useful picture is a construction site where several trades work on one project:

Electrician
Plumber
Painter
Inspector

Different jobs, different skills, one house. A support workflow can be split the same way:

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

That split earns its place only when the jobs really differ. Adding extra boxes to a slide diagram doesn't count.

The graph in this project

The compiled graph runs like this:

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

Intake, knowledge and support are called agents in the project layout because each owns one clear job. Classify and the ask-for-clarification step sit under a nodes/ folder instead, which is the same graph idea with slightly different folder naming. Here "multi-agent" means specialized nodes inside a single compiled StateGraph. It doesn't mean separate deployed services, and it doesn't mean agents debating each other. Folder names matter less than the separation of responsibilities.

What each specialist does

Intake

Intake takes the latest user message and produces a user_role:

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

It doesn't search documentation and it doesn't write the final answer. All it does is prepare routing context.

Classify and the clarification branch

Classify decides the topic and whether enough is known to continue:

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

That branch is orchestration: same system, different next specialist.

Knowledge

Knowledge never chats. It retrieves:

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

An @tool wrapper named search_knowledge lives in the same module for later experiments, but the graph calls the underlying implementation directly.

Support

Support never browses the filesystem. It reads retrieved_documents and produces final_answer, built from a template by default and optionally polished by an LLM when one is configured.

How LangGraph keeps them in order

No manager LLM decides in free form who speaks next. The wiring is explicit:

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

In plain terms, LangGraph is the waiter and each node is a station in the kitchen. Technically, edges define the default path, conditional edges define branches that depend on state, and a shared SupportState is how specialists hand work products to one another without calling each other. That last property is the one that counts:

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

Why not a single agent?

One function would have been possible:

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

For a tiny demo that works, but as a learning system it hides the seams. Splitting the graph makes several things easier:

  • Testing classification without involving document search
  • Debugging a wrong answer separately from a wrong route
  • Replacing one step later, such as an LLM classifier or better retrieval, without rewriting everything
  • Explaining the system with a simple diagram

Clarity is the real payoff of the multi-agent design here.

What it isn't

To be straight about it, these specialists aren't separate deployed services, they don't argue with each other and they aren't autonomous companies of agents. They're focused graph nodes with clear contracts, orchestrated by LangGraph. That's enough to learn the idea, and it's an honest description of what the project does.

The idea in three lines

Multi-agent orchestration in the LEPA support agent comes down to this:

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

Intake, knowledge and support are separate because their responsibilities differ, and LangGraph makes the handoffs visible. A related concept comes next: human-in-the-loop, which is not yet implemented as true approval gates and differs from asking clarification questions.