You Can Build Better AI Agents in Java Than Python

Estimated read time 6 min read

Too many people assume that Gen AI means Python. Not so.

In this blog I’ll demonstrate that the best programming model for writing agents is on the JVM, and that the Embabel agent framework offers significant advantages over Python alternatives.

I’ll take a nontrivial sample app from a leading Python framework and rewrite it in Java to be cleaner, more extensible, and require less code.

The Task: Writing a Book

CrewAI is one of the most popular agent frameworks. Thus it’s a good candidate to benchmark Java versus Python.

I chose an example from the official collection of complete CrewAI applications, billed as containing “end-to-end implementations that showcase how to build real-world applications using CrewAI’s framework for orchestrating AI agents.”

The Write a Book Flow seemed a good place to start. Here’s their description of what it does:

This flow will guide you through the process of writing a book by leveraging multiple AI agents, each with specific roles. Here’s a brief overview of what will happen in this flow:

1. Generate Book Outline: The flow starts by using the OutlineCrew to create a comprehensive outline for your book. This crew will search the internet, define the structure, and main topics of the book based on the provided goal and topic.

2. Write Book Chapters: Once the outline is ready, the flow will kick off a new crew, WriteBookChapterCrew, for each chapter outlined in the previous step. Each crew will be responsible for writing a specific chapter, ensuring that the content is detailed and coherent.

3. Join and Save Chapters: In the final step, the flow will combine all the chapters into a single markdown file, creating a complete book. This file will be saved in the root folder of your project.

By following this flow, you can efficiently produce a well-structured and comprehensive book, leveraging the power of multiple AI agents to handle different aspects of the writing process.

This is a nice multi-agent scenario, fun in itself and relevant to many real-world problems.

The Crew Implementation

Concepts

Crew models tasks in terms of “crews”: groups of specialized agents that are assigned tasks. Most Crew examples have a 1:1 mapping between agents and tasks.

Agents and tasks are usually expressed in YML, and everything is wired up in Python. As in most Python frameworks, Pydantic models are used to specify structured output from LLM calls.

The Implementation

The book writing flow involves two crews. The first researches the topic of the book and writes an outline; the second writes each chapter of the book, after further, focused research.

The outline crew consists of two agents. A Crew agent has a role, goal and backstory:

researcher:
role: >
Research Agent
goal: >
Gather comprehensive information about {topic} that will be used to create an organized and well-structured book outline.
Here is some additional information about the author's desired goal for the book:\n\n {goal}
backstory: >
You're a seasoned researcher, known for gathering the best sources and understanding the key elements of any topic.
You aim to collect all relevant information so the book outline can be accurate and informative.

outliner:
role: >
Book Outlining Agent
goal: >
Based on the research, generate a book outline about the following topic: {topic}
The generated outline should include all chapters in sequential order and provide a title and description for each chapter.
Here is some additional information about the author's desired goal for the book:\n\n {goal}
backstory: >
You are a skilled organizer, great at turning scattered information into a structured format.
Your goal is to create clear, concise chapter outlines with all key topics and subtopics covered.

The outline crew has two tasks, also defined in YML:

research_topic:
description: >
Research the provided topic of {topic} to gather the most important information that will
be useful in creating a book outline. Ensure you focus on high-quality, reliable sources.

Here is some additional information about the author's desired goal for the book:\n\n {goal}
expected_output: >
A set of key points and important information about {topic} that will be used to create the outline.
agent: researcher

generate_outline:
description: >
Create a book outline with chapters in sequential order based on the research findings.
Ensure that each chapter has a title and a brief description that highlights the topics and subtopics to be covered.
It's important to note that each chapter is only going to be 3,000 words or less.
Also, make sure that you do not duplicate any chapters or topics in the outline.

Here is some additional information about the author's desired goal for the book:\n\n {goal}

expected_output: >
An outline of chapters, with titles and descriptions of what each chapter will contain.
agent: outliner

Agent and crew definitions contain placeholders such as {topic} and {goal}.

The crew is wired up in Python. The agents are loaded and configured. Each agent can use its own LLM and tools:

@CrewBase
class OutlineCrew:
"""Book Outline Crew"""

agents_config = "config/agents.yaml"
tasks_config = "config/tasks.yaml"
llm = LLM(model="gpt-4o")

@agent
def researcher(self) -> Agent:
search_tool = SerperDevTool()
return Agent(
config=self.agents_config["researcher"],
tools=[search_tool],
llm=self.llm,
verbose=True,
)

@agent
def outliner(self) -> Agent:
return Agent(
config=self.agents_config["outliner"],
llm=self.llm,
verbose=True,
)

Next, the tasks are loaded, specifying their output format (what the LLM call should return):

@task
def research_topic(self) -> Task:
return Task(
config=self.tasks_config["research_topic"],
)

@task
def generate_outline(self) -> Task:
return Task(
config=self.tasks_config["generate_outline"],
output_pydantic=BookOutline
)

Finally we build the crew. The ordering of agents implies the data flow: the research will be available when the outline is computed, although this is not made explicit:

@crew
def crew(self) -> Crew:
"""Creates the Book Outline Crew"""
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)

The “write book chapter” crew is similar.

Python code in the root of the example brings together both crews. Pydantic models provide a simple domain model for book and chapter outline:

class ChapterOutline(BaseModel):
title: str
description: str


class BookOutline(BaseModel):
chapters: List[ChapterOutline]


class Chapter(BaseModel):
title: str
content: str

These types are used in BookState

You May Also Like

More From Author

+ There are no comments

Add yours