ミーティングブリーフジェネレーター
会社名と任意の連絡先情報を入力します。Tavily で企業を調査し、Gemini で1ページのプレコールブリーフに要約します。オプションで Notion に保存できます。
重要なルール: 具体的な情報を捏造しないでください。ブリーフ内のすべての事実、数値、主張は Tavily の検索結果に基づいている必要があります。検索データがないセクションには「公開情報は限られています」と記載してください。資金調達額、従業員数、製品詳細などをでっち上げないでください。
ステップ 1: セットアップ確認
必要な環境変数を確認します:
echo "TAVILY_API_KEY: ${TAVILY_API_KEY:+set}"
echo "GEMINI_API_KEY: ${GEMINI_API_KEY:+set}"
echo "NOTION_TOKEN: ${NOTION_TOKEN:-not set}"
echo "NOTION_DATABASE_ID: ${NOTION_DATABASE_ID:-not set}"
TAVILY_API_KEY がない場合: 処理を停止し、ユーザーに次のように伝えます: 「TAVILY_API_KEY が必要です。app.tavily.com で取得し、.env ファイルに追加してください。」
GEMINI_API_KEY がない場合: 処理を停止し、ユーザーに次のように伝えます: 「GEMINI_API_KEY が必要です。aistudio.google.com で取得し、.env ファイルに追加してください。」
NOTION_TOKEN または NOTION_DATABASE_ID がない場合: 処理を続行します。ブリーフはテキストとしてのみ出力され、Notion への保存はスキップされます。
入力が存在することを確認します。 ユーザーは最低でも会社名を提供する必要があります。提供されない場合は、「どの会社とのミーティングですか?」と尋ねてください。
ステップ 2: コンテキストの収集
以下の情報を収集します。不足しているものだけを尋ねてください。
必須:
- 会社名(またはドメイン/URL)
- ミーティング日
オプション(必須ではないが、提供されればブロックしない):
- 連絡先の名前と役職
- ミーティングの種類(ディスカバリー、デモ、フォローアップ、QBR)
- ユーザーがカバーしたい特定のトピックや目標
ユーザーが会社の URL やドメインを提供した場合は、それを使って Tavily のクエリをより正確にします(例: site:example.com や検索語にドメインを含める)。
ステップ 3: Tavily で調査
以下の検索を順番に実行します。各検索はブリーフの1つのセクションを対象とします。各検索の上位結果(タイトル、URL、コンテンツスニペット、スコア)を保存します。
スコアが 0.5 以上の結果のみを保持します。検索で該当結果が0件の場合は、そのセクションに「公開情報は限られています」とマークします。
検索 1: 会社概要
curl -s -X POST "https://api.tavily.com/search" \
-H "Content-Type: application/json" \
-d '{
"api_key": "'"$TAVILY_API_KEY"'",
"query": "\"COMPANY\" overview founded employees headquarters",
"search_depth": "advanced",
"max_results": 5,
"include_answer": true
}'
検索 2: 最近のニュース(過去30日間)
curl -s -X POST "https://api.tavily.com/search" \
-H "Content-Type: application/json" \
-d '{
"api_key": "'"$TAVILY_API_KEY"'",
"query": "\"COMPANY\" news announcement",
"search_depth": "advanced",
"max_results": 5,
"include_answer": true,
"topic": "news",
"time_range": "month"
}'
検索 3: 技術スタック
curl -s -X POST "https://api.tavily.com/search" \
-H "Content-Type: application/json" \
-d '{
"api_key": "'"$TAVILY_API_KEY"'",
"query": "\"COMPANY\" technology stack engineering infrastructure tools",
"search_depth": "advanced",
"max_results": 5,
"include_answer": true
}'
検索 4: 製品と価格
curl -s -X POST "https://api.tavily.com/search" \
-H "Content-Type: application/json" \
-d '{
"api_key": "'"$TAVILY_API_KEY"'",
"query": "\"COMPANY\" product features pricing use case",
"search_depth": "advanced",
"max_results": 5,
"include_answer": true
}'
検索 5: 競合
curl -s -X POST "https://api.tavily.com/search" \
-H "Content-Type: application/json" \
-d '{
"api_key": "'"$TAVILY_API_KEY"'",
"query": "\"COMPANY\" competitors alternatives vs",
"search_depth": "advanced",
"max_results": 5,
"include_answer": true
}'
検索 6: 資金調達と成長
curl -s -X POST "https://api.tavily.com/search" \
-H "Content-Type: application/json" \
-d '{
"api_key": "'"$TAVILY_API_KEY"'",
"query": "\"COMPANY\" funding raised valuation growth",
"search_depth": "advanced",
"max_results": 5,
"include_answer": true
}'
連絡先名が提供されている場合は、さらに2つの検索を実行します:
検索 7: 連絡先プロフィール
curl -s -X POST "https://api.tavily.com/search" \
-H "Content-Type: application/json" \
-d '{
"api_key": "'"$TAVILY_API_KEY"'",
"query": "\"CONTACT_NAME\" \"COMPANY\" role title",
"search_depth": "advanced",
"max_results": 5,
"include_answer": true
}'
検索 8: 連絡先の経歴
curl -s -X POST "https://api.tavily.com/search" \
-H "Content-Type: application/json" \
-d '{
"api_key": "'"$TAVILY_API_KEY"'",
"query": "\"CONTACT_NAME\" background career LinkedIn",
"search_depth": "advanced",
"max_results": 5,
"include_answer": true
}'
ステップ 4: Gemini で要約
references/brief-format.md を全て読みます。references/output-template.md を読み、テンプレートを使用します。
Gemini リクエストを一時ファイルに書き込みます:
cat > /tmp/meeting-brief-request.json << 'ENDJSON'
{
"system_instruction": {
"parts": [{
"text": "あなたは、営業またはビジネス開発のミーティングのために1ページのプレコールブリーフを作成するGTMリサーチアナリストです。ルール: すべての主張は、提供されたリサーチのソースURLを引用する必要があります。トーキングポイントには「[リサーチからの発見] により、[目標] を達成するために [ポイント] に言及する」という形式を使用します。データを捏造しないでください。リサーチデータがないセクションには「公開情報は限られています」と書いてください。emダッシュは使用しないでください。禁止ワードは使用しないでください。合計400ワード未満にしてください。ブリーフは3分でスキャン可能である必要があります。"
}]
},
"contents": [{
"parts": [{
"text": "RESEARCH_RESULTS_AND_INSTRUCTIONS_HERE"
}]
}],
"generationConfig": {
"temperature": 0.3,
"maxOutputTokens": 2500
}
}
ENDJSON
curl -s -X POST \
"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d @/tmp/meeting-brief-request.json \
| python3 -c "import sys,json; d=json.load(sys.stdin); print(d['candidates'][0]['content']['parts'][0]['text'])"
RESEARCH_RESULTS_AND_INSTRUCTIONS_HERE を次の内容に置き換えます:
- すべての Tavily 検索結果(結果ごとのタイトル、URL、コンテンツスニペット)
- output-template.md のブリーフテンプレート構造
- 会社名、連絡先名(提供されている場合)、ミーティング日、ミーティングの種類(提供されている場合)
ステップ 5: 自己 QA
提示前に確認します:
- 捏造されたデータがない。すべての事実に Tavily 結果からのソースURLがある。
- トーキングポイントが「[発見] により、[目標] を達成するために [ポイント] に言及する」形式を使用している。
- どの行にも emダッシュが含まれていない。
- 禁止ワードが使用されていない。
- ブリーフが400ワード未満である。
- 意思決定者セクションに、連絡先が提供されていない場合は「指定なし」と表示される。
- データがないセクションは、推測する代わりに「公開情報は限られています」と表示される。
- 未解決の質問は、この会社に固有のものであり、一般的なものではない。
違反があれば、提示前に修正します。
ステップ 6: 出力、または Notion に保存
完全なブリーフをコードブロックで提示します。
NOTION_TOKEN と NOTION_DATABASE_ID の両方が設定されている場合は、「このブリーフを Notion に保存しますか?」と尋ねます。
確認後:
cat > /tmp/notion-brief-payload.json << 'ENDJSON'
{
"parent": { "database_id": "NOTION_DATABASE_ID_HERE" },
"properties": {
"Name": {
"title": [{ "text": { "content": "ミーティングブリーフ: COMPANY, DATE" } }]
},
"Date": {
"date": { "start": "YYYY-MM-DD" }
}
},
"children": [
{
"object": "block",
"type": "paragraph",
"paragraph": {
"rich_text": [{ "type": "text", "text": { "content": "BRIEF_CONTENT_HERE" } }]
}
}
]
}
ENDJSON
curl -s -X POST "https://api.notion.com/v1/pages" \
-H "Authorization: Bearer $NOTION_TOKEN" \
-H "Content-Type: application/json" \
-H "Notion-Version: 2022-06-28" \
-d @/tmp/notion-brief-payload.json
投稿後: 「ブリーフが Notion に保存されました。データベースを確認してください。」
Notion が設定されていない場合: ブリーフのみを提示します。Notion については言及しないでください。