Skip to content
← Back to all pipelines

Feedback Analyzer

Aggregate an array of customer reviews → per-review sentiment + themes + score → roll up distribution + top themes → suggest concrete action items.

v1.0.0CompositionVerified
sentimentthemesstructured-output
Setup — API key

Set one of these env vars before running locally. The CLI resolves $VAR via env-var substitution.

shell · bash
# Choose ONE provider
export MINIMAX_API_KEY="sk-..."      # default provider for these pipelines
# OR
export OPENROUTER_API_KEY="sk-..."  # OpenRouter (multi-model gateway)

Pipeline YAMLs use ${VAR:-default} syntax; runtime reads fromprocess.env at parse time. agentsmarket pipeline call returns a clear error if no key is found.

Install

Downloads Pipeline.yaml. R16 stub — server route pending.

CLI · bash
agentsmarket pipeline install feedback-analyzer
Run locally

Executes the pipeline via the local CLI runtime. Use --mock for a dry-run (no API key needed).

CLI · bash
# Dry-run (no API key needed)
agentsmarket pipeline call feedback-analyzer --local --mock

# Real run (uses one of MINIMAX_API_KEY / OPENROUTER_API_KEY)
agentsmarket pipeline call feedback-analyzer --local

Inputs are passed via --inputs '<JSON>' or read from~/.config/agentsmarket/pipelines/feedback-analyzer/inputs.json. See the pipeline YAML below for the input schema.

Pipeline YAML

Verbatim copy of packages/pipeline-runtime/pipelines/feedback-analyzer.yaml. Verified end-to-end against mock LLM provider.

pipeline.yaml · yaml
# feedback-analyzer — aggregates customer reviews into sentiment + themes + action items.
#
# Demonstrates: array inputs over many items (per-stage iteration),
# structured_json output_format with nested fields, `uses:` skill at the
# final aggregation stage, mcp_servers forward-compat declaration.
#
# Run locally:  agentsmarket run pipelines/feedback-analyzer.yaml --mock
name: feedback-analyzer
version: 1.0.0
description: Aggregate an array of customer reviews → per-review sentiment + themes + score → roll up distribution + top themes → suggest concrete action items.
author_id: 0xYourAddress
license: MIT

inputs:
  reviews:
    type: array
    required: true
    items: { type: string, description: "One customer review (free text)" }
  product_name:
    type: string
    required: false
    default: my-product

outputs:
  summary:
    format: structured_json
    description: "Aggregated feedback report with sentiment distribution, top themes, and action items"
    fields: [distribution, top_themes, actions]

defaults:
  model: MiniMax-M3

stages:
  - id: per_review
    provider: minimax
    system: ${FOCUS_AREA:-You analyze customer reviews for overall satisfaction, themes, and concrete improvement signals.}
    prompt: |
      Analyze the following list of customer reviews for product `{{product_name}}`.

      Output a JSON object with shape: `{"items": [<each review as object>]}`
      Each item must have exactly these fields:
        - `index` (0-based position in the input array)
        - `sentiment` (positive | neutral | negative)
        - `score` (1-5)
        - `themes` (array of ≤3 short tags, e.g. `["pricing","onboarding"]`)
        - `one_liner` (≤100 chars summary)

      Reply with valid JSON only. No prose, no markdown fences.

      Reviews (one per line):
      ```
      $input.reviews
      ```
    output_format: structured_json
    fields:
      - "items[*].index"
      - "items[*].sentiment"
      - "items[*].score"
      - "items[*].themes"
      - "items[*].one_liner"
    mcp_servers: [posthog, sentry]
    mcp_tools: [posthog_read_funnel, sentry_list_issues]

  - id: aggregate
    provider: minimax
    depends_on: [per_review]
    prompt: |
      Compute aggregated feedback report for product `{{product_name}}`.
      Output a JSON object with exactly these three fields:
        - `distribution` = { positive: n, neutral: n, negative: n, total: n, avg_score: float }
        - `top_themes` = array of {theme, count} sorted by count desc, ≤10 entries
        - `actions` = array of concrete, prioritized next-step actions (≤5 strings, each ≤120 chars)

      Reply with valid JSON only. No prose, no markdown fences.

      Per-review data: $stages.per_review.output
    output_format: structured_json
    fields: [distribution, top_themes, actions]

  - id: action_items
    depends_on: [aggregate]
    uses: action_extractor@1.0.0
    input:
      summary: $stages.aggregate.output
      context: 'priority = high if low avg_score, medium if negative >= 30%, low otherwise'
    output_format: text

  - id: writeup
    provider: minimax
    depends_on: [aggregate, action_items]
    prompt: |
      Compose a Markdown report for the product team:

        # {{product_name}} — Feedback Pulse
        ## Sentiment
        <one paragraph using distribution + avg_score>
        ## Top Themes
        <bulleted list of top_themes>
        ## Recommended Actions
        <numbered list — merge aggregated `actions` with extracted action_items,
        dedupe, prioritize>

      Aggregated: $stages.aggregate.output
      Extracted: $stages.action_items.output
    output_format: text
Verification evidence

How do we know this pipeline actually runs?

Each pipeline in this catalog is gated by packages/pipeline-runtime/tests/examples-execution.test.ts— a mock-provider end-to-end test that runs the actual YAML through the real runPipelineV2 executor and asserts every stage produces output. The CI test suite reports results on every push.

What the test verifies:

  • YAML parses + has valid name/version/stages array
  • Every stage declares a non-empty id
  • All stage IDs are unique
  • runPipelineV2 executes without throwing
  • Every stage produces an output
  • Mock provider is called at least once per model stage
  • structured_json stages declare a non-empty fields array
  • Pipeline version pin enforcement (uses: foo@1.0.0 returns matching version)
Run it yourself

From the repo root:

shell · bash
pnpm --filter @agentsmarket/pipeline-runtime test examples-execution

# Expected: 16 tests pass (1 file × 16 it() blocks)
Author

by agents-market-demo