mcpField
D
duplicate-conversation-prevention

duplicate-conversation-prevention

github.com/louisblytheマーケティング・グロース190405 回インストール40 週間前に更新
リポジトリ

duplicate-conversation-prevention について

営業自動化システムの開発者向けスキルです。ID照合、チャネルのロックアウト、シーケンスの競合、会話状態の管理を通じて、複数チャネルでの重複連絡を防ぐ方法を扱います。

主な機能

  1. 01チャネル横断のID照合
  2. 02チャネルのクールダウンとロックアウト
  3. 03シーケンス競合の優先順位付け
  4. 04会話状態とイベントの調整
  5. 05重複連絡先の統合方法

活用シーン

  1. 01メール、SMS、電話での連絡を調整
  2. 02返信後に他チャネルを一時停止
  3. 03重複連絡先の検出と統合

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/louisblythe/sales-skills --skill duplicate-conversation-prevention

インストール後、Claude Code で/duplicate-conversation-preventionを入力して読み込まれたか確認します。

詳細

会話の重複防止

営業ボットが見込み客に同時に連絡して負担をかけないようにするシステム構築のエキスパートです。重複した連絡を避けながら、カバー範囲を最大化するインテリジェントな調整機能を開発者が作成できるよう支援することが目標です。

これが重要な理由

衝突の問題
Without coordination:
- Email sequence sends Day 3 message
- SMS bot triggers engagement sequence
- LinkedIn bot sends connection request
- Phone system queues callback

All happen within same 2-hour window.

Result: Prospect annoyed, opt-out, reputation damage
重複防止を導入した場合
Coordinated outreach:
- Email sends → All other channels pause 24h
- Response detected → Route to single channel
- Engagement spike → Consolidate to winning channel

Result: Coherent experience, higher conversion

重複検出の階層

レイヤー 1:ID の解決
Match prospects across channels:

Primary keys:
- Email address (normalized)
- Phone number (E.164 format)
- LinkedIn URL/ID

Secondary matching:
- Name + Company combination
- Domain + first name
- Phone area code + name

Fuzzy matching:
- "John Smith" vs "J. Smith"
- "[email protected]" vs "[email protected]"
- "+1 (555) 123-4567" vs "5551234567"
レイヤー 2:チャネルの調整
Track active conversations:

{
  "prospect_id": "unified_12345",
  "active_channels": ["email", "sms"],
  "last_touch": {
    "email": "2024-01-15T10:00:00Z",
    "sms": "2024-01-14T14:30:00Z"
  },
  "status": "awaiting_response",
  "cooldown_until": "2024-01-16T10:00:00Z"
}

Before any outreach:
1. Check if prospect in active conversation
2. Check cooldown period
3. Verify channel not recently used
4. Confirm no pending touches queued
レイヤー 3:シーケンスの認識
Track sequence membership:

Prospect enrolled in:
- "Enterprise Outbound" email sequence (Step 3)
- "Demo Follow-up" SMS sequence (Step 1)

Conflict detection:
- Same prospect, multiple sequences
- Overlapping timing
- Conflicting messages

Resolution:
- Priority rules (demo > cold outreach)
- Pause lower priority sequence
- Merge into single coordinated flow

調整戦略

チャネルのロックアウト
When outreach occurs on Channel A:
→ Lock other channels for X hours

Lockout rules:
Email sent → 24h lockout on SMS, phone
SMS sent → 48h lockout on email, phone
Call made → 72h lockout on all automated
Response received → All automated paused

This prevents pile-on effect.
優先チャネルの割り当て
Assign each prospect a primary channel:

Based on:
- Response history (responded to email? = email primary)
- Preference stated ("text me" = SMS primary)
- Engagement data (opens email, ignores SMS)
- Industry norms (enterprise = email, SMB = phone)

Once assigned:
- 80% of touches on primary
- Other channels for variety/re-engagement only
会話の状態マシン
States:
- COLD: No active outreach
- ACTIVE: Sequence in progress
- ENGAGED: Response received
- MEETING_SET: Appointment booked
- PAUSED: Manual hold
- OPTED_OUT: Do not contact

Transitions control outreach:
COLD → ACTIVE: Start sequence
ACTIVE → Can receive next touch
ENGAGED → All automated stops, human takes over
MEETING_SET → Only reminders allowed
PAUSED → No outreach
OPTED_OUT → No outreach ever

実装パターン

集中型キュー
class OutreachQueue:
    def can_send(self, prospect_id, channel):
        # Check unified contact record
        prospect = get_unified_prospect(prospect_id)

        # Already in active conversation?
        if prospect.conversation_state == "ENGAGED":
            return False

        # Channel in cooldown?
        if is_channel_locked(prospect_id, channel):
            return False

        # Too many recent touches?
        recent = count_touches_last_48h(prospect_id)
        if recent >= MAX_TOUCHES_48H:
            return False

        # Pending touch in queue?
        if has_pending_touch(prospect_id):
            return False

        return True

    def record_touch(self, prospect_id, channel, message_type):
        # Log the touch
        log_touch(prospect_id, channel, message_type)

        # Lock other channels
        apply_lockout(prospect_id, channel)

        # Update conversation state
        update_state(prospect_id, "ACTIVE")
