Sensors turned inbox noise into sales opportunities.

Sensors turned inbox noise into sales opportunities.

#agentic-ai #aws #aws-competency #bedrock #dynamodb #genai #lambda #serverless #strands-agents
Saar Cohen
June 07, 2026

How Develeap built a serverless sales-intelligence platform on AWS — watching real signals, proposing opportunities, and coaching reps in real time.

Open your inbox on a Monday morning. Forty-seven unread mails. A calendar full of “follow-up” slots. A Drive notification about a doc someone shared with you last Thursday. A Slack DM that says “are we still doing the Tuesday thing?”

Somewhere in there is the deal that closes this quarter. Somewhere else is the conversation that, if you don’t reply within 24 hours, dies quietly.

Every account executive has been there. Every department manager has been there. And the honest truth is that no CRM I’ve ever used solves this — they’re filing cabinets, not partners. So at Develeap we built our own. We called it Sensors.

This is the story of what we shipped, what the numbers look like 6 months in, and what AWS made easy that would have been miserable on anything else.

What Sensors actually does

Sensors is an internal sales-intelligence platform for our own organization — 78 active users across sales, department heads, and engineering leaders, working a pipeline of 249 opportunities across 139 customers and a 73-solution catalog. It does three things:

  1. It watches. Sensors continuously ingests signals from each user’s connected Gmail, Calendar, Drive, and Slack — 14,721 signals in the last 30 days alone — and looks for patterns that suggest a real opportunity. Not “did someone use the word cloud“, but “did this customer’s CTO ask about Datadog pricing in three separate threads this week”.
  2. It proposes. When a pattern crosses confidence thresholds, Sensors writes a draft opportunity — title, customer, suggested solutions from our catalog, primary signal source — and drops it into the right department’s pipeline. A human qualifies it (or doesn’t).
  3. It coaches. Once an opportunity is live, our multi-agent assistant — “The Owl” — answers questions about it, drafts follow-up emails, pulls the customer’s tech stack, and recommends adjacent solutions from the knowledge base. All grounded in real catalog content, all streaming live in the browser.
sensors.develeap.com
Opportunities dashboard. The Develeap pipeline as Sensors shows it. The “Auto” badge on a row means it was created by the detector; clicking it opens the side panel with the AI agent ready to coach.

The whole thing runs on AWS, fully serverless, in a single region. The pilot footprint is around $8k–$15k ARR. We have not yet had to talk to anyone about provisioning a Kubernetes cluster, which is a sentence I do not often get to write.

The challenge: why we couldn’t just use a normal CRM

Three problems compounded each other:

Solution-knowledge fragmentation. Develeap maintains 73 distinct solutions across 7 departments — AWS, AI Engineering, FinOps, Data, DevOps & AI, ISV (Grafana, Datadog, CloudBees, Auditty, n8n…), and Education. Every solution has its own overview, pricing model, and use-cases written by the department that owns it. A senior AE knew which one fit which conversation. A new AE didn’t, and there was no system that would tell them.

Per-touchpoint context cost. Before any meaningful next step — a follow-up email, a quote, an upsell — a rep would spend 15-30 minutes assembling context. Who’s the contact? What’s their tech stack? Did we already pitch them Datadog three months ago? What did they push back on? That cost scaled linearly with pipeline volume, and our pipeline doesn’t get smaller.

Static recommendations. The pre-AI version of Sensors had a rule engine. Same suggestions for opportunities with the same numeric score. It didn’t know that Customer A had already bought Auditty and Customer B’s CTO had publicly written a blog post calling Datadog “overpriced”. It couldn’t, structurally.

We could buy something. We chose to build, partly because we’re an AWS Premier Partner and this is exactly the kind of thing we sell to customers, and partly because if we wouldn’t trust a vendor with our pipeline data, neither would they.

What we built

Sensors is a serverless AWS-native multi-tier app in us-east-1:

                ┌────────────────┐
   Browser ───▶ │  CloudFront    │ ─── S3 (Next.js static export)
                │  + WAF + ACM   │
                └────────────────┘
                        │
                        ▼ HTTPS + Cognito ID token
                ┌────────────────┐       ┌──────────────────────────┐
                │  API Gateway   │ ───▶  │  Lambda (5 domain        │
                │  (REST)        │       │  handlers: users,        │
                └────────────────┘       │  customers, opportunities,│
                                         │  departments, analytics) │
                                         └────────────┬─────────────┘
                                                      │
                                                      ▼
                                              DynamoDB single-table
                                              (sensors-main-prod)
                                                      ▲
                                                      │
   Browser ───▶ Lambda Function URL ──▶ Strands Agent ─┤
   (SSE)        RESPONSE_STREAM         │              │
                                        ▼              │
                              Bedrock Claude Sonnet 4  │
                                        +              │
                              Bedrock Knowledge Base ──┘
                              (TIEW1QMHHH, 73 solutions × 3 md files)

