Comments are the most honest product research a creator gets. Viewers tell you what confused them, what they want next, who is pretending to be you, and who is about to unsubscribe.
Most creators can't read them all. The ones who try usually end up pasting the same "Thanks for watching 🙏" a hundred times. Generic AI replies are even worse, because viewers can smell them instantly.
So we built ReplyDNA, an open-source (MIT) comment assistant that runs inside Claude Code. This post covers the three design decisions that mattered most:
- Voice before replies: measure how the creator actually talks before writing anything.
- Language mirror: answer every viewer in their own language and script.
- Safety in code, not prompts: the dangerous paths are blocked by validators and CI, not by asking the model nicely.
1. Voice DNA: measure first, write later
A reply sounds like you when it uses your habits:
- how you address viewers ("you", "aap", "tum", "usted"…);
- the phrases you repeat;
- how you open and close.
So ReplyDNA downloads the creator's own video captions and counts them before it writes a single reply.
The first surprise was tokenization. Many creators we care about speak Hindi, Hinglish, Tamil or Spanish. A naive \w+ splits Devanagari words at combining vowel signs, and it also keeps the danda (।). Here is the tokenizer we ended up with:
TOKEN = re.compile( r"(?:[^\W\d_]|[\u0900-\u0963\u0966-\u0dff])" r"(?:[^\W_]|[\u0300-\u036f\u0900-\u0963\u0966-\u0dff]|'(?=\w))*" ) The second lesson: a "signature phrase" is not the most frequent n-gram. One long rant can repeat a phrase 30 times. A real catchphrase shows up across many different videos, so we rank candidates by spread × frequency:
# signature = said in many different videos (not one long rant), ranked by spread x frequency min_df = max(2, round(nv * 0.3)) cand = sorted(((g, count[g], df[g]) for g in count if df[g] >= min_df and count[g] >= 5), key=lambda x: -(x[1] * x[2] / nv)) These numbers become a voice card: a short Markdown file the creator reads and approves. Then comes a blind test. We mix three of their real replies with three drafts; if they can't tell which is which, the card is ready.
2. The language mirror
Every comment gets a label (question, praise, troll, valid criticism, fraud claim…) and a draft in the commenter's language and script:
- Spanish → Spanish;
- Hindi in Devanagari → Devanagari;
- Hinglish in Latin letters → Hinglish in Latin letters.
It sounds obvious, but it's the single biggest "this feels human" signal in the demo.
Tricky comments (trolls, "you're just selling", valid criticism) get two drafts: A is calm, B is witty but never rude. The creator picks one.
3. Safety lives in code, not in the prompt
Claude does the thinking: labels and drafts. Small Python scripts only move data, and they validate everything Claude writes before it reaches the database. Some categories can never be auto-answered, and a product mention is never allowed on others:
# your product / course / membership is never mentioned on these NEVER_OFFER = {"blame", "distress", "troll", "valid_criticism", "success_story", "customer_complaint", "advice_request", "fraud_claim"} # these always go to you as 🔴 alerts, never an automatic reply ALERT_ONLY = {"distress", "legal_threat", "customer_complaint", "fraud_claim"} if r.get("category") in ALERT_ONLY and r.get("action") != "alert": errs.append(f"{r['category']} must have action=alert") One bug taught us the most. The creator can type "approve all" in the inbox. In an early version, that also approved 🔴 alerts sitting in the same list. Now "all" only means reply items:
def nums(s, mp, con=None): """"all" means every 🟢/🟡/🔥 reply item: never 🔴 alerts or ⏸ holds, which can only be approved one by one, by number, after the creator has read them.""" if s == "all": ids = list(mp.values()) ok = {r[0] for r in con.execute( "SELECT comment_id FROM labels WHERE action='reply' AND comment_id IN (...)", ids)} return [i for i in ids if i in ok] And CI makes sure it never comes back:
# "approve all" must never approve 🔴 alerts python scripts/post_replies.py --approve all --post --dry-run --gap 0 # ...then assert: 0 alert drafts with status='approved' A few more guardrails:
- Draft mode by default: nothing is posted without the creator's OK.
- Scam shield: fake "it's me, DM me on Telegram" accounts are held automatically, but only when Claude's confidence is ≥ 0.95, and holds are reversible.
- Other channels are read-only. The mentions radar finds podcasts and "exposed" videos about you, but it never posts, hides or reports anything there.
- Quota guard: it stops at 9,000 of YouTube's 10,000 free daily API units.
- Local first: comments, labels and login live in a SQLite file on the creator's laptop. There is no server.
4. Insight, not just replies
Once a month, ReplyDNA turns the comments into an interactive report (HTML + PDF):
- what viewers keep asking;
- the questions nobody answered, turned into a ready-to-film list of video ideas;
- a Keep / Improve / Avoid verdict, where every claim is backed by a number.
👉 Open the live demo report (a fictional DIY channel, 30 comments in 5 languages).
Try it in 30 seconds
No YouTube login needed for the demo:
git clone https://github.com/AlcubiX/replydna.git && cd replydna python3 -m venv .venv && .venv/bin/pip install -r requirements.txt .venv/bin/python scripts/demo.py --open Or install it as a Claude Code plugin:
/plugin marketplace add AlcubiX/replydna /plugin install replydna@replydna A Claude Pro or Max plan is enough; there's no separate API key.
What's next (open issues, contributions welcome)
- Any-LLM mode: local models (Ollama, LM Studio) and OpenAI-compatible APIs.
- Shorts and community-post comments.
- A translated report UI (Hindi, Spanish, Portuguese…).
- Optional API mode: scheduled runs without a laptop.
We'd love feedback, especially on what you would never want an AI to do in your comments. If it's useful, a ⭐ on GitHub helps other creators find it.
Built by AlcubiX. We compress the time work takes.




