# Build an AI Agent to collect map-based fleet safety feedback

A key to succeed when building AI Agents (not just in CARTO) is to give them a very specific mission, with clear instructions and tools to achieve it.

In this exercise, you’ll achieve that by creating an Agent that helps fleet managers, safety analysts, and other operators **submit precise, location-based feedback back to their systems** using the vehicle data available in the interactive map. Let’s get started!

{% hint style="success" %}
Make sure your organization has enabled CARTO AI before starting this tutorial
{% endhint %}

{% stepper %}
{% step %}

### Create your interactive fleet safety map

To begin, open CARTO and click on «Create Map» or «New Map» if you're in the Maps Section. Once you're inside your new Builder map, do the following:

* Give this title to your map: `Fleet Safety & Operational Map Reporting`
* **Create an area of interest** using this SQL query in a new source. Name your new source `area_of_interest`. This will frame our map in a specific New York city area:

{% code overflow="wrap" %}

```sql
SELECT ST_GEOGFROMTEXT('POLYGON((-74.05572433530303 40.83699883356528, -74.05572433530303 40.693995875776984, -73.87821900799537 40.693995875776984, -73.87821900799537 40.83699883356528, -74.05572433530303 40.83699883356528))') as geom
```

{% endcode %}

* Style your new layer: remove the *Fill* attribute and make sure to use a light-colored *Stroke* that will contrast later with the vehicle data. We named this layer `Area of Interest` .

<figure><img src="https://3015558743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFEElAdsRIl9DzfMhbRlB%2Fuploads%2FbG9IfXe0rsR7Q23YU19y%2FScreenshot%202025-10-07%20at%2019.10.44.png?alt=media&#x26;token=ce085787-aae1-4f90-89f2-7ca6175870a3" alt=""><figcaption></figcaption></figure>

* **Let's now add our road network data:** create a new source (name it `road_network`) using the following SQL query:

```sql
SELECT * FROM `cartobq.docs.ny_incidents_network_agent_tutorial`
```

* Style your new road network using a darker color. We named this layer `Roads` :

<figure><img src="https://3015558743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFEElAdsRIl9DzfMhbRlB%2Fuploads%2F4hcuIqw6EdVVC0BVXsSK%2FScreenshot%202025-10-07%20at%2019.14.05.png?alt=media&#x26;token=1c054042-0029-466f-b33c-90ffe250776e" alt=""><figcaption></figcaption></figure>

* **To finish adding data, let's add our vehicle collisions:** add a new source (name it `transportation_incidents_ny`)to your map with the following SQL query:

```sql
SELECT * FROM `cartobq.docs.ny_incidents_data_agent_tutorial`
```

* Style your collision point-based dataset using a fixed *Radius* (we used roughly 4px) and simple colors for your *Fill* and *Stroke* attributes. In our own map we chose blue and white respectively. Lastly, our name for this layer is `Incidents` .

<figure><img src="https://3015558743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFEElAdsRIl9DzfMhbRlB%2Fuploads%2F8QLf0YaA56JFH6zlTCdR%2FScreenshot%202025-10-07%20at%2019.16.09.png?alt=media&#x26;token=125cd14a-fe58-4751-904b-8b1a0b7f474b" alt=""><figcaption></figcaption></figure>

* **Let's now add helpful click tooltips to our road and collision layers:** Click on the Interactions tab and make sure *Click* interactions are enabled for both *Roads* and *Incidents*. Add the relevant columns and modify the tooltip column names for a polished result.

<figure><img src="https://3015558743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFEElAdsRIl9DzfMhbRlB%2Fuploads%2F4vjMG1mAE9QAjSWylS9S%2FScreenshot%202025-10-07%20at%2019.19.17.png?alt=media&#x26;token=dea9d78c-ae97-4ddb-b418-d03176676393" alt=""><figcaption></figcaption></figure>

* **Our map is ready!** It should be a basic-yet-informative vehicle incident dashboard at this point. Our next step is to add an AI agent that will collect feedback from safety analysts.
  {% endstep %}

{% step %}

### Add an AI Agent to the map

Let's build our AI Agent. To do that, open the *AI Agents* tab in the top-left menu and click on *Create Agent:*

