Zheat Logo
    YohanYohanSenior Software Engineer

    Agents, same recipe, different ingredients

    An agent is an LLM that can call tools. Same skeleton every time: model, prompt, MCP, sub-agents. YAML to instantiate them, a UI so the client creates them, no single provider lock-in.

    View on LinkedIn

    An agent is an LLM that can call the right tools from a sentence in natural language. That is the whole bar. A reasoning loop makes it stronger. The recipe does not change. The ingredients do: which model, which MCP servers, which prompt, which sub-agents.

    This paper is that recipe. Same architecture I already use on client work: split responsibilities, keep components independent, do not glue the app to one vendor. A live UI exists at composables.soludev.tech (access is not open; contact me).

    Canonical URL: https://www.zheat.xyz/en/insights/composable-agents/


    Table of contents

    1. What is an agent?
    2. What is a reasoning loop?
    3. When is RAG the wrong tool?
    4. Why put the agent in YAML?
    5. What are the three bricks?
    6. Will agents become packaged software?
    7. FAQ
    8. References

    What is an agent?

    An agent is an LLM that can call the right tools from a sentence in natural language. No extra sophistication. No reasoning loop required. From there you already have an agent.

    Agents are everywhere in software now. Almost too much.

    Unless you live at the centre of the earth with almost no access to civilisation, you already know what an agent is. Still, better to line up the words.

    I do not ask much of a piece of software before I call it an agent. Simple, yes. That is where it starts.


    What is a reasoning loop?

    A reasoning loop is the next brick: at each turn the LLM asks whether it can answer now, or whether it needs a tool. If it can answer, it returns to the caller.

    Most agents you see sit on that brick, from ChatGPT to Claude Code. The loop is what people call intelligence.

    Remember that. That is the fundamental of what an agent does today.


    When is RAG the wrong tool?

    RAG is the wrong tool when the job needs to cross facts across several documents, the answer is not in a passage that is semantically close, and the number of chunks that reach the LLM is capped.

    A client had put a RAG in place to analyse real-estate crowdfunding files. It was not good enough. It missed information.

    I was hired to improve what was there. After a few tests I could see I would not get a much better result by pushing the same RAG harder.

    I stopped spending time on that RAG and tried something else.

    ApproachWhat it does wellWhere it failed on those files
    RAGRetrieve passages that look similar to the questionMissed facts spread across documents. Chunk cap.
    Agent + tools + MCPCall tools, cross documents, delegate to sub-agentsFit the job once pushing the RAG stopped being worth it.

    Why put the agent in YAML?

    The agent is parameters: model, prompt, MCP, sub-agents, interrupts. YAML is the config. The runtime instantiates different agents from it.

    I needed to test several agents, with different methods, fast. At the same time I was looking at Deep Agents, a LangChain abstraction for autonomous agents.

    The ReAct loop is already wrapped by LangChain.

    mcp = MultiServerMCPClient({
        "github": {
            "transport": "http",
            "url": "https://mcp-anything/real-estate/mcp"
        }
    })
    
    agent = create_deep_agent(
        model="openai:gpt-5.5",
        tools=mcp.get_tools(),
        subagents=[
            {
                "name": "researcher",
                "model": "anthropic:claude-haiku-4-5-20251001",
                "description": "Web search",
                "system_prompt": "You search."
            }
        ],
        system_prompt="You code. Delegate to researcher.",
        interrupt_on={"file_write": True},
    )

    A few lines later you have an agent that uses tools over MCP, delegates to a sub-agent, and asks a human before some actions.

    Look closer: everything that defines the agent is a parameter. So you can put that definition in YAML and instantiate different agents from it.

    I built a small layer that parses YAML and instantiates an agent.

    name: haiku-rag-formation
    
    model: openai:anthropic/claude-haiku-4.5:nitro
    
    system_prompt: |
      ## Goal
      You are a real-estate analyst assistant...
    
    mcp_servers:
      - name: raganything
        transport: http
        url: https://mcp-anything/real-estate/mcp
        headers:
          Authorization: "Bearer ${USER_JWT}"
          X-API-Key: "${USER_API_KEY}"

    The benefit for me is obvious: a small factory of agents I can reuse on other client cases.

    And then: what if the client could create the agents themselves?


    What are the three bricks?

    The three bricks are independent: a UI to create agents, a runtime to run them, MCP services to give them capabilities. You can use them apart. Together they are a platform.

    One piece was still missing for a complete, reusable system: an interface anyone can use.

    What I built for that client generalises to three bricks:

    ┌──────────────────┐
    │  Composable UI   │
    │  create / use    │
    │     the agents   │
    └────────┬─────────┘
             │
             ▼
    ┌──────────────────┐
    │ Composable Agents│
    │                  │
    │ runtime agents   │
    │ subagents / HITL │
    └────────┬─────────┘
             │ MCP
    ┌────────┴─────────┐
    ▼                  ▼
    ┌──────────────────┐  ┌──────────────────┐
    │ MCP-RAGAnything  │  │   other MCP      │
    │                  │  │      servers     │
    │ files + RAG      │  │                  │
    └──────────────────┘  └──────────────────┘

    Any client can now create agents themselves without depending on one provider.


    Will agents become packaged software?

    I think agents will become a new packaged software unit. For a large share of use cases you will not rewrite the implementation from zero. You start from an existing agent, give it new capabilities, change its behaviour, compose it with others.

    Custom code will still exist. It should become the exception, not the rule.

    I did not predict the future of agents.

    I applied the architecture I already use: decouple responsibilities, keep components independent, define clear interfaces, do not couple the app to one implementation.

    A few months into this project, several large players in the ecosystem land on similar abstractions.

    I will not conclude that I found the right architecture. It is still reassuring: a way of designing software that felt natural pointed in a direction the industry also seems to take.


    FAQ

    What is an agent? An agent is an LLM that can call the right tools from natural language. A reasoning loop is optional at the start, then almost always added.

    When is RAG the wrong tool for document analysis? When the files need facts crossed across documents. Semantic retrieval plus a chunk cap missed that on real-estate crowdfunding dossiers. The agent stack (tools, MCP, sub-agents) was the better fit.

    Why define agents in YAML? The agent is parameters: model, prompt, MCP, sub-agents, interrupts. YAML is the config. The runtime is the recipe. See also I rebuilt an agent for the fourth time.

    Do I still write custom agent code? Yes, for the odd case. For most cases you should not rebuild the glue.

    Is the composable UI public? There is an online version at composables.soludev.tech. Sign-up is not open. Contact me.


    References

    LangChain describes Deep Agents as an abstraction for autonomous agents, and now also pushes managed agents.