Get started with AI agents
Build your first AI agent using Mosaic AI Agent Framework. In this tutorial, you will:
- Author an agent using Agent Framework.
- Add a tool to your agent.
- Deploy your agent to a Databricks model serving endpoint.
For a conceptual introduction to agents and other gen AI apps, see What are gen AI apps?
Requirements
Your workspace must have the following features enabled:
- Unity Catalog
- Mosaic AI Agent Framework
- Foundation models (pay-per-token, provisioned throughput, or external models). See Features with limited regional availability
Example notebook
This notebook contains all the code you need to author and deploy your first AI agent. Import the notebook to your Databricks workspace to run it.
Mosaic AI agent demo
Define the agent
An AI agent consists of the following:
- A large language model (LLM) that can reason and make decisions
- Tools that the LLM can use to do more than just generate text, such as running Python code or fetching data
Run the following code in a Databricks notebook to define a simple tool-calling agent:
-
Install the required Python packages:
Python%pip install -U -qqqq mlflow databricks-openai databricks-agents
dbutils.library.restartPython()mlflow
: Used for agent development and agent tracing.databricks-openai
: Used to connect to the Databricks-hosted LLM.databricks-agent
: Used to package and deploy the agent.
-
Define the agent. This code snippet does the following:
- Connects to the Databricks model serving endpoint using the OpenAI client.
- Enables MLflow tracing using
autolog()
. This adds instrumentation so you can see what your agent does when you submit a query. - Adds the
system.ai.python_exec
tool to your agent. This built-in Unity Catalog function allows your agent to run Python code. - Defines a function that queries the LLM with a prompt and handles responses.
Pythonimport mlflow
import json
from databricks.sdk import WorkspaceClient
from databricks_openai import UCFunctionToolkit, DatabricksFunctionClient
# Get an OpenAI client configured to connect to Databricks model serving endpoints
# Use this client to query the LLM
openai_client = WorkspaceClient().serving_endpoints.get_open_ai_client()
# Enable automatic tracing for easier debugging
mlflow.openai.autolog()
# Load Databricks built-in tools (Python code interpreter)
client = DatabricksFunctionClient()
builtin_tools = UCFunctionToolkit(function_names=["system.ai.python_exec"], client=client).tools
for tool in builtin_tools:
del tool["function"]["strict"]
def call_tool(tool_name, parameters):
if tool_name == "system__ai__python_exec":
return DatabricksFunctionClient().execute_function("system.ai.python_exec", parameters=parameters)
raise ValueError(f"Unknown tool: {tool_name}")
def run_agent(prompt):
"""
Send a user prompt to the LLM and return a list of LLM response messages
The LLM is allowed to call the code interpreter tool, if needed, to respond to the user
"""
result_msgs = []
response = openai_client.chat.completions.create(
model="databricks-claude-3-7-sonnet",
messages=[{"role": "user", "content": prompt}],
tools=builtin_tools,
)
msg = response.choices[0].message
result_msgs.append(msg.to_dict())
# If the model executed a tool, call it
if msg.tool_calls:
call = msg.tool_calls[0]
tool_result = call_tool(call.function.name, json.loads(call.function.arguments))
result_msgs.append({"role": "tool", "content": tool_result.value, "name": call.function.name, "tool_call_id": call.id})
return result_msgs
Test the agent
Test the agent by querying it with a prompt that requires running Python code:
answer = run_agent("What is the 100th fibonacci number?")
for message in answer:
print(f'{message["role"]}: {message["content"]}')
In addition to the LLM's output, you will see detailed trace information directly in your notebook. These traces help you debug slow or failed agent calls. These traces were automatically added using mlflow.openai.autolog()
.
Deploy the agent
Now that you have an agent, you can package and deploy it to a Databricks serving endpoint. Start collecting feedback on a deployed agent by sharing it with others and chatting with it using a built-in chat UI.
Prepare agent code for deployment
To prepare your agent code for deployment, wrap it using MLflow's ChatAgent
interface. The ChatAgent
interface is the recommended way to package agents for deployment on Databricks.
-
To implement the
ChatAgent
interface, you must define apredict()
function that sends the user's message to the agent, collects the agent's response, and returns it in theChatAgentResponses
format.Pythonimport uuid
from typing import Any, Optional
from mlflow.pyfunc import ChatAgent
from mlflow.types.agent import ChatAgentMessage, ChatAgentResponse, ChatContext
class QuickstartAgent(ChatAgent):
def predict(
self,
messages: list[ChatAgentMessage],
context: Optional[ChatContext] = None,
custom_inputs: Optional[dict[str, Any]] = None,
) -> ChatAgentResponse:
# 1. Extract the last user prompt from the input messages
prompt = messages[-1].content
# 2. Call run_agent to get back a list of response messages
raw_msgs = run_agent(prompt)
# 3. Map each response message into a ChatAgentMessage and return
# the response
out = []
for m in raw_msgs:
out.append(ChatAgentMessage(
id=uuid.uuid4().hex,
**m
))
return ChatAgentResponse(messages=out) -
Add the following code to your notebook to test your
ChatAgent
class:PythonAGENT = QuickstartAgent()
for response_message in AGENT.predict({"messages": [{"role": "user", "content": "What's the 100th fibonacci number?"}]}).messages:
print(f"role: {response_message.role}, content: {response_message.content}") -
Combine all of your agent code into a single file so you can log and deploy it.
- Consolidate all of your agent code into one notebook cell.
- At the top of the cell, add the
%%writefile quickstart_agent.py
magic command to save your agent to a file. - At the bottom of the cell, call
mlflow.models.set_model()
with your agent object. This tells MLflow which agent object to use when serving predictions. This step effectively configures the entry point to our agent code.
Your notebook cell should look like the following:
%%writefile quickstart_agent.py
import json
import uuid
from databricks.sdk import WorkspaceClient
from databricks_openai import UCFunctionToolkit, DatabricksFunctionClient
from typing import Any, Optional
import mlflow
from mlflow.pyfunc import ChatAgent
from mlflow.types.agent import ChatAgentMessage, ChatAgentResponse, ChatContext
# Add an mlflow.openai.autolog() call to capture traces in the serving endpoint
# Get an OpenAI client configured to talk to Databricks model serving endpoints
# We'll use this to query an LLM in our agent
openai_client = WorkspaceClient().serving_endpoints.get_open_ai_client()
# Load Databricks built-in tools (a stateless Python code interpreter tool)
client = DatabricksFunctionClient()
builtin_tools = UCFunctionToolkit(function_names=["system.ai.python_exec"], client=client).tools
for tool in builtin_tools:
del tool["function"]["strict"]
def call_tool(tool_name, parameters):
if tool_name == "system__ai__python_exec":
return DatabricksFunctionClient().execute_function("system.ai.python_exec", parameters=parameters)
raise ValueError(f"Unknown tool: {tool_name}")
def run_agent(prompt):
"""
Send a user prompt to the LLM, and return a list of LLM response messages
The LLM is allowed to call the code interpreter tool if needed, to respond to the user
"""
result_msgs = []
response = openai_client.chat.completions.create(
model="databricks-claude-3-7-sonnet",
messages=[{"role": "user", "content": prompt}],
tools=builtin_tools,
)
msg = response.choices[0].message
result_msgs.append(msg.to_dict())
# If the model executed a tool, call it
if msg.tool_calls:
call = msg.tool_calls[0]
tool_result = call_tool(call.function.name, json.loads(call.function.arguments))
result_msgs.append({"role": "tool", "content": tool_result.value, "name": call.function.name, "tool_call_id": call.id})
return result_msgs
class QuickstartAgent(ChatAgent):
def predict(
self,
messages: list[ChatAgentMessage],
context: Optional[ChatContext] = None,
custom_inputs: Optional[dict[str, Any]] = None,
) -> ChatAgentResponse:
prompt = messages[-1].content
raw_msgs = run_agent(prompt)
out = []
for m in raw_msgs:
out.append(ChatAgentMessage(
id=uuid.uuid4().hex,
**m
))
return ChatAgentResponse(messages=out)
AGENT = QuickstartAgent()
mlflow.models.set_model(AGENT)
Log the agent
Log your agent and register it to Unity Catalog. This packages your agent and its dependencies into a single artifact for deployment.
import mlflow
from mlflow.models.resources import DatabricksFunction, DatabricksServingEndpoint
from pkg_resources import get_distribution
# Change the catalog name ("main") and schema name ("default") to register the agent to a different location
registered_model_name = "main.default.quickstart_agent"
# Specify Databricks resources that the agent needs to access.
# This step lets Databricks automatically configure authentication
# so the agent can access these resources when it's deployed.
resources = [
DatabricksServingEndpoint(endpoint_name="databricks-claude-3-7-sonnet"),
DatabricksFunction(function_name="system.ai.python_exec"),
]
mlflow.set_registry_uri("databricks-uc")
logged_agent_info = mlflow.pyfunc.log_model(
artifact_path="agent",
python_model="quickstart_agent.py",
extra_pip_requirements=[f"databricks-connect=={get_distribution('databricks-connect').version}"],
resources=resources,
registered_model_name=registered_model_name
)
Deploy the agent
Deploy your registered agent to a serving endpoint:
from databricks import agents
deployment_info = agents.deploy(
model_name=registered_model_name, model_version=logged_agent_info.registered_model_version
)
After the agent endpoint starts, you can chat with it using AI Playground or share it with stakeholders for feedback.
Next steps
Choose where to go next based on your goals:
Measure and improve your agent’s quality: See Agent Evaluation quickstart.
Build more advanced agents: Create an agent that performs RAG using unstructured data, handles multi-turn conversations, and uses Agent Evaluation to measure quality. See Tutorial: Build, evaluate, and deploy a retrieval agent.
Learn how to build agents using other frameworks: Learn how to build agents using popular libraries like LangGraph, pure Python, and OpenAI. See Use ChatAgent
to author agents