dhilst

Building Agent Chains and Self-Improving Loops with LangChain and Ollama

Large Language Models (LLMs) are great at responding to prompts, but what if you could orchestrate multiple LLMs to collaborate, each playing a specific role, like characters in a game or components in a system?

That’s exactly what I explored with a tool I developed using LangChain and Ollama, two fantastic libraries that make it easy to run local LLMs and compose them into complex chains. The idea: define a series of agents, each with a role and a prompt, and chain them together so that the output of one becomes the input of the next. Then loop the process for self-improving or interactive behavior.

From Idea to Code: Generating with Gemini

The core of this system was drafted with help from Gemini (Google’s AI code assistant). I wanted a flexible CLI tool where I could:

  • Specify multiple agents with roles and prompts.
  • Chain them so that each agent receives the output of the previous.
  • Loop the chain so that the process could iterate, potentially converging to a solution or evolving the content.

I described the goal to Gemini, iterated a bit, and ended up with a working prototype. Then I fine-tuned the details and added features like prompt history, model selection, and streaming responses.

How It Works

You define a chain of agents using --agent arguments like this:

    --agent "judge:You are a Fight Judge. You'll be intermediating the fight between player1 and player2..." \\
    --agent "player1:You are a fast fighter. Choose your move:" \\
    --agent "player2:You are a strong fighter. Choose your move:" \\ 
    --agent "math engine:Analyze the moves and compute damage." 

You can assign models using --model llama3, and provide an initial task like --task "Start the fight."

Once the chain starts, the first agent processes the task, the second processes the result, and so on. Each agent works like an LLM-based function with a custom prompt. This is done using LangChain’s PromptTemplate and Ollama-backed LLM calls.

Enabling Loops for Self-Improvement and Games

The magic comes when you use --loop:

--loop 10

This turns the chain into a loop. The final output of the last agent is fed back as the input to the first agent in the next iteration. That means your agents can:

  • Iterate toward a solution (e.g. refining an algorithm or improving a story).
  • Simulate a game loop (like turn-based combat or roleplaying).
  • Serve as optimization steps in a machine learning-style feedback loop.

Each iteration maintains context (unless --no-history is used), allowing agents to “remember” recent interactions—like short-term memory.

Example: AI-Powered Fighting Game

Here’s a simple example of a looped simulation:

python pipe.py \\
  --model llama3 \\
  --agent "judge:You are a Fight Judge. You'll be intermediating the fight between player1 and player2..." \\
  --agent "player1:You are an agile fighter, you can punch and kick really fast..." \\
  --agent "player2:You are a strong fighter, your punches are heavy but slow..." \\
  --agent "math engine:You are the math game engine, analyse players moves and decide what landed..." \\
  --task "Compute the output of a fight between two players mediated by a judge and computed by an engine" \\
  --loop 10

Each agent plays its role, the judge moderates, and the math engine ensures the game mechanics make sense. After 10 iterations, you get a complete fight simulation—generated by AI agents in a structured loop.

Game example running

Here is a GIF showing the following chaing running

python pipe.py \\
  --model llama3 \\
  --agent "DungeonMaster:You are a Dungeon Master for a classic fantasy RPG.
    Describe the immediate surroundings to the player, including any points of
    interest or immediate threats. Add frequent moster fights. After the first
    round you'll receive a command from the Player, interpret the Player command
    and tell what it happens." \\
  --agent "Player:You are a brave adventurer in a dungeon. Based on the Dungeon
    Master's description, decide your next action. Be concise and direct." \\
  --task "The adventure begins. The player character has just entered a dimly lit, damp cavern." \\
  --loop 10

GameRPGStream

Why This Is Useful

This system goes beyond fun simulations:

  • Code generation: A “developer” agent writes code, a “reviewer” critiques, and a “tester” evaluates output.
  • Research automation: A “researcher” collects data, a “writer” generates summaries, a “critic” refines them.
  • Creative writing: Characters evolve a story together, iteratively.

Because it runs locally using Ollama models, you can experiment freely with no API cost and full control.

Closing Thoughts

This project shows how composing agents—rather than prompting a single monolithic model—can unlock emergent behaviors, iterative refinement, and playful or productive systems. Whether you want to simulate a fantasy battle or automate code reviews, chaining LLM agents offers a powerful new way to work with language models.

Build your own loop, give your agents roles, and let them surprise you.