The pieces that matter:

  • Frontend: Next.js 16 static export on S3 + CloudFront + ACM + AWS WAF. No SSR, no server runtime — the bundle is static, auth is a Cognito-issued ID token in localStorage.
  • Backend (sync): API Gateway REST → five domain Lambdas (Node.js 20) → DynamoDB single-table with GSI1 (by customer) and GSI2 (by stage). Everything pay-per-invocation; nothing idles.
  • AI tier (streaming): A dedicated Lambda Function URL with RESPONSE_STREAM invoke mode hosts the multi-tool agent. The browser opens an SSE connection, the agent calls tools, each tool result streams back as it arrives.
  • The agent itself: built on AWS Strands Agents, the AWS-aligned open-source framework for multi-tool agentic systems. Eight tools, one sub-agent. The agent reasons over which tool to call; we don’t route by hand.
// Simplified — the actual handler is ~400 lines
const agent = new Agent({
  model: new BedrockModel({
    modelId: "us.anthropic.claude-sonnet-4-20250514-v1:0",
    region: "us-east-1",
    invokeMode: "RESPONSE_STREAM",
  }),
  tools: [
    queryOpportunities,
    queryCustomers,
    queryDepartments,
    queryAnalytics,
    searchIntegrations,        // Slack / Gmail / Calendar / Drive
    searchSolutionKnowledge,   // Bedrock KB Retrieve
    recommendSolutions,        // KB + catalog cross-check
    marketResearcher,          // sub-agent w/ Tavily web search
  ],
  hooks: [new MaxTurnsHook(15)],
  conversationHistory: await loadConversation(conversationId),
});

for await (const event of agent.stream(userMessage)) {
  if (event.type === "modelContentBlockDeltaEvent") {
    writeSSE(res, "delta", event.delta.text);
  }
  if (event.type === "afterToolCallEvent") {
    writeSSE(res, "tool", { name: event.toolName, durationMs: event.duration });
  }
}

The MaxTurnsHook(15) is the small but important detail — it caps how many tool calls the agent can chain before the answer must be returned. We learned to set it the hard way. The first version had no cap; one user asked “tell me everything about our Cellebrite relationship” and the agent spent $4 in Bedrock tokens before timing out. We now bound everything.

  • Knowledge Base: Amazon Bedrock Knowledge Base TIEW1QMHHH. The KB ingests 73 markdown files × 3 sections (overview.md, pricing.md, use-cases.md) from a single S3 bucket. Ingestion is event-driven — an S3 PUT triggers a Lambda that calls StartIngestionJob. There is no vector database we manage. There is no OpenSearch cluster. We have not paged anyone at 3am about a vector index. This is the most underrated feature of Bedrock KB.

How qualification actually works

This is the part the AWS Competency reviewers want to read, and it’s also the part Develeap leadership cares most about.

When a signal arrives — a new email, a calendar invite, a Drive share — it’s routed by source-specific Lambda pollers (gmail-poller, calendar-poller, drive-poller, slack-poller) running daily at 06:15–06:45 UTC. Each cleans, dedupes, and writes the signal into sensors-signals-prod with a hot-score, intent-score, and context-score.

At 07:00 UTC, the detector wakes up. It does 8 phases:

  1. Fetch signals from the last window
  2. Group by user × external domain (so Gmail conversations with acme.com cluster together)
  3. Filter internal domains, suspicious TLDs, Drive-share GUIDs (the kind of thing that wouldn’t be an opportunity)
  4. Haiku-classify each group cheaply, to drop the obvious noise before paying for Sonnet
  5. Vector-match the surviving groups against the Bedrock KB to pre-shortlist candidate solutions
  6. Reason the high-confidence ones via Claude Sonnet 4 — does this group actually represent buying intent? If yes, which solutions? With what confidence? (The reasoner has a validation checklist: is this a real company, is the buying-intent specific, is this a new need, is there pain–solution fit?)
  7. Dedup against opportunities that already exist for this customer + solution combo, across all active stages — same customer + same solution = skip; same customer + different solution = allowed (different need)
  8. Auto-create the opportunity record + OppSolution children with detectionSource: "auto" and a detectionConfidence score

Six months in, the numbers look like this:

MetricValue
Auto-detected opportunities (lifetime)101
Manually created opportunities148
Qualification rate of auto-detected opps31.5% (of those decided)
Median time from auto-detection to decision25 hours
Detection confidence (median, auto opps)72%
Signals ingested in last 30 days14,721
AI assistant conversation turns (prod)103 (early days)

