会议简报生成器 是做什么的?
输入公司名称和可选联系人。通过 Tavily 研究该公司。使用 Gemini 合成一份一页会前简报。可选择保存到 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)
- 会议日期
可选(缺失时不阻塞流程):
- 联系人姓名和职位
- 会议类型(探索性会议、演示、跟进、季度业务回顾)
- 用户希望涵盖的任何特定主题或目标
如果用户提供了公司 URL 或域名,则使用它来提高 Tavily 查询的精确度(例如,在搜索词中包含 site:example.com 或域名)。
步骤 3:使用 Tavily 进行研究
按顺序运行以下搜索。每个搜索针对简报的一个部分。保存每个搜索的顶级结果(标题、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
}'
如果提供了联系人姓名,请再运行两个搜索:
搜索 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": "You are a GTM research analyst preparing a 1-page pre-call brief for a sales or business development meeting. Rules: Every claim must cite a source URL from the provided research. Use the format 'Because [finding from research], mention [point] to [goal]' for talking points. No invented data. If a section has no research data, write 'Limited public information found.' No em dashes. No banned words. Under 400 words total. The brief must be scannable in 3 minutes."
}]
},
"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:自我质量检查
在展示前检查:
- 没有编造的数据。每个事实都有来自 Tavily 结果的来源 URL。
- 谈话要点使用“因为[研究发现],提及[要点]以[目标]”的格式
- 任何行中都没有长破折号
- 没有禁用词
- 简报总字数小于 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": "Meeting Brief: 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。