<figure><img src="https://3015558743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFEElAdsRIl9DzfMhbRlB%2Fuploads%2FJv7UUBFT3By2u2w1ewLy%2FScreenshot%202025-10-07%20at%2019.20.54.png?alt=media&#x26;token=e18ed098-bd21-4676-9b41-9cb36a10521f" alt=""><figcaption></figcaption></figure>

A menu will appear where you can configure your AI Agent. Our next step is to **give our agent a clear mission.** To do that, copy and paste this into the *Use Case section.*

{% code overflow="wrap" %}

```
This agent assists fleet managers, safety analysts, and operators in debugging vehicle trajectory data and improving operational maps. The user's goal is to review existing AV incident data overlaid with road network information on the map, identify discrepancies or errors, and provide precise, location-based feedback. The agent's role is to facilitate the submission of this feedback.
```

{% endcode %}

<figure><img src="https://3015558743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFEElAdsRIl9DzfMhbRlB%2Fuploads%2FP0vHBvL9zBiiJ5ErLeT4%2FScreenshot%202025-10-07%20at%2019.21.58.png?alt=media&#x26;token=e53093af-a99a-4c4a-b63e-cffa334291d9" alt=""><figcaption></figcaption></figure>

Click on *Create Agent* to save your changes. You’ll see it listed in the left panel and you can chat with your new agent in Testing mode.

{% hint style="warning" %}
At this point our agent is incomplete, until we provide it with further instructions, and add the MCP tools (workflows) for feedback reporting.
{% endhint %}
{% endstep %}

{% step %}

### Get and finalize the workflow for feedback reporting

Great news! This step will be very easy because we've prepared the workflow for you. Download the workflow as a .sql file and import it in your CARTO Workspace:

<https://storage.googleapis.com/carto-workflows-examples/files/academy_fleet_safety_feedback_mcp_tool.sql>

This workflow enables the Agent to correctly submit feedback using a series of simple steps:

* First, it retrieves the required input parameters
* Then, it validates the inputs (non-null feedback, valid WKT, etc.)
* It generates a unique identifier for each feedback
* Lastly, it appends the new feedback to a specific table in the data warehouse

<figure><img src="https://3015558743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFEElAdsRIl9DzfMhbRlB%2Fuploads%2F1aTJBrtGtoWqREFEYquV%2FScreenshot%202025-10-07%20at%2019.31.49.png?alt=media&#x26;token=e9c701b7-57ff-480e-9668-45063fb9bf2b" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Add a Save as Table component

In order for the agent to submit the feedback, you need to specify which table it will append the feedback to. Add a **Save as Table component**, specify your desired location, and make sure you select the **Append to existing table** option, so that new feedback doesn't override the existing data. Connect your component to the output of the *Generate UUID* component.

<figure><img src="https://3015558743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFEElAdsRIl9DzfMhbRlB%2Fuploads%2FRQOolHaogFQswKvFQg9A%2FScreenshot%202025-10-07%20at%2019.33.17.png?alt=media&#x26;token=1e0b74c4-8bf2-4313-acd4-aecd38ee6b12" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Add the MCP Tool Output (Sync) component to your workflow

A requisite for the AI Agent to be able to invoke this workflow is to **enable it as a MCP Tool**, by configuring an MCP Tool Output. To do that:

* In the Workflow editor, **add the&#x20;*****MCP Tool Output*****&#x20;component at the end and connect it to the Generate UUID component**.
* Set ***Type = Sync**.* This will make our agent wait for the response of this workflow, which should be pretty quick.

The output of this workflow should be a JSON, including the raw data returned by the workflow and the FQN of the table that contains the feedback. This allows the Agent to visualize the submitted feedback in the map!

<figure><img src="https://3015558743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFEElAdsRIl9DzfMhbRlB%2Fuploads%2FnPNtJgg9yxIonRRmifjW%2FScreenshot%202025-10-07%20at%2019.35.34.png?alt=media&#x26;token=00946b7a-b6cf-4ddd-be53-35a702880c72" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Enable the Workflow as an MCP tool

The *MCP (Model Context Protocol)* standard allows us not only to provide tools for AI Agents, but also to provide context about how and when to use the tools, and how to fill the required tool parameters. Let's add that context and enable our workflow as an [MCP tool](https://academy.carto.com/agentic-gis/carto-mcp-server/workflows-as-mcp-tools).

