Organizations are more and more investing in AI as these new instruments are adopted in on a regular basis operations increasingly. This steady wave of innovation is fueling the demand for extra environment friendly and dependable frameworks. Following this development, Datapizza (the startup behind Italy’s tech neighborhood) simply launched an open-source framework for GenAI with Python, known as Datapizza AI.
When creating LLM-powered Brokers, it’s essential choose an AI stack:
- Language Mannequin – the mind of the Agent. The primary large choice is open-source (i.e. Llama, DeepSeek, Phi) vs paid (i.e. ChatGPT, Claude, Gemini). Then, based mostly on the usecase, one wants to think about the LLM data: generic (is aware of a little bit little bit of every little thing like Wikipedia) vs topic-specific (i.e. fine-tuned for coding or finance).
- LLM Engine – it’s what runs the language mannequin, responding to prompts, inferring that means, and creating textual content. Mainly, it generates intelligence. Probably the most used are OpenAI (ChatGPT), Anthropic (Claude), Google (Gemini), and Ollama (runs open-source fashions domestically).
- AI Framework – it’s the orchestration layer to construct and handle workflows. To place it in one other method, the framework should construction the intelligence created by LLMs. In the meanwhile, the panorama is dominated by LangChain, LLamaIndex, and CrewAI. The brand new library Datapizza AI falls on this class and desires to be an alternative choice to the opposite foremost frameworks.
On this article, I’m going to indicate how one can use the brand new Datapizza framework for constructing LLM-powered AI Brokers. I’ll current some helpful Python code that may be simply utilized in different comparable circumstances (simply copy, paste, run) and stroll by each line of code with feedback in an effort to replicate this instance.
Setup
I’ll use Ollama because the LLM engine, as a result of I wish to host fashions domestically on my pc. That’s the usual follow for all corporations with delicate knowledge. Maintaining every little thing native offers full management over knowledge privateness, mannequin conduct, and price.
Initially, it’s essential obtain Ollama from the web site. Then, choose a mannequin and run the command indicated on the web page to drag the LLM. I’m going with Alibaba’s Qwen, because it’s each sensible and lite (ollama run qwen3).
Datapizza AI helps all the primary LLM engines. We are able to full the setup by working the next instructions:
pip set up datapizza-ai
pip set up datapizza-ai-clients-openai-like
As indicated within the official documentation, we will rapidly check our AI stack by calling the mannequin with a easy immediate and asking a query. The article OpenAILikeClient() is the way you hook up with the Ollama API, which is normally hosted on the identical localhost URL.
from datapizza.purchasers.openai_like import OpenAILikeClient
llm = "qwen3"
immediate = '''
You might be an clever assistant, present the absolute best reply to person's request.
'''
ollama = OpenAILikeClient(api_key="", mannequin=llm, system_prompt=immediate, base_url="http://localhost:11434/v1")
q = '''
what time is it?
'''
llm_res = ollama.invoke(q)
print(llm_res.textual content)
Chatbot
One other technique to check the aptitude of the LLM is to construct a easy Chatbot and do some dialog. To take action, at each interplay, we have to retailer the chat historical past and feed it again to the mannequin, specifying what was stated by whom. The Datapizza framework already has a built-in reminiscence system.
from datapizza.reminiscence import Reminiscence
from datapizza.kind import TextBlock, ROLE
reminiscence = Reminiscence()
reminiscence.add_turn(TextBlock(content material=immediate), position=ROLE.SYSTEM)
whereas True:
## Person
q = enter('🙂 >')
if q == "stop":
break
## LLM
llm_res = ollama.invoke(q, reminiscence=reminiscence)
res = llm_res.textual content
print("🍕 >", f"x1b[1;30m{res}x1b[0m")
## Update Memory
memory.add_turn(TextBlock(content=q), role=ROLE.USER)
memory.add_turn(TextBlock(content=res), role=ROLE.ASSISTANT)

If you want to retrieve the chat history, you can just access the memory. Usually, AI frameworks use three roles in the interaction with an LLM: “system” (core instructions), “user” (what was said by the human), “assistant” (what the chatbot replied).
memory.to_dict()

Obviously, the LLM alone is very limited and it can’t do much besides chatting. Therefore, we need to give it the possibility to take action, or in other words, to activate Tools.
Tools
Tools are the main difference between a simple LLM and an AI Agent. When the user requests something that goes beyond the LLM knowledge base (i.e. “what time is it now?“), the Agent should understand that it doesn’t know the answer, activate a Tool to get additional information (i.e. checking the clock), elaborate the result through the LLM, and generate an answer.
The Datapizza framework allows you to create Tools from scratch very easily. You just need to import the decorator @tool and any function can become actionable for the Agent.
from datapizza.tools import tool
@tool
def get_time() -> str:
'''Get the current time.'''
from datetime import datetime
return datetime.now().strftime("%H:%M")
get_time()
Then, assign the designated Tool to the Agent, and you’ll have an AI that combines language understanding + autonomy decision making + tool use.
from datapizza.agents import Agent
import os
os.environ["DATAPIZZA_AGENT_LOG_LEVEL"] = "DEBUG" #max logging
agent = Agent(title="single-agent", shopper=ollama, system_prompt=immediate,
instruments=[get_time], max_steps=2)
q = '''
what time is it?
'''
agent_res = agent.run(q)