That 31.5% qualification rate is the one I usually have to defend in conversations. “Only 1 in 3?” Yes — and on purpose. The system is intentionally permissive at the detector: we’d rather show a rep a borderline opp and let them dismiss it in 30 seconds than miss the one that would have closed. The economics are asymmetric.

The number to actually optimize is the second one: 25-hour median time-to-decision. That’s the gap between Sensors writing “here’s an opportunity, the signals say Cellebrite is asking about observability” and a human saying “yes that’s real, marking qualified” or “no, this was just an internal forwarding chain”. A rep can triage one of these in under a minute with the side panel open. That’s where Sensors earns its keep.

sensors.develeap.com
Opportunity side panel. Triaging an auto-detected opportunity. Stage, follow-up, and priority are one click each. The “Ask AI” link drops the rep straight into the agent with the opportunity already in context.

Improving qualification — what we’ve changed

The qualification rate was 22% in the first month. We pulled it up to 31.5% by addressing three categories of false positives:

Internal forwards. Reps would forward client emails internally for review. The detector treated those as a fresh customer signal. Fix: filter develeap.com and the customer’s known internal domains out of the grouping phase entirely.

Customer + solution duplicates. A single conversation thread that touched on multiple weeks of follow-ups would spawn a new opp every week, all for the same Cellebrite Datadog conversation. Fix: dedup on (customer + solution) across all active stages, not just detected. The old check only looked at the detected stage — if an opp had graduated to qualified, the detector couldn’t see it and would happily create another one. We rewrote that and cleaned up the 4 duplicate pairs that already existed in prod.

Hallucinated solution recommendations. The reasoner would occasionally suggest a solution we hadn’t actually built yet, because the KB description was close enough to the user’s signal. Fix: validate every recommendation against the live solution catalog in DynamoDB after the LLM call, before showing it to the user. The validation rate is observable in CloudWatch; anything that doesn’t pass is silently dropped from the SSE recommendations event.

We also added the customer-pain field to the opp record — the reasoner is told to identify what the customer is actually trying to solve, in their own words, with a direct signal quote. That single change cut “ambiguous” not-qualified reasons in half because reps can see why the agent thought this was a deal.

How we help reps respond fast

A typical interaction:

  1. Rep opens the dashboard at 09:00. Pulse widget shows: “3 follow-ups overdue, 2 new auto-detected, 1 won this week.”
  2. They click the auto-detected Bond opp.
  3. Side panel opens. Customer pain (“Bond is renegotiating their Datadog contract this month and exploring alternatives”) quoted directly from the signal that triggered detection. Solutions tab shows Grafana Labs, Auditty, Datadog (the alternative) with match percentages. Stage / Follow-Up / Priority pickers populated.
  4. Rep clicks “Ask AI”. The assistant streams in real time: “Bond previously bought your Senior DevOps Engineer engagement in 2024. Current spend on Datadog is in their last quarterly report. Logz.io is in your catalog as the closest cost-optimization alternative. Want me to draft a follow-up?”
  5. Rep says yes. Follow-up email streams in. Rep edits two sentences, sends.

The whole interaction is under 90 seconds — versus the 18-minute median for the manual workflow it replaced. The 18 minutes weren’t waste; they were unavoidable context-gathering on a system that didn’t have memory. Sensors has memory.

sensors.develeap.com
AI assistant streaming. The agent answers with the opportunity already in context. The “tool used: query_customers” pill is visible as the agent’s reasoning makes the trip through the data layer.

Security & data privacy

This is the part Develeap leadership cared about most, because Sensors is reading our own confidential pipeline data, including customer emails.

Identity. Amazon Cognito user pool with Google federation. The Sensors session token is a short-lived Cognito-issued JWT; there are no long-lived API keys in the browser, and there are no shared secrets between the application tier and the AI tier — all service-to-service calls use SigV4 signed by the Lambda execution role.

Data isolation. Every Lambda execution role is scoped to exactly the AWS resources it needs. The AI streaming Lambda can call bedrock:InvokeModelWithResponseStream on the regional inference profile, bedrock:Retrieve only on the KB ARN TIEW1QMHHH, read/write only on the four Sensors DynamoDB tables, and read only on the integration buckets. Nothing else. We cdk diff this every deploy.

No long-lived AWS keys anywhere. GitHub Actions assumes an OIDC-federated AWS role for CI/CD. There is no AWS_ACCESS_KEY_ID in any repo secret. There never has been.