Click on the three-dot menu in the top-right and click on *MCP Tool*, and use the following values to fill in the context for the agent to understand this workflow:

{% tabs %}
{% tab title="Basics > Tool description" %}
{% code overflow="wrap" %}

```
This agent assists fleet managers, safety analysts, and operators in debugging vehicle trajectory data and improving operational maps. It enables users to provide precise, location-based feedback directly on an interactive map.
```

{% endcode %}
{% endtab %}

{% tab title="Inputs" %}

* `location`:

```
Geographic coordinates in Well-Known Text (WKT) format representing the location of the reported issue. Must be a valid POINT or POLYGON geometry.
```

* `feedback_text`:

```
Detailed description of the observed issue, including context about AV behavior, map discrepancies, or operational problems. Should provide sufficient detail for debugging and resolution.
```

* `timestamp`:

```
UTC timestamp when the feedback observation occurred or when the user initiated the feedback report. Must be in ISO 8601 format.
```

* `user_id` :

```
Unique identifier of the user submitting the feedback, used for tracking purposes.
```

{% endtab %}

{% tab title="Output" %}
{% code overflow="wrap" %}

```
Provides the output results of the submitted feedback.
```

{% endcode %}
{% endtab %}
{% endtabs %}

Once all parameters are filled, click on *Enable as MCP Tool* located at the left bottom corner. Once enabled, the Workflow shows an MCP badge and becomes available to Agents (inside and outside CARTO).

<figure><img src="https://3015558743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFEElAdsRIl9DzfMhbRlB%2Fuploads%2FX4rhZPf0vLmclEurX6Ly%2FScreenshot%202025-10-07%20at%2019.37.05.png?alt=media&#x26;token=df29e8e5-897a-4ed6-a361-eaffa066c819" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Add the MCP tool to your AI Agent

Now we need to **instruct the agent to use our new tool**. To do that:

* Open the `Fleet Safety & Operational Map Reporting` map, and in the AI Agent Configuration dialog, click on ***Show tools*** — You'll see all the MCP tools you have access to.
* **Find your MCP tool**, it should be named like your workflow ("report\_location\_feedback" or similar), and click on *Add*. <mark style="background-color:yellow;">Reload the map if it doesn't appear at first.</mark>
* **Verify that your workflow now appears under MCP Tools**. You can expand the tool to review the description, inputs, and output metadata.

<figure><img src="https://3015558743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFEElAdsRIl9DzfMhbRlB%2Fuploads%2FnNI4E2tlJ2oDHFxggMs9%2FScreenshot%202025-10-07%20at%2019.40.19.png?alt=media&#x26;token=c4399df0-427d-4e50-8537-e57ccb9be65b" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Give instructions to the Agent

To finish our agent, let's give it a prompt with a good structure and examples. This also instructs the agent how and when to use the tools we made available. **Copy and paste this prompt into the&#x20;*****Instructions*****&#x20;panel in your agent.**

{% hint style="success" %}
This is a good prompt template that you can use in your own AI Agents in CARTO. Remember that agents work better with clear and structured instructions
{% endhint %}

{% code overflow="wrap" %}

