ColdOpen:学习你写作风格的开源权重模型,起草你真正会发出的邮件
ColdOpen: an open-weight model that learns how you write, then drafts the email you'd actually send
ColdOpen 是一款基于开源权重模型的冷邮件起草工具,用户粘贴 2-3 条自己写过的消息后,它会生成一份"voice learned"风格说明,再输出三种语气(Direct & Concise、Warm & Respectful、Curiosity-First)的邮件和主题行各三版。
This is a submission for the Hacktoberfest Weekend Challenge: Build for a Friend
What I Built
I built ColdOpen for my sister, Aishwarya. She's a software engineer with 5+ years of experience, and she's good at her job. She still puts off one task for weeks: writing the first message to someone she doesn't know. That could be a referral request, a note to a recruiter, or a question to someone who changed roles the way she wants to.
She told me "I rewrite the first line ten times and then close the tab". The AI tools she'd tried made it worse. The drafts were polished, but they started with "I hope this email finds you well" and sounded like nobody she knows. If it doesn't sound like her, she won't send it.
ColdOpen starts from her own writing instead of a template:
- She pastes 2-3 messages she has actually written.
- She says who she's writing to and what she wants (15 goals: referral, recruiter intro, alumni intro, resume feedback, mock interview, mentoring, follow-up, thank-you, reconnect, reference, switching roles, and more).
- ColdOpen writes a short "voice learned" note (greeting, sign-off, sentence length, habits) that she can check. Then it writes three emails and three subject lines: Direct & Concise, Warm & Respectful, and Curiosity-First.
- One checkbox shows the same request written with no voice, side by side, so she can see what the voice step changed.
The highlights are the part I'm proudest of. In the side-by-side view, green marks wording that carries her voice, pink marks stock template phrases in the generic draft, and amber marks [placeholders] she has to fill in before sending.
It also won't invent facts. If she doesn't tell it about a shared project or a talk, it writes [bracketed placeholder] and doesn't make something up.
Demo
Live: https://coldopen-fe.onrender.com/ (hosted on Render's free tier, and an UptimeRobot monitor pings the /api/health endpoint every 5-10 minutes so the service stays awake)
Screenshot:
1. Direct & Concise: the same reference request, in her voice and without it

Top: "In your voice". Bottom: "Generic (no voice)". Green marks her phrasing, pink marks stock template phrases, and amber marks [Your name], which she has to fill in.
2. Warm & Respectful: the same request, a softer tone
Screen recording: Watch the 1-minute walkthrough on Google Drive
Code
atharv96k
/
ColdOpen
Cold emails in your own voice. Paste your past messages, get 3 drafts that sound like you.
Cold emails that sound like you wrote them
Paste a few of your own messages. ColdOpen learns how you write and drafts three cold emails and three subject lines in your voice, then shows you what changed next to a generic AI draft.
Live demo · Write-up on DEV · Report an issue
Motivation
ColdOpen was built for a software engineer with more than five years of experience. Reaching out to someone you do not know is difficult; the first message is often the one that never gets sent. Generic AI email tools produce polished drafts that do not sound like the sender, so those drafts go unsent as well.
ColdOpen begins with the user’s own writing rather than a template.
Features
| Feature | Description |
|---|---|
| Voice learning | Analyzes 2–3 of your own messages and produces a short “voice learned” note (greeting, sign-off, sentence length, habits) that you can review. |
| Three drafts, |
…
React + Vite frontend, Node/Express backend, MIT licensed.
How I Built It
The model. ColdOpen calls open-weight models (default openai/gpt-oss-120b, with qwen/qwen3.8-27b and openai/gpt-oss-20b as fallbacks) through Groq's hosted API. The list is one environment variable (GROQ_MODELS). If a model is rate limited or unavailable, the server moves to the next one. I started out thinking of running the model locally, but I wanted Aishwarya to be able to open a link and use it without installing anything, so I switched to a hosted open-weight model and deployed the app. Because the model is open-weight and the list is a single environment variable, that switch was a config change, not a rewrite, and the same prompts can point back at a local runtime later.
Prompt design. The model describes how she writes before it drafts anything. That voice-notes step is shown in the UI so she can tell whether it understood her. Her text goes into the prompt fenced as data, not as instructions. The fact rules are strict: the model may only use what she typed into About you, Your question and Anything specific.
Most of the work was guardrails around a small model. The prompt alone wasn't enough, so the server checks the output:
- It validates the JSON.
- It rejects stock clichés like "I hope you're doing well" in the voice column and retries once.
- It repairs one-line emails into a proper email layout (greeting, short paragraphs, sign-off).
- It checks that every highlighted phrase really appears in the email. If the model's picks fail the check, it falls back to simple methods: overlap with her samples for the voice column and a hand-written stock-phrase list for the generic column.
Looking back, getting highlights to work was harder than getting emails to work. Early on the model returned empty highlight arrays, and exact-match checks failed on curly quotes and dashes. I fixed that by normalizing punctuation before matching.
Other things. The API is rate limited to 10 requests a minute per IP, and inputs have length caps. In development there's a test bar with 15 sample cases, one per goal. I wrote them from an experienced engineer's point of view, because that's who the app is for. The whole app deploys as a single Render web service, since Express serves the built React client.
Why Does Open Innovation Matter?
Moving from local to hosted was a config change. I needed a deployed link she could open, so I moved from a local setup to a hosted open-weight model by changing one environment variable. A closed API would have tied the prompts and guardrails to one provider's models.
I could see where the model stopped and my code started. With open weights and a swappable model list, I could tell which problems were the model's (clichés, invented details, one-line emails) and which were mine to guard against. Most of this project is that second part.
It cost nothing to build. A free-tier key was enough for a weekend of testing, and I tested a lot.
An honest limit: ColdOpen calls a hosted open-weight model, so the writing samples are sent to that provider to generate drafts. This app doesn't store them, but they do leave the machine. Writing samples can be personal, and the open-weight advantage I'd most like to use is running locally so they never leave. My machine isn't configured well enough to run an LLM locally, so this version uses a hosted open-weight model instead, and I'd rather say that than imply privacy it doesn't have. Because the model is just a setting, the same app can point at a local runtime on a machine that can handle one.
Where a closed model might have done better: The models kept falling back on "I hope you're doing well" even when told not to, and sometimes returned the whole email as one line. I added a banned-phrase check with a retry and a layout repair step. A frontier model might have followed those instructions the first time.
The Hand-over
She didn't care much about the three tones. What she reacted to was the generic version next to her own. She pointed at the pink-highlighted "I hope this email finds you well" and laughed: "That's exactly what I hate." Then she pointed at the green phrases in her version and said, "That's actually how I'd say it."
Prize Categories
Best Use of Render: the app is deployed as a single Render web service, with Express serving the built React client.
Limitations
- Language models sometimes add small details that weren't in the input. The fact rules and filters reduce this but don't remove it. Read every draft before you send it.
- Voice match depends on how much natural writing you paste in.
- Highlights are a guide, not an AI-text detector.
- With the generic comparison on, each request makes two model calls, so free-tier rate limits apply.
What's next
- Gemma as an additional model, with a side-by-side voice comparison between models
- Remember writing samples in the browser
- "Make it shorter / more casual" per email
来源:Google AI:DEV 作者专属(RSS) · dev.to