An LLM-powered AI Agent is an clever system constructed round a language mannequin that doesn’t simply reply, nevertheless it causes, decides, and acts. Apart from dialog (which suggests chatting with a general-purpose data base), the most typical actions that Brokers can do are RAG (chatting together with your paperwork), Querying (chatting with a database), Internet Search (chatting with the entire Web).
As an example, let’s attempt an internet looking Software. In Python, the best technique to do it’s with the well-known non-public browser DuckDuckGo. You possibly can instantly use the authentic library or the Datapizza framework wrapper (pip set up datapizza-ai-tools-duckduckgo).
from datapizza.instruments.duckduckgo import DuckDuckGoSearchTool
DuckDuckGoSearchTool().search(question="powell")

Let’s create an Agent that may search the online for us. If you wish to make it extra interactive, you’ll be able to construction the AI like I did for the Chatbot.
os.environ["DATAPIZZA_AGENT_LOG_LEVEL"] = "ERROR" #flip off logging
immediate = '''
You're a journalist. You should make assumptions, use your instrument to analysis, make a guess, and formulate a closing reply.
The ultimate reply should include info, dates, evidences to assist your guess.
'''
reminiscence = Reminiscence()
agent = Agent(title="single-agent", shopper=ollama, system_prompt=immediate,
instruments=[DuckDuckGoSearchTool()],
reminiscence=reminiscence, max_steps=2)
whereas True:
## Person
q = enter('🙂 >')
if q == "stop":
break
## Agent
agent_res = agent.run(q)
res = agent_res.textual content
print("🍕 >", f"x1b[1;30m{res}x1b[0m")
## Update Memory
memory.add_turn(TextBlock(content=q), role=ROLE.USER)
memory.add_turn(TextBlock(content=res), role=ROLE.ASSISTANT)

Multi-Agent System
The real strength of Agents is the ability to collaborate with each other, just like humans do. These teams are called Multi-Agent Systems (MAS), a group of AI Agents that work together in a shared environment to solve complex problems that are too difficult for a single one to handle alone.
This time, let’s create a more advanced Tool: code execution. Please note that LLMs know how to code by being exposed to a large corpus of both code and natural language text, where they learn patterns, syntax, and semantics of programming languages. But since they can not complete any real action, the code they create is just text. In short, LLMs can generate Python code but can’t execute it, Agents can.
import io
import contextlib
@tool
def code_exec(code:str) -> str:
'''Execute python code. Use always the function print() to get the output'''
output = io.StringIO()
with contextlib.redirect_stdout(output):
try:
exec(code)
except Exception as e:
print(f"Error: {e}")
return output.getvalue()
code_exec("from datetime import datetime; print(datetime.now().strftime('%H:%M'))")
There are two types of MAS: the sequential process ensures tasks are executed one after the other, following a linear progression. On the other hand, the hierarchical structure simulates traditional organizational hierarchies for efficient task delegation and execution. Personally, I tend to prefer the latter as there is more parallelism and flexibility.
With the Datapizza framework, you can link two or more Agents with the function can_call(). In this way, one Agent can pass the current task to another Agent.
prompt_senior = '''
You are a senior Python coder. You check the code generated by the Junior,
and use your tool to execute the code only if it's correct and safe.
'''
agent_senior = Agent(name="agent-senior", client=ollama, system_prompt=prompt_senior,
tools=[code_exec])
prompt_junior = '''
You're a junior Python coder. You possibly can generate code however you'll be able to't execute it.
You obtain a request from the Supervisor, and your closing output should be Python code to cross on.
If you do not know some particular instructions, you need to use your instrument and search the online for "how one can ... with python?".
'''
agent_junior = Agent(title="agent-junior", shopper=ollama, system_prompt=prompt_junior,
instruments=[DuckDuckGoSearchTool()])
agent_junior.can_call([agent_senior])
prompt_manager = '''
You realize nothing, you are only a supervisor. After you get a request from the person,
first you ask the Junior to generate the code, you then ask the Senior to execute it.
'''
agent_manager = Agent(title="agent-manager", shopper=ollama, system_prompt=prompt_manager,
instruments=[])
agent_manager.can_call([agent_junior, agent_senior])
q = '''
Plot the Titanic dataframe. You could find the info right here:
https://uncooked.githubusercontent.com/mdipietro09/DataScience_ArtificialIntelligence_Utils/grasp/machine_learning/data_titanic.csv
'''
agent_res = agent_manager.run(q)
#print(agent_res.textual content)


Conclusion
This text has been a tutorial to introduce Datapizza AI, a model new framework to construct LLM-powered Chatbots and AI Brokers. The library may be very versatile and user-friendly, and may cowl totally different GenAI usecases. I used it with Ollama, however it may be linked with all of the well-known engines, like OpenAI.
Full code for this text: GitHub
I hope you loved it! Be at liberty to contact me for questions and suggestions or simply to share your fascinating initiatives.
👉 Let’s Join 👈

(All pictures are by the writer except in any other case famous)
