Feedback Agent
Collect feedback and turn it into actionable insights. Feedback Agent helps you understand user needs faster and improve your product quickly — right inside your app.
How to Enable Feedback Agent
To enable Feedback Agent in Navigation SDK, follow these steps:
For new projects you may need to follow the Navigation "Get Started" guide to configure your Mapbox access token and project settings.
Step 1: Add the dependency
Add the following dependencies to your Xcode Package Dependencies or Package.swift
dependencies: [
.package(url: "https://github.com/mapbox/mapbox-navigation-ios.git", exact: 3.17.0),
.package(url: "https://github.com/mapbox/mapbox-mapgpt-ios.git", exact: 3.17.0-alpha.1),
],
Step 2: Instantiate MapGptSession
To integrate Feedback Agent with the Navigation SDK, you need to instantiate a MapGptSession and provide it with a Recorder object and a MapboxNavigationProvider.eventsManager object.
import MapboxCommon
import SwiftUI
import MapboxMapGpt
import MapboxNavigationCore
@main
struct MapGptExampleApp: App {
init() {
let localRecorder = Recorder()
self._recorder = StateObject(wrappedValue: localRecorder)
self.navigationProvider = MapboxNavigationProvider(coreConfig: CoreConfig())
let eventsManager = navigationProvider.eventsManager
self._gptSession = StateObject(
wrappedValue: MapGptSession(
eventsManager: eventsManager(),
recorder: localRecorder
)
)
}
var navigationProvider: MapboxNavigationProvider
@StateObject var recorder: Recorder
@StateObject var gptSession: MapGptSession
var body: some Scene {
WindowGroup {
TabView {
ExampleContentView(mapGptSession: gptSession)
.tabItem {
Label("MapGpt", systemImage: "message.badge.waveform")
}
}
}
}
}
Step 3: Provide MapGptSession to VoiceFeedbackView
Now you can create a view that will present VoiceFeedbackView in a sheet to use the MapGptSession Feedback Agent pre-built UI:
import AVFoundation
import Combine
import CoreLocation
import CoreLocationUI
import MapboxCommon
import MapboxMapGpt
import MapboxMapGptUI
import MapboxNavigationCore
import SwiftUI
struct ExampleContentView: View {
@StateObject var locationManager = LocationManager()
@ObservedObject var mapGptSession: MapGptSession
@State var showFeedbackAgentSheet: Bool = false
@State var sessionStatusDescription = "_"
var body: some View {
VStack(spacing: 20) {
LocationButton {
locationManager.setup()
}
.foregroundStyle(Color(.systemBackground))
.clipShape(RoundedRectangle(cornerRadius: 10))
.overlay(alignment: .trailing) {
if locationManager.loading {
ProgressView()
.offset(x: 26)
}
}
Text(sessionStatusDescription)
HStack {
Text("State:")
Spacer()
Text(mapGptSession.state.display)
}
.padding(.horizontal)
VStack {
Button("Present Feedback Agent sheet") {
showFeedbackAgentSheet = true
}
}
.disabled(!mapGptSession.ready)
Spacer()
List {
ForEach(mapGptSession.transcriptContents, id: \.hashValue) { transcript in
Text(transcript)
}
}
}
.sheet(isPresented: $showFeedbackAgentSheet) {
VoiceFeedbackView(
sessionObserver: mapGptSession
) {
showFeedbackAgentSheet = false
} completion: { result in
showFeedbackAgentSheet = false
// Note: Result<UUID, Error> will contain the feedback ID
}
}
.onChange(of: locationManager.currentLocation) { newValue in
mapGptSession.userContext = Context(
location: newValue
)
}
}
}
class LocationManager: NSObject, ObservableObject {
private(set) var manager = CLLocationManager()
@Published var currentLocation: CLLocation?
@Published var loading: Bool = false
func setup() {
manager.delegate = self
updateLocation()
}
func updateLocation() {
if manager.authorizationStatus == .authorizedWhenInUse || manager.authorizationStatus == .authorizedAlways {
loading = true
manager.requestLocation()
}
}
}
extension LocationManager: CLLocationManagerDelegate {
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
updateLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
currentLocation = locations.first
loading = false
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: any Error) {}
}
Step 4: Get the Feedback ID for an item
The Feedback SDK automatically generates a feedback ID for every feedback item. You can optionally track this value to close the feedback loop with your users and notify them when one of their items has been closed, for example. For more information, see Closing the Feedback Loop.
VoiceFeedbackView(
sessionObserver: mapGptSession
) {
showFeedbackAgentSheet = false
} completion: { result in
showFeedbackAgentSheet = false
// Note: Result<UUID, Error> will contain the feedback ID
switch result {
case .success(let feedbackItemIdentifier):
sessionStatusDescription = "Succeeded reporting \(feedbackItemIdentifier)"
case .failure(let error):
sessionStatusDescription = "Failed to report feedback due to \(error)"
}
}
Step 5: Add a microphone usage description
Your Info.plist will need to have a NSMicrophoneUsageDescription key value pair to explain all the ways that your application uses the microphone including for Feedback Agent.
Feedback Explorer
The Feedback Explorer inside the Mapbox Console is the easiest mechanism to visualize the items from the users in your application:
Tapping on a feedback item will give you all the details, including a map with the location of the report:
The Feedback Explorer allows you to:
- Browse all feedback items from users of your application.
- View the category generated by the Feedback Agent (see list below), the date of the item, the transcription, the resolution state, and the location of the item.
- Filter items by date, category, or status (one of
open,acknowledged,fixed,unreproducible,unactionable,unsupported). - Tap on an individual item to get all its information, including a map of the location of the item.
Default Categories
By default, Feedback Agent provides a set of default categories for location-related items:
| Category | Description |
|---|---|
alternative_route_issue | To report wrong or missing alternative route. |
banner_issue | Problems with the given banners. |
eta_issue | Problems with ETA quality. |
false_negative_traffic_issue | When a user reports traffic congestion or delays (e.g., traffic jams or traffic build up) |
false_positive_traffic_issue | When a user reports traffic is flowing smoothly and there's no congestion |
guidance_issue | Problems with the given guidance. |
illegal_entrance | When a suggested entrance is illegal. |
illegal_turn | When a suggested turn is illegal. |
lane_guidance_issue | Issues specifically around lane guidance or details about the road as displayed on the map. |
map_data_issue | Problems with map features and functionality. |
map_rendering_issue | Problems with map rendering. |
missing_expected_maneuver | When a legal turn is not suggested. |
no_route | When a route is not built. |
poi_closed | When a user reports that a place on the map or navigation no longer exists. |
poi_details | When a user reports that details about a place are incorrect or need to be updated. |
poi_location | When a user reports that location about a place is incorrect. |
poi_missing | Problems with the assistant's ability to find POIs, addresses, or other places. |
police_speed_trap | When a user reports a police speed checkpoint. |
poor_arrival_issue | To report issues with arrival behavior. |
poor_routing_issue | Problems with the given route. |
positioning_issue | Problems with a puck/location of car and matching to the current roads. |
rerouting_recalculation | To report continuous or incorrect rerouting/route recalculation. |
road_closure_issue | When a road is closed temporarily or permanently. |
road_incident_issue | Problems with road incident. |
speed_limit_issue | To report wrong or missing speed limit data. |
traffic_issue | When the user wants to report traffic, congestion or incidents like trash in the road. |
voice_guidance_issue | Problems with the given voice guidance. |
application_issue | Capture issues with application performance, bugs, or errors unrelated to specific navigation features. |
non_feedback | Irrelevant or nonsensical feedback that does not pertain to application functionality or navigation issues. |
Mapbox will automatically triage and act on these items on your behalf to improve the underlying data based on items from users of your application.
Custom Categories
Besides the default categories mentioned above, Feedback Agent provides a generic application_issue category to capture issues with application performance, bugs, or errors unrelated to specific navigation features.
If you need more fine-grained application-related categories, you can also define your own. For example, a food delivery application might want to collect specific information about food_packaging.
For more information on how to create custom categories, see contact us.
Closing the Feedback Loop
When using Feedback Agent you can close the feedback loop with the user that submitted an item, by notifying them that their feedback has been received and its current status. At a high level, the process will be as follows:
- Get the
feedbackIdfrom the Feedback SDK. This is a unique identifier string automatically generated by the Feedback SDK. - Store this value in your system associated with a specific logged-in user in your app.
- Use the Mapbox Feedback API to query the status of the item using its
feedbackId. - When the status changes, use a dedicated screen, a push notification, email, or any other relevant mechanism to notify the user.
Feedback API
The Mapbox Feedback API provides a unified, programmatic way to access end user feedback collected from the apps you build with Mapbox.
This API allows you to integrate feedback data directly into your own internal tools and data pipelines, giving you visibility into the issues and suggestions your users provide. You can track the status of feedback items as they are reviewed by Mapbox and get valuable insights about your applications.
In particular, the Feedback API allows querying items by feedbackId to close the feedback loop with your users.
Language Support
During the Public Preview, Feedback Agent supports the following languages:
- English (en-US)
- German (de-DE)
- Spanish (es-ES)
- Japanese (ja-JP)
Other languages and locales are accepted, but recognition accuracy and classification quality may vary. If your use case requires support for languages not in this list, contact us.
Pricing Information
Feedback Agent is free during the Public Preview, including access to Feedback Explorer and the Feedback API.
At General Availability, customers using Feedback Agent will incur a charge of $0.02 per feedback item, with data retained only for a limited period. This charge includes access to Feedback Explorer and the Feedback API.
For custom categories, contractual service level agreements (SLAs) on map and navigation feedback resolution, or advanced reporting, contact us.