GuidesUser feedback loop

How to set up a user feedback loop for your application

Once traces are coming in, capturing user feedback is a great next step. Your users judge every response through what they click, edit, retry, or say. Capturing that on your traces gives you a quality signal grounded in real usage, where each score points at a trace you can open and learn from.

A lot of teams ask "I have traces coming in, how do I now get started with evals?". Often, these teams are better off starting with user feedback first.

This feedback gathering step generally has a very high ROI, in the AI Engineering process. We often write about this process in the Langfuse Academy, where we walk through the AI engineering loop in more detail. Gathering user feedback happens in the monitoring stage highlighted below.

Prerequisites

You already have traces coming into Langfuse. See tracing if you have not set this up yet.

Walkthrough

Choose your feedback signals

Feedback comes in two forms. Explicit feedback is a rating the user gives on purpose, like a thumbs up or down or a star rating: unambiguous, but rare and skewed toward unhappy users. Implicit feedback is derived from what users do, like retrying a query or editing a draft: you have data on every trace, but it needs interpretation.

The best signals depend heavily on your use case. Some examples as inspiration:

SignalWhat it tells youTypically captured via
Thumbs up or down on a responseDirect rating of that responseBrowser SDK
A user rephrasing the same questionThe previous answer didn't landLLM-as-a-Judge
A user asking to speak to a humanThe user stopped trusting the assistantLLM-as-a-Judge
A response copied by the userThe output was good enough to reuseBrowser SDK
A drafted reply edited before it is sentWhat was wrong or missing in the draftSDK / API
A copilot suggestion accepted or dismissedWhether the suggestion fit the contextBrowser SDK
An extracted field corrected in a review stepWhich field was extracted incorrectlySDK / API
A search query reformulated without clicking a resultThe results missed the intentSDK / API
A recommended item skipped right after it startsThe pick missed the user's tasteSDK / API

Tips:

  • signals combine well, no need to implement only one
  • capture free-form text wherever it fits (can be as a comment on the score), as much of this analysis is now done by agents, and they work better with more context
  • the academy examples show how signals are chosen for a specific application and change over its lifecycle

Capture the signals as scores

Every signal ends up as a score on the trace that produced the output. A score has a name, a value with a data type (boolean, numeric, categorical or free text), and an optional comment. Evaluators also store their results as scores, so your user feedback can land in the same filters, dashboards, and analytics.

The route into that score depends on where the signal originates:

Ratings from your UI go straight from the browser using your public key:

import { LangfuseBrowserClient } from "@langfuse/browser";

const langfuse = new LangfuseBrowserClient({
  publicKey: process.env.NEXT_PUBLIC_LANGFUSE_PUBLIC_KEY!,
});

// On a thumbs up / down click
await langfuse.score({
  traceId, // returned by your backend with the response
  id: `response_rating-${traceId}`, // stable id, so re-rating updates instead of duplicating
  name: "response_rating", // one descriptive name per signal
  value: 1, // 1 for thumbs up, 0 for thumbs down
  dataType: "BOOLEAN",
});

The User Feedback page has the full setup for a Next.js chatbot, including how the frontend gets the trace ID.

Events your app observes, like an accepted suggestion, an edited draft, or a closed ticket, are scored the moment they happen:

from langfuse import get_client

langfuse = get_client()

# The user edited the drafted reply before sending it
langfuse.create_score(
    trace_id=trace_id,  # the trace that produced the draft
    name="draft_edited",
    value=1,
    data_type="BOOLEAN",
    comment=edit_diff,  # the edit itself, as context for later analysis
)
import { LangfuseClient } from "@langfuse/client";

const langfuse = new LangfuseClient();

// The user edited the drafted reply before sending it
await langfuse.score.create({
  traceId, // the trace that produced the draft
  name: "draft_edited",
  value: 1,
  dataType: "BOOLEAN",
  comment: editDiff, // the edit itself, as context for later analysis
});

// Flush the scores in short-lived environments
await langfuse.flush();

See Scores via API/SDK for score types, updating scores, and validating them against a score config.

Signals that live in free text, like a user asking for a human or rephrasing a question, leave no event your code can catch. An LLM-as-a-Judge evaluator on your production traces reads the conversation and writes the score, with no change to your application.

Act on the feedback

Score analytics and custom dashboards chart how each signal moves over time. One caveat: not every signal is a clean quality metric, e.g. thumbs feedback skews toward unhappy users.

Surface interesting traces

Filter traces by score, for example response_rating = 0, to get a concrete list of traces to investigate. Error analysis is a structured way to read and cluster them, and an annotation queue brings in more reviewers.

Use it as input for structured improvement

Add the failing cases to a dataset, test a fix with an experiment before shipping, and turn a recurring failure mode into an automated evaluator that scores every production trace from then on.

Much of this can also be handed to an agent, see Let an agent act on the feedback below.

Let an agent act on the feedback

Langfuse is built for agent access through the Langfuse CLI, the Agent Skill, and the MCP Server: point one at your project and it can interpret and act on the behavior that gets surfaced via user feedback. An example task:

Fetch the traces from the last 7 days with a response_rating score of 0.
Read the comments and outputs, cluster the failures into categories,
and propose a prompt change for the two biggest ones.

Some reading material as inspiration:


Was this page helpful?

Last edited