Building an AI-Native Feedback System on the AI Cloud
We're open-sourcing GTM Feedback, an internal AI-powered system that collects customer feedback from Slack and web, triages it into feature requests, and generates daily product insights. The entire system is built on AI SDK, AI Gateway, and Workflow DevKit, and you can deploy it to your own account.
Feedback from the field is one of the highest-signal inputs you can give product teams, but it typically arrives fragmented across Slack threads, sales notes, and screenshots in DMs. Most of it never gets captured as structured, actionable product work. We built this system to fix that, and we're releasing it as a reference architecture for building AI-native applications on the AI Cloud.
Capturing feedback in Slack
The best feedback system is one that doesn't require extra work. When someone reacts to a message or thread with the :gtm-feedback: emoji, the Slack app automatically:
- Pulls the relevant Slack context
- Summarizes the thread into a clear pain description
- Searches for an existing request match, or proposes a new one
- Posts the result back into the thread
For situations where there's no existing thread to reference, the Slack shortcut opens a modal with structured fields (severity, account ID, pain description, links). Submitting the form sends the payload into the same ingestion and triage pipeline.
Daily insights that help PMs prioritize
Traditional feedback dashboards show charts and counts. Our analytics agent goes further by generating a structured report that updates daily with dealbreakers, themes, segment impact, and execution status.
The analytics agent pulls the underlying data, then produces a structured output that the UI renders as a narrative. Product managers can use this directly for prioritization decisions because it explains why certain requests matter, not just how many times they've been mentioned.
Human-in-the-loop for critical decisions
The system routes decisions by confidence, but it doesn't auto-create roadmaps.
Humans stay in control at the critical points:
- Approving creation of new feature requests
- Confirming whether feedback truly matches an existing request
- Closing the loop when something ships
You can add human approval to an AI workflow with two approaches.
- AI SDK's
needsApprovalmarks specific tools as requiring approval before execution - Workflow DevKit hooks pause long-running workflows until a human responds
How it works: The three-layer architecture
The system has three layers:
- Clients capture feedback
- Orchestration coordinates workflows
- Intelligence provides AI capabilities
Clients are the entry points where feedback is captured:
- Slack emoji reaction: React with
:gtm-feedback:on any message to trigger capture - Slack shortcut modal: Open a form directly in Slack for structured feedback
- Web UI: Submit, browse, and manage feedback through a dedicated interface
Orchestration uses Workflow DevKit to coordinate multi-step flows including ingestion, triage, approvals, reporting, and notifications.
Intelligence is a reusable agent.* interface (implemented as multiple ToolLoopAgents under the hood) that powers summarization, matching, proposal generation, analytics reporting, and Slack message composition.
All three clients share the same underlying intelligence layer.
A shared agent.* interface
Instead of spreading prompts and model calls across the codebase, the system exposes a small set of capabilities that any client can call:
agent.slack.*: Extract and summarize threads, compose messages for notifications and DMs, power interactive Slack chat with tool callingagent.request.*: Create request proposals, match feedback to existing requests with confidence scores, find related requestsagent.search.*: Semantic search via candidate gathering and rerankingagent.analytics.*: Generate structured product-area insight reportsagent.identity.*: Resolve identity reliably (for example, email to user match as structured output)
This separation is what makes the system extensible. Slack, web, workflows, and future clients all call the same interface. Each capability is implemented as a focused ToolLoopAgent with a narrow job, structured outputs, and scoped tool access. That composition keeps quality high while keeping each component understandable and replaceable.
// Use the search agent to match customer pain to existing feature requests
const result = await agent.search.generate({ query: customerPain });
return { matches: result.output.matches };
Specialized models per capability, routed through AI Gateway
Different tasks have different requirements: message composition needs speed, complex matching needs reasoning depth, and analytics needs both. AI Gateway lets us choose the best model for each sub-agent, iterate on model choices over time, and get observability into model behavior.
// Create a reusable agent with injected context and tools
function createAgent(context: AnalyticsToolContext) {
return new ToolLoopAgent({
model: claudeSonnet,
tools: analyticsTools,
instructions: ANALYTICS_INSTRUCTIONS,
experimental_context: context,
output: Output.object({ schema: analyticsOutputSchema }),
});
}
Clients don't need to know any of this. Slack, web, and workflows call agent.* and get structured results back. Model iteration stays behind the interface.
What we learned
A few things we learned and iterated on while building GTM Feedback:
- Use human-in-the-loop when the cost of being wrong is high: We route by confidence, but keep humans in control for creating new requests, confirming matches, and closing the loop when something ships.
- Centralize the intelligence layer behind a small interface: Early versions scattered prompts and tool calls across Slack, web, and workflows. Moving to a shared
agent.*surface let us iterate on prompts, models, and tools without touching every client, and kept behavior consistent. - Prefer structured outputs over freeform text: We use typed schemas so the UI can render reports deterministically and workflows can branch on confidence scores or specific fields instead of using regex to parse prose.
Extending the system for your use case
The repository is designed for extension:
- Add a new client (email, Zendesk, Linear, CRM) by reusing the
agent.*interface - Add a new capability by introducing another specialized sub-agent with a typed output schema
- Swap models per capability via AI Gateway without touching clients
- Evolve tools and adapters while keeping the interface stable
Why we're open-sourcing this
We built this system to solve our own problem, but the architecture patterns are useful beyond GTM feedback. By open-sourcing it, we're providing a reference implementation that shows how to compose AI SDK, AI Gateway, and Workflow DevKit into a production system.
This is how we build AI-native applications at Vercel. We're sharing it so you can see the patterns, adapt them for your use case, and build on top of the same primitives.
Ready to build your own? Deploy this template and start capturing feedback in minutes. The full source code is available so you can customize it for your team's workflow.