AI会议助手搭建指南2026:自动化笔记、摘要和行动项
使用Claude、GPT-4或Gemini构建AI会议助手。自动化转录、生成摘要、提取行动项,并与Zoom、Teams和Google Meet集成。
使用Claude、GPT-4或Gemini构建AI会议助手。自动化转录、生成摘要、提取行动项,并与Zoom、Teams和Google Meet集成。
会议消耗了普通知识工作者每周23小时,但71%的会议被认为是低效的。2026年的AI会议助手已从简单的转录工具转变为能够捕获决策、跟踪承诺并生成可操作见解的智能参与者。
本指南将向您展示如何构建一个完整的AI会议助手,每周节省10+小时。
当前现实:
AI解决方案影响:
核心能力:
```typescript
// AI会议助手架构
interface MeetingAssistant {
// 核心管道
transcriber: SpeechToText; // 音频 → 文本
diarizer: SpeakerDiarization; // 识别说话人
summarizer: MeetingSummarizer; // 生成摘要
extractor: ActionItemExtractor; // 查找承诺
analyzer: MeetingAnalyzer; // 见解和指标
integrator: CalendarIntegration; // 日程和跟进
}
// 会议输出
interface MeetingOutput {
transcript: string;
speakers: Speaker[];
summary: string;
keyDecisions: string[];
actionItems: ActionItem[];
topics: Topic[];
sentiment: SentimentAnalysis;
duration: number;
participants: Participant[];
}
interface ActionItem {
task: string;
assignee: string;
deadline: Date | null;
priority: 'high' | 'medium' | 'low';
status: 'pending' | 'in-progress' | 'completed';
context: string;
}
```
| 使用场景 | 最佳方案 | 成本 | 设置时间 | 准确率 |
|----------|---------|------|---------|--------|
| Zoom会议 | Otter.ai + Claude | ¥140/月 | 30分钟 | 95% |
| Google Meet | Fireflies.ai | ¥70/月 | 15分钟 | 93% |
| Microsoft Teams | Teams Premium | ¥70/用户/月 | 5分钟 | 94% |
| 自定义/多平台 | Whisper + Claude API | ¥350-1050/月 | 6小时 | 96% |
| 注重隐私 | 本地Whisper + Ollama | ¥0(硬件) | 10小时 | 92% |
设置步骤:
```bash
npm install @anthropic-ai/sdk otter-api-client
export ANTHROPIC_API_KEY="your-claude-key"
export OTTER_API_KEY="your-otter-key"
```
会后处理器:
```typescript
import Anthropic from '@anthropic-ai/sdk';
import { OtterClient } from 'otter-api-client';
class MeetingProcessor {
private anthropic: Anthropic;
private otter: OtterClient;
constructor() {
this.anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY
});
this.otter = new OtterClient(ps.env.OTTER_API_KEY!);
}
async processMeeting(meetingId: string): Promise
// 从Otter.ai获取转录
const transcript = await this.otter.getTranscript(meetingId);
// 使用Claude处理
const analysis = await this.analyzeWithClaude(transcript);
// 提取行动项
const actionItems = await this.extractActionItems(transcript);
// 生成摘要
const summary = await this.generateSummary(transcript, analysis);
return {
transcript: transcript.text,
speakers: transcript.speakers,
summary,
keyDecisions: analysis.decisions,
actionItems,
topics: analysis.topics,
sentiment: analysis.sentiment,
duration: transcript.duration,
participants: transcript.participants
};
}
private async analyzeWithClaude(transcript: any) {
const message = await this.anthropic.messages.create({
model: 'claude-sonnet-4-20250514',
max_tokens: 4096,
messages: [{
role: 'user',
content: `分析这个会议转录并提取结构化信息:
${transcript.text}
以JSON格式提供分析:
{
"decisions": ["决策1", "决策2"],
"topics": [
{"name": "主题", "duration": "分钟数", "sentiment": "positive|neutral|negative"}
],
"sentiment": {
"overall": "positive|neutral|negative",
"concerns": ["担忧1"],
"enthusiasm": ["积极点1"]
},
"keyMoments": [
{"timestamp": "MM:SS", "description": "发生了什么", "importance": "high|medium|low"}
],
"nextSteps": ["步骤1", "步骤2"]
}`
}]
});
const response = message.content[0].type === 'text'
? message.content[0].text
: '';
return JSON.parse(response);
}
private async extractActionItems(transcript: any): Promise
const message = await this.anthropic.messages.create({
model: 'claude-sonnet-4-20250514',
max_tokens: 2048,
messages: [{
role: 'user',
content: `从这个会议转录中提取所有行动项:
${transcript.text}
对于每个行动项,识别:
以JSON数组格式响应:
[
{
"task": "需要完成的清晰描述",
"assignee": "人名或'未分配'",
"deadline": "ISO日期或null",
"priority": "high|medium|low",
"context": "会议中的简要上下文",
"confidence": 0.0-1.0
}
]
只包括明确的承诺,不包括模糊的讨论。`
}]
});
const response = message.content[0].type === 'text'
? message.content[0].text
: '';
const items = JSON.parse(response);
return items.map((item: any) => ({
...item,
status: 'pending' as const,
deadline: item.deadline ? new Date(item.deadline) : null
}));
}
private async generateSummary(transcript: any, analysis: any): Promise
const message = await this.anthropic.messages.create({
model: 'claude-sonnet-4-20250514',
max_tokens: 1024,
messages: [{
role: 'user',
content: `生成简洁的会议摘要:
转录: ${transcript.text.substring(0, 3000)}
关键决策: ${analysis.decisions.join(', ')}
讨论主题: ${analysis.topics.map((t: any) => t.name).join(', ')}
创建包含以下内容的摘要:
保持在200字以内,适合高管阅读。`
}]
});
return message.content[0].type === 'text'
? message.content[0].text
: '';
}
}
```
实时会议助手:
```typescript
import { OpenAI } from 'openai';
import Anthropic from '@anthropic-ai/sdk';
import { createWriteStream } from 'fs';
import { spawn } from 'child_process';
class RealtimeMeetingAssistant {
private openai: OpenAI;
private anthropic: Anthropic;
private audioBuffer: Buffer[] = [];
private transcriptBuffer: string = '';
constructor() {
this.openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY
});
this.anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY
});
}
async startRecording(audioSource: string = 'default') {
// 使用ffmpeg录制音频
const ffmpeg = spawn('ffmpeg', [
'-f', 'avfoundation', // macOS(Linux用'alsa',Windows用'dshow')
'-i', `:${audioSource}`,
'-acodec', 'pcm_s16le',
'-ar', '16000',
'-ac', '1',
'-f', 'wav',
'pipe:1'
]);
let audioChunk: Buffer[] = [];
let chunkDuration = 0;
const CHUNK_SECONDS = 30; // 每30秒处理一次
ffmpeg.stdout.on('data', async (data: Buffer) => {
audioChunk.push(data);
chunkDuration += data.length / (16000 * 2); // 16kHz, 16位
if (chunkDuration >= CHUNK_SECONDS) {
const audio = Buffer.concat(audioChunk);
await this.processAudioChunk(audio);
audioChunk = [];
chunkDuration = 0;
}
});
return ffmpeg;
}
private async processAudioChunk(audio: Buffer) {
// 保存到临时文件供Whisper使用
const tempFile = `/tmp/audio-${Date.now()}.wav`;
const writeStream = createWriteStream(tempFile);
writeStream.write(audio);
writeStream.end();
// 使用Whisper转录
const transcription = await this.openai.audio.transcriptions.create({
file: createReadStream(tempFile),
model: 'whisper-1',
language: 'zh',
response_format: 'verbose_json'
});
// 添加到转录缓冲区
this.transcriptBuffer += transcription.text + '\n';
// 每5分钟进行实时分析
if (this.transcriptBuffer.length > 5000) {
await this.realtimeAnalysis();
}
// 清理临时文件
unlinkSync(tempFile);
}
private async realtimeAnalysis() {
const message = await this.anthropic.messages.create({
model: 'claude-sonnet-4-20250514',
max_tokens: 1024,
messages: [{
role: 'user',
content: `分析这个正在进行的会议转录并提供实时见解:
${this.transcriptBuffer}
提供:
保持简洁(150字以内)。`
}]
});
const analysis = message.content[0].type === 'text'
? message.content[0].text
: '';
console.log('\n=== 实时会议见解 ===');
console.log(analysis);
console.log('====================\n');
// 可选:发送到Slack、邮件等
await this.sendRealtimeUpdate(analysis);
}
private async sendRealtimeUpdate(analysis: string) {
// 发送到Slack、Teams、邮件等
// 实现取决于您的通知系统
}
async endMeeting(): Promise
// 最终综合分析
const finalAnalysis = await this.analyzeWithClaude({
text: this.transcriptBuffer
});
const actionItems = await this.extractActionItems({
text: this.transcriptBuffer
});
const summary = await this.generateSummary(
{ text: this.transcriptBuffer },
finalAnalysis
);
return {
transcript: this.transcriptBuffer,
speakers: [],
summary,
keyDecisions: finalAnalysis.decisions,
actionItems,
topics: finalAnalysis.topics,
sentiment: finalAnalysis.sentiment,
duration: 0,
participants: []
};
}
}
```
```typescript
import { Client } from '@notionhq/client';
class NotionMeetingSync {
private notion: Client;
constructor() {
this.notion = new Client({
auth: process.env.NOTION_API_KEY
});
}
async saveMeeting(meeting: MeetingOutput, databaseId: string) {
// 创建会议页面
const page = await this.notion.pages.create({
parent: { database_id: databaseId },
properties: {
'标题': {
title: [{ text: { content: meeting.title } }]
},
'日期': {
date: { start: meeting.date.toISOString() }
},
'时长': {
number: meeting.duration
},
'参与者': {
multi_select: meeting.participants.map(p => ({ name: p.name }))
}
},
children: [
{
object: 'block',
type: 'heading_2',
heading_2: {
rich_text: [{ text: { content: '摘要' } }]
}
},
{
object: 'block',
type:ragraph',
paragraph: {
rich_text: [{ text: { content: meeting.summary } }]
}
},
{
object: 'block',
type: 'heading_2',
heading_2: {
rich_text: [{ text: { content: '行动项' } }]
}
},
...meeting.actionItems.map(item => ({
object: 'block' as const,
type: 'to_do' as const,
to_do: {
rich_text: [{
text: {
content: `${item.task} (@${item.assignee}${item.deadline ? ` - 截止: ${item.deadline.toLocaString('zh-CN')}` : ''})`
}
}],
checked: false
}
}))
]
});
return page.id;
}
}
```
```typescript
import { WebClient } from '@slack/web-api';
class FeishuMeetingNotifier {
private client: any; // 飞书SDK客户端
constructor() {
// 初始化飞书客户端
}
async sendMeetingSummary(meeting: MeetingOutput, chatId: string) {
await this.client.sendMessage({
chat_id: chatId,
msg_type: 'interactive',
card: {
header: {
title: {
content: `📝 会议摘要: ${meeting.title}`,
tag: 'plain_text'
}
},
elements: [
{
tag: 'div',
text: {
content: meeting.summary,
tag: 'plain_text'
}
},
{
tag: 'div',
text: {
content: '关键决策:\n' + meeting.keyDecisions.map(d => `• ${d}`).join('\n'),
tag: 'lark_md'
}
},
{
tag: 'div',
text: {
content: '行动项:\n' + meeting.actionItems.map(item =>
`• ${item.task} - @${item.assignee}${item.deadline ? ` (截止: ${item.deadline.toLocaleDateString('zh-CN')})` : ''}`
).join('\n'),
tag: 'lark_md'
}
}
]
}
});
// 向负责人发送单独消息
for (const item of meeting.actionItems) {
const user = await this.findFeishuUser(item.assignee);
if (user) {
await this.client.sendDirectMessage({
user_id: user.id,
content: `您有来自会议的新行动项:\n\n${item.task}\n${item.deadline ? `截止: ${item.deadline.toLocaleDateString('zh-CN')}` : '未设置截止日期'}\n\n上下文: ${item.context}`
});
}
}
}
private async findFeishuUser(name: string) {
// 查找飞书用户
return null;
}
}
```
| 方案 | 转录 | AI处理 | 总计 | 会议数/月 | 每次会议成本 |
|------|------|--------|------|----------|-------------|
| Otter.ai + Claude | ¥140 | ¥210 | ¥350 | 40 | ¥8.75 |
| Fireflies.ai | ¥70 | 包含 | ¥70 | 40 | ¥1.75 |
| Teams Premium | ¥70 | 包含 | ¥70 | 无限 | ¥0 |
| Whisper + Claude | ¥105 | ¥350-1050 | ¥455-1155 | 60 | ¥7.58-19.25 |
| 本地(Whisper + Ollama) | ¥0 | ¥0 | ¥0 | 无限 | ¥0 |
时间节省:
价值:
- 提前2分钟自动加入会议
- 加载之前的会议上下文
- 准备基于议程的提示
- 实时转录
- 实时行动项检测
- 情绪监控
- 生成摘要(30秒)
- 提取行动项
- 发送给参与者
- 创建日历提醒
- 更新项目管理工具
```typescript
// 实施同意管理
class MeetingConsent {
async requestConsent(participants: string[]): Promise
// 录制前发送同意请求
const responses = await Promise.all(
participants.map(p => this.sendConsentRequest(p))
);
return responses.every(r => r.consented);
}
async handleOptOut(participant: string) {
// 删除参与者的贡献
// 或完全停止录制
}
}
```
❌ 未经同意录制 - 始终获得明确许可
❌ 音频质量差 - 使用好的麦克风,提前测试
❌ 无说话人识别 - 行动项需要明确的所有权
❌ 忽略上下文 - 提供之前的会议笔记以保持连续性
❌ 过度依赖 - AI会遗漏细微差别;分享前审查摘要
2026年的AI会议助手已经可以投入生产并立即带来ROI。从Otter.ai + Claude开始快速获胜,或使用Whisper + Claude构建自定义以获得最大控制。
下一步:
再也不用手动记会议笔记了。