Learning · Guide

Build a Multi-Agent LLM Pipeline in Python

A working multi-agent LLM pipeline in Python: plain code fetches, one agent reads, another writes. Complete code, runs locally with no API key.

Last tested on 2026-11-12

A multi-agent LLM pipeline splits a job between several agents, each with its own instructions, and passes the output of one to the next. It beats one long prompt when the job has distinct stages, because you can test, fix and swap one stage without touching the others.

This page shows a small, complete example in Python with Maki, an open-source multi-agent framework. It finds a Hacker News story, reads the page and writes a short brief. It runs on a model on your own machine, so it needs no API key.

The pattern

  1. Gather with plain code. Anything that needs no judgement, such as searching and fetching, stays ordinary Python.
  2. Read with one agent. The Reader gets the raw page and extracts the points.
  3. Write with another. The Writer sees only the Reader's points, never the page.
  4. Check between the steps. If the Reader says the page does not match the story, stop.

The code

"""Chapter 4: a two-step pipeline, plain code plus two agents.

Run it with:  python ch04_pipeline/scout.py "python"
Step 1 (plain Python): find a story on Hacker News and fetch the page as Markdown.
Step 2 (agent "Reader"): summarise the page.
Step 3 (agent "Writer"): turn the summary into a short brief.
"""
import os
import sys

from maki import init_backend
from maki.agents import Agent
from maki.plugins.web_search import WebSearch
from maki.plugins.web_to_md import WebToMd

DEFAULT_SPEC = "ollama:qwen3.5:4b"   # 3.4 GB. Bigger machine: "ollama:gemma4:26b".


def make_backend(spec=None):
    """The model Scout talks to, named by a "provider:model" string.

    Set SCOUT_BACKEND to use another server, for example "llamacpp" or
    "vllm:Qwen/Qwen2.5-1.5B-Instruct". Nothing else in the program changes.
    """
    spec = spec or os.environ.get("SCOUT_BACKEND", DEFAULT_SPEC)
    # think=False: qwen3.5 is a "thinking" model. Left on, a long page can use up its budget
    # on reasoning and Maki then returns the reasoning as the answer. Ollama-only setting.
    options = {"think": False} if spec.split(":")[0] == "ollama" else {}
    return init_backend(spec, **options)


FOOTER = "\n\n_Made with Maki (https://pypi.org/project/maki-framework/)._"
MAX_PAGE_CHARS = 6000   # a small model reads a small page


def gather(topic):
    """Step 1: the first story that has a readable page, as (title, url, markdown)."""
    for item in WebSearch().search_hackernews(topic, max_results=5):
        page = WebToMd().fetch_and_convert_to_md(item["url"])
        if page.get("success") and page.get("content"):
            return item["title"], item["url"], page["content"][:MAX_PAGE_CHARS]
    return None


def main(topic="python", backend=None, footer=True):
    found = gather(topic)
    if found is None:
        print(f"No readable story found for {topic!r} this week.")
        return None
    title, url, markdown = found

    model = backend or make_backend()
    reader = Agent(name="Reader", maki_instance=model, role="reader",
                   instructions=("Summarise the page in five bullet points. Use only the page. "
                                 "If the page is not about the title (a login wall, a cookie notice), "
                                 "reply only: PAGE DOES NOT MATCH."))
    writer = Agent(name="Writer", maki_instance=model, role="writer",
                   instructions="Write a three-sentence brief for a busy developer.")

    summary = reader.execute_task(f"Page title: {title}\n\n{markdown}")
    if "PAGE DOES NOT MATCH" in summary:
        print(f"Skipped {url}: the page did not match its title.")
        return None
    brief = writer.execute_task(f"Source: {url}\n\nSummary:\n{summary}")
    result = f"# {title}\n\n{brief}\n\nSource: {url}" + (FOOTER if footer else "")
    print(result)
    return result


if __name__ == "__main__":
    main(sys.argv[1] if len(sys.argv) > 1 else "python")

Run it

python -m venv .venv && source .venv/bin/activate
pip install maki-framework
ollama pull qwen3.5:4b
python ch04_pipeline/scout.py python

You need Ollama running and the code from the course. The package is maki-framework.

Why split it up

  • Each agent has one small job. A small local model handles "write five bullets" much better than "find, read and write".
  • You can see where it went wrong. If the brief is bad, print the Reader's bullets and you know which agent to fix.
  • You can swap one part. Give the Writer a larger model, or replace the Gather step with a different source, and leave the rest alone.

The full walk-through, from installing Maki to this pipeline, is the Learning course, which starts with what Maki is. It also explains the two ways this pipeline broke and how they were fixed.