はじめに
こんにちは。ITフィールドセールスをしている長井洸太です。
前回の記事(Claude APIとGemini APIを使い分ける基準を考えた)で「文章生成・パーソナライズはClaude」という役割分担について書きました。
実はこれまでGitHub・Qiita・connpassと3つのエンジニア発掘スクリプトを作ってきて、DM文を生成するプロンプトをそれぞれ書いてきたのですが、見比べてみると「型」はほぼ同じで、変えているのは中身の情報だけだと気づきました。今回はこのプロンプト設計の型と、なぜその形に落ち着いたかをまとめます。
結論:型は4ブロック固定、変えるのは「情報」だけ
自分が組んでいるDM生成プロンプトは、どれもこの4ブロック構成です。
| ブロック | 役割 | 変わるか |
|---|---|---|
| ① 役割設定 | 「あなたはITフィールドセールス担当者です」 | 固定 |
| ② 候補者情報 | 名前・自己紹介・技術スタックなど | ソースごとに変わる |
| ③ 送信者情報 | 会社名・担当者名・役職 | 固定 |
| ④ 条件 | 文字数・トーン・締め方などの箇条書き | ソースごとに1〜2個追加 |
つまり「①役割」「③送信者情報」はテンプレとしてそのまま使い回し、「②候補者情報」と「④条件」だけをそのソース特有の内容に差し替えるという設計です。
なぜこの型に落ち着いたか
「あなたは〇〇です」で毎回スタートする
3スクリプトすべて、プロンプトの1行目は同じ書き出しです。
prompt = f"""
あなたはITフィールドセールス担当者です。
以下の{対象}に向けた、自然で簡潔なアプローチDM文を日本語で作成してください。
...
役割を先に固定することで、後続の情報や条件が「誰のための指示か」を毎回書き直さなくて済みます。地味ですが、プロンプトの中で最初に読まれる部分なので、ここがブレると全体の出力トーンもブレる体感がありました。
情報は見出し付き箇条書きにする
候補者情報・送信者情報は必ず 【見出し】 + - 項目: 値 の形式にしています。文章として繋げず、箇条書きにする理由は、Claudeに「これは参照情報であって、そのまま出力する文章ではない」と伝えるためです。地の文で書くと、まれに候補者情報の言い回しがそのままDM文に紛れ込むことがありました。
条件は「量」ではなく「具体性」
3スクリプトの条件欄を並べてみると違いがわかります。
# GitHub版
- 200文字以内
- 売り込み感を出さない
- 相手の技術スタックに触れる
- 返信しやすい一言で締める
# Qiita版
- 200文字以内
- 売り込み感を出さない
- 相手の技術・記事内容に具体的に触れる ← 「記事内容」を追加
- 返信しやすい一言で締める
# connpass版
- 200文字以内
- 売り込み感を出さない
- 主催イベントの内容に具体的に触れる ← イベント文脈に差し替え
- 技術コミュニティへのリスペクトを示す ← 条件を1つ追加
- 返信しやすい一言で締める
共通条件(文字数・売り込み感・締め方)は3つとも同じ文言をコピーして使い、ソース特有の1条件だけを足しています。「相手の技術スタックに触れる」を「相手の技術・記事内容に具体的に触れる」のように候補者情報のブロックで渡している項目名と条件の文言を揃えると、Claudeがどの情報を参照すべきか迷わなくなりました。
実際の候補者情報ブロックの違い(比較)
同じ4ブロック構成の中で、②候補者情報だけがソースごとにこう変わっています。
# GitHub版
【候補者情報】
- 名前: {name}
- 場所: {location}
- 自己紹介: {bio}
- 主な使用言語: {langs}
- 公開リポジトリ数: {repos}
# Qiita版
【候補者情報】
- 名前: {name}
- 所属: {org or '不明'}
- 自己紹介: {desc}
- よく書くタグ: {tags}
- 記事数: {articles}本 / フォロワー: {followers}人
# connpass版
【候補者情報】
- 名前: {name}
- 主催イベント: {event}
- 開催場所: {place or '不明'}
- 参加者数: {accepted}人
- 検索キーワード: {keyword}
GitHubは「コード」、Qiitaは「記事」、connpassは「イベント」というそのプラットフォームで一番自然に取れる情報を主軸に据えているだけで、項目数も構成もほぼ同じです。新しいソースを追加するときも、このテンプレの②と④だけ埋め替えれば動く、という再利用のしやすさにつながっています。
やってみてわかったこと
条件を1つ増やすと文章が1文増える傾向がある
connpass版で「技術コミュニティへのリスペクトを示す」を条件に足したところ、生成されるDM文に「〇〇な勉強会を継続されているのはすごいと思います」のような一文がほぼ確実に追加されるようになりました。条件は「守ってくれたらラッキー」ではなく、ほぼそのまま文章に反映されると考えて書いた方が精度が上がります。
「不明」のフォールバックが地味に重要
{location} や {org} は候補者によって空欄のことが多く、or '不明' を入れずに空文字を渡すと「場所: 」のような不自然な行がプロンプトに混ざり、Claudeが違和感のある文章を返すことがありました。値が欠けている前提で、プロンプトに渡す前に必ずフォールバック文字列を用意するようにしています。
200文字制限は「超過を防ぐ」より「まとめる力」を試す指定
最初は「長すぎるDMにならないように」という目的で200文字以内を指定していたのですが、実際の効果はむしろ逆でした。文字数を絞ると、Claudeが候補者情報の中から一番刺さりそうな1点だけを選んで書くようになり、結果的に内容の薄いテンプレ文になりにくいという副次効果がありました。
おわりに
3つの発掘スクリプトのプロンプトを見比べたことで、「役割設定」「候補者情報」「送信者情報」「条件」という4ブロックの型と、条件欄は共通部分をコピーして差分だけ足すという書き方が、自分の中でのDM生成プロンプトの基本形になりました。
次回はHaiku・Sonnetどちらを使うべきか、DM生成のようなタスクでのコスト・精度比較を書く予定です。
毎日X(Twitter)・Instagram・LinkedInで自動化ツールや開発の話を投稿しています。ぜひ繋がりましょう!