Data minimization in observability. This one we made a deliberate choice on. CloudWatch Logs do not capture prompts or completions by default — only tool names, turn counts, and error metadata. We can debug a session if needed by re-reading the DynamoDB-persisted conversation, but we never want a CloudWatch log group to become a PII liability.

Encryption. TLS 1.2+ on every public edge (CloudFront, API Gateway, Function URL). SSE on every S3 bucket (frontend, KB source, integration message stores). DynamoDB encryption at rest. Secrets Manager (KMS-encrypted) for OAuth credentials. Bedrock data stays inside the regional Bedrock boundary.

Account governance. Sensors runs in a dedicated AWS account (674932045187) under Develeap’s org. Root MFA-enforced. CloudTrail enabled, all-region, logs in a bucket with deletion-denied bucket policy. No console-only resources; everything is in CDK.

What’s still on the roadmap. Amazon Bedrock Guardrails (PII filtering, topic blocking) — currently mitigated by prompt-level guardrails and the no-PII-in-logs default, but the proper guardrails work is the highest-priority next item before broad availability. AWS WAF on the streaming Function URL — the synchronous API tier is fronted by API Gateway which sits behind our account WAF posture, but the Function URL is currently public-by-design with auth in-handler. We’re honest about these in our submission; they’re not gaps in requirements, they’re gaps in maturity.

What I’d tell another team that wants to build this

Three things, none of them about AI:

1. Bedrock Knowledge Base does the boring 80%. I’ve watched too many teams stand up an OpenSearch cluster, write a chunker, and tune an embedding model — and then realize that the actual differentiation is in the prompts and tool design, not the retrieval engine. Bedrock KB is one S3 bucket + one CDK resource. If your content is markdown, just use it. Save the cluster work for when you’ve actually outgrown it.

2. Strands Agents is the agent layer I’d bet on right now if you’re on AWS. First-class Bedrock integration. Declarative tool registration. Streaming events that map cleanly to SSE. Open source, AWS-aligned. If you’ve already written your own tool router because LangChain felt heavy, you’re going to like Strands.

3. Cap your agent’s multi-step budget on day one. The Strands MaxTurnsHook(15) is a four-line change and a real safety net. The version of this story without it is the one where someone’s vacation week ends with a $400 Bedrock bill from a single weird query. Don’t be that team.

AWS services we used (and would use again)

ServiceWhat it does for us
Amazon BedrockClaude Sonnet 4 inference, both streaming and synchronous
Amazon Bedrock Knowledge BaseVector retrieval over our solution catalog — zero infra to operate
AWS Strands AgentsMulti-tool agent runtime; 8 tools + 1 sub-agent
AWS LambdaBoth sync (API Gateway) and streaming (Function URL, RESPONSE_STREAM)
Amazon DynamoDBSingle-table design for opps/customers/solutions; PITR on
Amazon API GatewayREST API with Cognito authorizer
Amazon CognitoUser pool + Google federation; ID-token validated in-handler
Amazon S3 + CloudFrontFrontend hosting + KB source bucket + integration message stores
AWS CDK100% of infrastructure-as-code, two stacks per environment
AWS Secrets ManagerOAuth credentials, KMS-encrypted, rotated on cadence
Amazon CloudWatch + X-RayObservability across every Lambda

What’s next

Bedrock Guardrails before broad rollout. WAF on the streaming Function URL. A multi-region active-passive uplift before we move from pilot to all-of-Develeap. A production analytics dashboard for AI-tier metrics (turn-count distribution, tool-call success rate, recommendation-validation drop rate) so we can see what the agent is doing in aggregate without grepping CloudWatch.

The bigger bet is on Sensors as a product we can sell. Six months in, the qualification rate is in the right range, the time-to-decision is where we wanted it, and our reps trust the recommendations enough to use them in real customer-facing follow-ups. The platform itself is generic — the solution catalog, the customer model, and the integration shape are all configurable. If you’ve got a pipeline and a knowledge base, the same architecture works.

Talk to us if you want to see it live.

About Develeap

Develeap is an AWS Premier Partner specializing in DevOps, FinOps, AI engineering, and platform modernization. We build for our customers and, when the right thing doesn’t exist yet, we build for ourselves first. Sensors is the latter.

Author. Saar Cohen leads the Sensors platform at Develeap. Find him on the company Slack if you want to talk about agentic AI on AWS, or what we learned the hard way about giving an LLM access to your pipeline.

Next readings

  • Why we chose AWS Strands Agents over LangGraph for our agent runtime — coming soon
  • Bedrock Knowledge Base in production: what the docs don’t tell you — coming soon
  • Develeap on AWS: how we ship serverless at scale — develeap.com/magazine/