Lead Agent: Inbound Qualification Workflow

Lead Agent: Inbound Qualification Workflow

A running deployment of the lead-agent reference architecture published by Vercel Labs. A contact form starts a durable workflow that runs a research agent over the submitted lead, categorises it with a structured-output call, drafts a personalised reply, then posts that draft to Slack with approve and reject buttons and blocks until a person answers. The interesting part is the shape rather than the form: an agent that pauses mid-run for human judgement and survives the wait.

This is Vercel Labs' lead-agent reference architecture, deployed and being adapted. The architecture and the code are theirs. What is mine is the deployment and the reading of it.

Why this one is worth deploying

Most agent demos run start to finish and hand you a result. This one stops in the middle.

A lead comes in through the form. A workflow starts, a research agent works the lead, a structured-output call categorises it, and a draft reply gets written. Then it posts that draft into Slack with approve and reject buttons, and stops. Nothing is sent until a person presses one.

That pause is the part worth studying. Holding a request open across a human decision does not work, so the run has to be durable: it survives the wait, wakes on a Slack webhook, and carries on. The Workflow SDK is what makes the pause survivable, and the pattern generalises well past lead handling.

The shape

form submit
    ↓
start(workflow)          durable execution
    ↓
research agent           AI SDK Agent, tool-using
    ↓
qualify                  generateObject, category + reasoning
    ↓
draft reply              generateText
    ↓
Slack approval           blocks here, indefinitely
    ↓
send, on approval only

Qualification returns a category and the reasoning behind it in one structured call, so the decision is auditable rather than a label with nothing behind it. That detail is easy to skip and it is the difference between a classifier you can debug and one you cannot.

What is not finished

The template ships deliberate placeholders, and they are still placeholders here. queryKnowledgeBase returns a fixed string:

execute: async ({ query }) => {
  // ex: pull from turbopuffer, pinecone, postgres, snowflake, etc.
  return 'Context from knowledge base for the given query';
}

Vercel says as much in the README: fill in lib/services.ts to make it yours. Pointing it at a real knowledge base and a real CRM is the work, and until that happens this is a reference architecture running, not a product.

Project stack

More projects