Inspirations

Every app with real users generates a firehose of reviews, most of them repetitive, a few of them genuinely urgent. A support lead reading them by hand tends to skim past the fiftieth "app keeps crashing" complaint, and that's exactly when a real, different problem slips through unnoticed. I wanted an agent that reads every single review individually, never gets bored, and only interrupts a human when there's an actual decision to make.

What it does

ReviewPulse is an autonomous agent, built with the Strands Agents SDK (AWS's open-source Python framework for LLM agents) on AWS Bedrock, that reads customer app reviews and turns thousands of them into a handful of engineering tickets instead of one ticket per review. It runs in the background and stays silent for routine feedback. It only surfaces in two situations: when enough reviews describe the same underlying problem to be worth an engineer's time (it automatically files a Jira ticket, and comments on it later if the cluster keeps growing, instead of ever creating a duplicate), or when it detects a sudden spike in negative reviews that looks like a genuine reputation crisis (it immediately drafts an internal alert and a public holding statement for a human to act on). The headline metric is suppression: a large volume of raw reviews should collapse into a small number of tickets and, ideally, zero-to-one human escalations.

How I built it

ReviewPulse is a five-stage pipeline, deployed on AWS Bedrock AgentCore Runtime:

  1. Ingest - pulls reviews from a review feed (a frozen Google Play export in this build) in bounded chunks, simulating a real incremental poll rather than a one-shot dump.
  2. Triage - a Strands agent (Claude Haiku on Bedrock) classifies every new review's sentiment, category, severity, and feature area as structured output. So the result is a typed object, not free text to parse. Reviews are cached once classified, so nothing is ever billed twice.
  3. Cluster - reviews describing the same issue are grouped for free (pure deterministic grouping, no LLM cost) by feature area and category. A cluster that crosses a size threshold gets a ticket title and description drafted by a Strands agent using Claude Sonnet.
  4. Ticket sync - the drafted ticket is created in a real Jira Cloud project via the REST v3 API. If the same cluster grows, ReviewPulse comments on the existing ticket with the delta instead of ever duplicating it.
  5. Crisis detection - a pure statistical burst-detector (no LLM at all) continuously compares the recent negative-review rate against the historical baseline. The moment it trips, a Strands agent (Claude Sonnet) automatically drafts an escalation for a human.

I also deployed the pipeline a second way: as a production web dashboard (FastAPI, served from AWS Lambda behind a Function URL, with DynamoDB replacing SQLite for persistent, stateless-safe storage across invocations). This is the live, interactive demo, with real-time triage counts, cluster cards, and one-click Jira sync from the browser.

Two Claude tiers are used deliberately: Haiku for the high-volume, low-stakes triage stage; Sonnet reserved for the rare, high-judgment ticket and crisis drafts, where reasoning and calibration matter more than speed.

Challenges I ran into

  • My first data source (a live Apple App Store review RSS feed) throttled aggressively from non-residential IPs, returning HTTP 200 with an empty page indistinguishable from "no new reviews" unless checked for explicitly. I ultimately switched to a frozen, real Google Play review export to keep the demo reproducible and independent of a flaky upstream.

Accomplishments that I'm proud of

  • The full five-stage pipeline is verified end-to-end against real infrastructure, not just automated tests against mocks: real Bedrock triage, real Bedrock Sonnet ticket and crisis drafts, real Jira issue creation against a live project, and a real invocation of the pipeline running on AWS Bedrock AgentCore Runtime.
  • Ticket sync's dedup logic was tested against a genuinely growing cluster in real Jira and correctly created once, then commented on subsequent growth, and no-op'd when nothing changed, never producing a duplicate ticket.

What's next for ReviewPulse

-Wire the AgentCore Runtime deployment to DynamoDB (it currently uses SQLite in /tmp, which resets between invocations) - the web dashboard already made this switch; the AgentCore tick hasn't yet.

  • Wire crisis escalation into a real notification channel (like email) instead of a loud terminal print.
  • Connect a live review API instead of a frozen CSV export, so the agent genuinely runs against an ongoing feed.
  • Run against enough real volume to observe crisis detection trigger naturally, rather than only under a synthetic test burst.

Built With

Share this project:

Updates

Submission history