分散ロック
For multi-system coordination:

Before send:
1. Acquire lock: prospect_id + channel
2. Check cooldowns
3. Send message
4. Record touch
5. Apply lockouts
6. Release lock

Lock timeout: 30 seconds
Prevents race conditions between systems
イベント駆動型の調整
Publish events to message bus:

Events:
- touch.sent: {prospect_id, channel, timestamp}
- response.received: {prospect_id, channel}
- meeting.booked: {prospect_id}
- opt_out.recorded: {prospect_id}

All systems subscribe and react:
- Email system pauses on touch.sent from SMS
- All systems stop on response.received
- Reminders only on meeting.booked

重複排除のルール

連絡先の正規化
def normalize_contact(contact):
    # Email
    email = contact.email.lower().strip()
    email = remove_plus_addressing(email)  # john+test@... → john@...

    # Phone
    phone = digits_only(contact.phone)
    phone = to_e164(phone, contact.country)  # +15551234567

    # Name
    name = contact.name.strip().title()

    return NormalizedContact(email, phone, name)
マージ戦略
When duplicates found:

Same email, different phones:
→ Merge records
→ Add both phones to contact
→ Use most recent as primary

Same phone, different emails:
→ Verify not different people
→ If same person, merge
→ Use business email as primary

Name + Company match only:
→ Flag for review
→ Don't auto-merge
→ Treat as potentially same person
競合の解決
When same prospect in multiple sequences:

Priority order:
1. Active deal sequences (highest)
2. Response follow-up sequences
3. Re-engagement sequences
4. Cold outreach sequences (lowest)

Action:
- Pause lower priority sequences
- Continue highest priority only
- Resume others after completion/exit

クロスチャネル調整

チャネルの引き継ぎ
When prospect responds on different channel:

Email sequence active, SMS response received:
1. Pause email sequence
2. Route SMS to conversation
3. Mark email as "response on other channel"
4. Continue on SMS only

Don't:
- Send next email anyway
- Ask same question on email
- Ignore the SMS response
統合受信トレイ
All responses flow to single view:

- Email replies
- SMS responses
- LinkedIn messages
- Call notes

Rep sees full picture:
- Chronological timeline
- All channels merged
- Single response thread
- No confusion about where to reply

エッジケース

正当なマルチチャネル連絡
Sometimes multiple touches are OK:

Meeting reminder:
- Email confirmation (day before)
- SMS reminder (1 hour before)
→ Both expected, not duplicates

Different stakeholders:
- Email to champion
- Call to economic buyer
→ Different people, both needed

Sequential escalation:
- Email → no response 5 days
- SMS → "Did you see my email?"
→ Intentional, coordinated
共有受信トレイへの対応
Multiple people, one email:

[email protected]
[email protected]

Detection:
- Generic prefix
- Multiple responders
- Different signatures

Strategy:
- Track individual responders separately
- Company-level coordination
- Don't assume single contact
組織の認識
Multiple contacts at same company:

Coordinate across prospects:
- Don't email CEO and CFO same day
- Space out touches within org
- Track company-level activity

Rules:
- Max 2 people/company/day
- 48h between same-department contacts
- Share positive signals across contacts

メトリクス

衝突率
Track:
- Duplicate touches sent (failure)
- Touches blocked by coordination (success)
- Near-misses (within 4h window)

Target: <1% collision rate

Alert when:
- Same prospect, 2+ channels, <24h apart
- Same prospect, same channel, <48h apart
オプトアウトの帰属
When opt-out occurs:

Check:
- Touches in last 7 days
- Channels used
- Frequency

Flag if:
- 3+ touches in 48h preceded opt-out
- Multiple channels same day
- Volume spike before opt-out

Use for rule refinement.

システム設計

アーキテクチャ
┌─────────────┐     ┌─────────────┐
│ Email Bot   │────▶│             │
├─────────────┤     │  Unified    │
│ SMS Bot     │────▶│  Outreach   │
├─────────────┤     │  Controller │
│ Phone Bot   │────▶│             │
├─────────────┤     └──────┬──────┘
│ LinkedIn    │────▶       │
└─────────────┘            ▼
                    ┌─────────────┐
                    │  Prospect   │
                    │  Database   │
                    └─────────────┘

All outreach routes through controller.
Controller enforces coordination rules.
状態の保存
{
  "prospect_id": "unified_12345",
  "identities": {
    "email": "[email protected]",
    "phone": "+15551234567",
    "linkedin": "linkedin.com/in/johnsmith"
  },
  "conversation_state": "ACTIVE",
  "primary_channel": "email",
  "active_sequences": ["enterprise_outbound"],
  "last_touches": {
    "email": {"at": "2024-01-15T10:00:00Z", "type": "sequence_step_3"},
    "sms": {"at": "2024-01-10T14:00:00Z", "type": "intro"}
  },
  "lockouts": {
    "sms": "2024-01-16T10:00:00Z",
    "phone": "2024-01-16T10:00:00Z"
  },
  "touch_count_7d": 4
}

コメント