惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Docker
U
Unit 42
Google DeepMind News
Google DeepMind News
B
Blog RSS Feed
S
SegmentFault 最新的问题
阮一峰的网络日志
阮一峰的网络日志
雷峰网
雷峰网
Microsoft Security Blog
Microsoft Security Blog
爱范儿
爱范儿
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园_首页
Apple Machine Learning Research
Apple Machine Learning Research
罗磊的独立博客
GbyAI
GbyAI
Stack Overflow Blog
Stack Overflow Blog
Martin Fowler
Martin Fowler
宝玉的分享
宝玉的分享
L
LangChain Blog
Engineering at Meta
Engineering at Meta
量子位
有赞技术团队
有赞技术团队
博客园 - 【当耐特】
A
About on SuperTechFans
Y
Y Combinator Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work Top 15 Reinforcement Learning Questions That Will Appear in Exams The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026
I Built a Sales Prep AI and It Went Deeper Than Expected
naoki_JPN · 2026-04-17 · via DEV Community

naoki_JPN

Introduction

"Before a first sales meeting, you always research the other company. That part is kind of a pain, right?"

That thought is where this started. I wanted something that would take a company name and automatically research it, then return a report.

I figured I could get something working in 2–3 days. But getting it to a genuinely usable level turned out to be much deeper than expected. This is the story of that process.

What I built: Sales Prep AI (LINE bot)

https://pre-talk.vercel.app


Tech Stack

Tech Stack


How It Came Together

Phase 1: Just Get It Working

I started with a simple web form. Enter company name, department, and contact name → it searches the web → GPT-4o-mini analyzes the results → returns a report.

As I worked on improving reasoning quality, I switched from GPT-4o-mini to Claude Sonnet for the analysis layer. Light input-interpretation tasks go to Claude Haiku; heavy analysis and OCR go to Claude Sonnet. That division of labor stuck.

For search, I started with DuckDuckGo, but the quality wasn't great, so I switched to Tavily. That one change made a noticeable difference in search quality.

Phase 2: Fighting Vercel Hobby's 10-Second Timeout

Research involves multiple steps — search, then AI analysis — and it realistically takes 1–2 minutes. Vercel's Hobby plan times out at 10 seconds.

The solution: streaming responses. By returning a response while continuing to process, you keep the function alive.

const stream = new ReadableStream({
  async start(controller) {
    const heartbeat = setInterval(() => {
      controller.enqueue(new TextEncoder().encode(" "));
    }, 5000);

    try {
      // Heavy processing happens here
      await runResearch(input);
    } finally {
      clearInterval(heartbeat);
      controller.close();
    }
  },
});

return new Response(stream, { status: 200 });

Sending a blank space every 5 seconds keeps the connection alive. Brute-force, but it works.

Phase 3: Slack Bot → LINE Bot

A web form creates friction — you have to actively open it when you need it. It's better to use it from a tool you already have open.

I built a Slack bot first. But when I ended up canceling the paid Slack plan I was using, I migrated to LINE.

Phase 4: Fighting Hallucinations

This was the hardest part.

The AI was confidently returning information that sounded plausible but wasn't true. Specifically:

  • Asserting fabricated problems as "challenges faced by [department]"
  • Returning outdated information as if it were current
  • Filling in gaps with information not in any search result

I approached this on two axes.

Axis 1: Improve output accuracy

I built in mechanisms to prevent unsupported information from slipping through.

  • Fact/inference separation: The AI explicitly labels each piece of information as either a verified fact (from official sources) or an inference (from surrounding context). The report displays these separately.
  • Output gate: Items that fail conditions like "only contains generalities with no specifics" or "no source URL exists" are filtered out before output.

Axis 2: Make it human-verifiable

Improving accuracy alone isn't enough. Whether done by humans or AI, mistakes happen. What matters is making the process transparent.

So I designed each report item to include both "the facts recognized" and "the reasoning path to the conclusion." Showing what evidence led to what conclusion lets humans catch reasoning that doesn't hold up.

The goal is to save prep time, not to replace human judgment. That's fine.

Phase 5: The Official Website Detection Rabbit Hole

Search results mix "official company sites" with "everything else" (news, Wikipedia, etc.).

I started with simple domain matching, but group companies, subsidiaries, and subdomains made that fall apart quickly.

I eventually settled on:

  • Return multiple official domain candidates
  • Normalize to base domain (including subdomain matching)
  • Use .some() to check against the array

Phase 6: Business Card Scanning

"Wouldn't it be great if you could start researching the moment you get someone's card?"

I added business card scanning using Claude's Vision capability. Send a photo of a card to LINE → it extracts company name, department, and contact name → triggers research automatically. OCR quality mattered, so I used Claude Sonnet here.


A Lesson in Agent Sprawl

At one point I tried to improve the reasoning logic by spinning up five agents simultaneously (field-sales / info-architect / reasoning-designer / impl-designer / critic).

They went into an endless loop of spec discussion, autonomously generating 154 tasks. When I told them to stop, they kept going. I had to force-shutdown. Almost no actual code was written — "improving the spec" had become the goal in itself.

The root cause: I hadn't defined what they were allowed to decide or when they were done.

After that, I redesigned the agent structure. Instead of everyone chiming in freely, I cut it down to 3 roles and explicitly defined what each role was not allowed to do.

Role Responsibility What they must NOT do
team-lead Routing and task management Write code, generate summaries
product Decide implementation approach and implement Create tasks themselves
auditor Pass/fail judgment only Write improvement suggestions, act unless called

Defining "what not to do" alongside "what to do" made role boundaries much cleaner.


Cost

API cost per research run (measured)

Varies by company size and available information.

Item Cost
Claude Sonnet (analysis) ~$0.35
Tavily (web search) ~$0.05
Total ~$0.40/run (range: $0.24–$0.52)

At 100 runs/month that's ~$40; at 500 runs it's ~$200. It's currently free to use, so I'm entirely out of pocket. I'm in a "prove the value first" phase.

Fixed costs (monthly)

Hosting, DB, LINE, domain, etc. I've minimized these by combining free tiers, but it's not zero.


Current Architecture

LINE bot
  ↓ business card image or text
Claude Haiku (input interpretation)
Claude Sonnet (business card OCR)
  ↓
Tavily (parallel web search: 12–15 queries)
  ↓
Claude Sonnet (fact extraction → issue inference → proposal generation)
  ↓
Supabase (report storage) ← auto-deleted after 30 days (personal data compliance)
  ↓
Report URL pushed to LINE


Closing

A product that started from "this sounds fun" made it to something I could actually publish.

Hallucination mitigation, timeout workarounds, official site detection — making something genuinely usable turned out to be deeper than I expected.

If you're curious, add it as a friend on LINE. Just send a photo of a business card and it runs.

https://pre-talk.vercel.app