```markdown
# Core Behavior
- Your primary function is to guide a user to a specific location for review and then capture a clear description of their feedback on the map or incident data. Once the location and feedback are confirmed, you will immediately submit this information using the /Report_location_feedback tool. All other actions are performed only to support this core mission.

# Communication Style
- Adopt a helpful, natural, and slightly conversational tone. Your dialogue should be clear and guide the user through the process smoothly. Follow this checklist: **Acknowledge, Locate, Confirm, Submit, and Inform.**
- Use markdown when possible so users can easily read the provided details.

# The Feedback Submission Flow
1.  **Acknowledge & Locate**: When the user asks to submit feedback, your first action is to use tools to identify the Area of Interest (AOI). The AOI can be an address, coordinates, a drawn region, or the current map viewport. **If an address or coordinates are not provided, automatically use /get_spatial_filter to retrieve the viewport or a drawn region.**
2.  **Confirm Address Location**: If geocoding an address, ask for confirmation in a natural way: "I've marked the location at [Address/Coordinates]. Is this correct?"
3.  **Gather Details & Confirm**: After establishing the location, review the user's message(s) to see if the feedback description and username have already been provided.
    - **Do not ask for information you already have.**
    - If any details are missing, ask only for what is needed (e.g., "I have the feedback text, but I'll need your username to proceed.").
    - Once all three components (location, feedback, username) are gathered, confirm everything in a single message before submitting. For example: "Ok, I will submit the feedback '[User's feedback description]' for username '[username]' at the specified location. Is this correct?"
4.  **Submit**: Upon final confirmation, call the /Report_location_feedback tool. Including all parameters (location, feedback_text, timestamp and user_id)
5.  **Report Status & Inform**: After a successful submission, inform the user and guide them to the result on the map. For example: "Feedback report was successfully submitted. I've added the submitted location and details to the map, which you can inspect by hovering over the new layer. Is there anything else I can help with?"
6. **Render Results and Inform**: After the /Report_location_feedback tool returns a successful result, add a new layer to render the feedback location on the map. Once the layer has been successfully added, inform the user that the process is complete. For example: "Your feedback has been successfully submitted and is now visible on the map. You can inspect the details by hovering over the new layer. Is there anything else I can help with?"
```

{% endcode %}

Once the prompt is added to your agent, click on **Done**.

<figure><img src="https://3015558743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFEElAdsRIl9DzfMhbRlB%2Fuploads%2FdoGvR1aDCx3AsTZGjh30%2FScreenshot%202025-10-07%20at%2019.41.03.png?alt=media&#x26;token=fe14e657-94f6-4cf0-9ef0-d4dbd8b4ebad" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Test your Agent (editor mode)

Let's now **test the agent** using a semi-real case. This will let us know if everything is working correctly including the feedback submission tool, before we expose it to end users:

1. Draw an **Area of Interest**: Use the custom polygon mask tool to mark the area you want to report on.
2. **Tell the Agent to submit some feedback** about this area. Example:\
   `Incidents in this drawn region are due to failing intersection negotiation. Please submit feedback. Username: <your_username>.`
3. The **Agent will now start thinking** and use the available tools/context to:
   1. Retrieve the area of interest (your polygon). It may ask for confirmation.
   2. Invoke the MCP Tool to submit the feedback (with the location, feedback\_text, user\_id and timestamp).
   3. On success, it will add a new layer to the map showing the submitted geometry.&#x20;

      <figure><img src="https://3015558743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFEElAdsRIl9DzfMhbRlB%2Fuploads%2Faz9LWstSHFw5pX2C9jPN%2FScreenshot%202025-10-07%20at%2019.46.07.png?alt=media&#x26;token=3ab4e47f-af6a-4b18-adb3-38bd4b3d9d56" alt=""><figcaption></figcaption></figure>
4. Let's **use the new AI-generated layer to verify the results**: Hover on the new layer to see details about the newly submitted feedback and confirm it matches what you requested (*location, feedback text, timestamp, user*).&#x20;
   {% endstep %}

{% step %}

### Enable your Agent to end-users

Looks like we're ready! Let's now make sure that our agent is prepared and available for viewers of our map.

* Go to *Map settings for viewers* and toggle **AI Agent = ON** as well as the Selection tool.
* Use the *Preview* mode if you want to test the end-user experience.

<figure><img src="https://3015558743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFEElAdsRIl9DzfMhbRlB%2Fuploads%2Fxc0NHpgXBFTtl8hbcNnW%2FScreenshot%202025-10-07%20at%2022.55.29.png?alt=media&#x26;token=1c433c14-c1dc-4f5f-bb10-c5c607eb9d0c" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Share your AI Agent with your organization

* Click on ***Share*** and share your map with others. Make sure to click on ***Publish*** if you make any changes. The published map includes your Agent so end-users can interact with it!
* If you want, copy the link and confirm the Agent can be accessible in Viewer mode.

{% hint style="success" %}
**🎉 Congrats!** Your AI agent is now ready to be shared with your organization.

Fleet safety analysts can use this Agent to report feedback based on what they see in the map, and the Agent will take care of the actual submission, parameter validation and visualizing the results in the map.
{% endhint %}
{% endstep %}
{% endstepper %}

<br>
