B Blengi docs

Improve your agent

Response feedback

Every reply your agent gives carries a quiet thumbs-up / thumbs-down under it in the chat widget. Ratings land on the agent's Response feedback page at /app/agents/{agent}/feedback, where a thumbs-down is broken down by what kind of wrong it was — which is what tells you whether to fix the knowledge base or the crawl.

This is the visitor-driven half of the self-improvement loop. Content gaps catch the questions your agent knew it couldn't answer; response feedback catches the ones it answered confidently and wrongly — the failures no automatic detector can see.

What the visitor sees

  • Two muted thumb icons appear under each finished assistant reply. They never appear on a reply that is still streaming, on an error bubble, or on a message typed by a human operator.
  • Thumbs up submits immediately and collapses to a short "Thanks for your feedback!" line.
  • Thumbs down also submits immediately, and then opens a small form: four reason chips (Not correct, Not what I asked, Incomplete, Something else) plus an optional free-text box.

The order matters. Most visitors abandon a feedback form, so the negative rating is recorded before we ask why — a rating you hold beats a reason you never get. Each later interaction (picking a chip, sending a comment) updates the same record rather than creating another one.

The endpoint

POST /api/v1/widget/messages/feedback, authenticated by the widget JWT like every other visitor endpoint, rate-limited to 120 requests per minute per visitor session.

{
  "message_id": "0198e4...",     // the assistant message being rated
  "rating": "negative",           // positive | negative
  "reason": "incorrect",          // optional: incorrect | irrelevant | incomplete | other
  "comment": "It only goes to 46.",  // optional, max 2000 chars
  "page_url": "https://example.com/boston"
}

The conversation is read from the signed token, never from the request body, and the message must belong to that conversation — so a visitor can only ever rate a reply from their own thread. An unknown message id returns 404 message_not_found.

It is not on the hot path. The rating is its own request; nothing in the SSE stream waits on it, and a failed POST is swallowed by the widget rather than surfaced as an error.

Where the message id comes from

The stream's start event already carries the server's message_id, emitted before the first token. The widget binds it to the bubble as it streams, so the feedback control has a real id by the time the reply finishes. Replies restored from history on a page reload carry their id already, so older turns can be rated too.

What is stored

One row per rated message in message_feedback, scoped to the agent (and therefore the workspace) and holding:

  • the rating, the reason category, and the visitor's comment;
  • snapshots of both the question and the answer — the record has to stay readable after the conversation is pruned, since "this exact answer was wrong" is worthless once the text is gone;
  • the page the visitor was on, and the conversation id for the deep link.

message_id is unique, so a visitor who changes their mind updates their existing row instead of stacking duplicates.

Reading the page

  • Headline stats — total ratings, helpful, not helpful, and the negative rate, with the change against the previous window of the same length. These always follow the date window and ignore the rating / reason pills, so the rate stays meaningful while you filter.
  • Why visitors were unhappy — the reason breakdown, and the fastest diagnosis on the page. A rising Not correct means the knowledge base holds something wrong; a rising Incomplete usually means a page was never crawled. Click a category to filter to it.
  • The list — question, answer, reason, comment and page for each rating, newest first, capped at 100 rows. Defaults to negatives only, because those are the ones that need work.

Closing the loop

Each negative row offers Write a curated answer, which opens the agent's curated-answer form with the failed question pre-filled. Save it and the next visitor who asks that question gets the pinned answer instead of the LLM — the same path Content gaps uses to turn a complaint into a fix.

There is deliberately no email per bad rating: gap notifications already cover the "something needs attention" signal, and one alert per thumbs-down would be noise. The page is the weekly read.