用大模型做一个会选模板的会议纪要 Agent
用大模型做一个会选模板的会议纪要 Agent
先看一个输入。
今天同步支付系统改造项目进度。支付回调接口开发已经完成 80%,但和渠道网关联调时出现偶发超时。王强需要明天上午前完成日志排查。需求方希望回调消息新增 channelName 字段,讨论后决定一期不加。测试环境还没有完成数据初始化,陈敏需要在 6 月 2 日下班前准备好商户、订单和退款数据。原定 6 月 3 日联调调整到 6 月 5 日。
我们希望 Agent 输出的不是一段“看起来还行”的总结,而是一份能直接发出去的纪要:
# 项目周会纪要
会议主题:支付系统改造项目周会
会议时间:2026-06-01 10:00
会议地点:腾讯会议
主持人:张伟
记录人:李娜
参会人:张伟、李娜、王强、陈敏
## 会议总结
本次会议同步了支付系统改造项目进度,确认接口联调延期风险,并明确了测试环境准备、网关异常排查和需求变更确认等事项。
## 待办事项
| 事项 | 负责人 | 截止时间 | 优先级 | 状态 |
|---|---|---|---|---|
| 排查网关超时问题 | 王强 | 2026-06-02 | 高 | 待处理 |
| 完成测试环境数据初始化 | 陈敏 | 2026-06-02 | 高 | 待处理 |
这篇文章会做一个可运行的会议纪要 Agent。用户上传或粘贴一份会议过程记录,Agent 自动判断会议类型,选择对应纪要模板,再填充主题、时间、地点、参会人、会议总结、结论、风险、未决问题和待办事项。
为什么不是简单总结
会议纪要的难点不是“把话变短”。真正难的是三件事。
第一,会议类型不同,纪要结构不同。项目周会要突出进度、风险和下周计划;需求评审要突出范围、争议点和变更项;技术评审要突出方案、架构决策和风险;客户沟通要突出诉求、承诺和跟进。
第二,会议记录通常很乱。发言顺序不等于纪要顺序,待办可能散在段落中,负责人和截止时间也可能靠上下文推断。
第三,企业场景不能让模型乱编。原文没有的信息要标记“待补充”,不能为了纪要完整而补故事。
所以我们把系统拆成四步:
会议过程记录
-> LLM 分析会议类型
-> 选择模板
-> 抽取结构化 JSON
-> 渲染 Markdown 纪要
Agent 设计
这个 Agent 不把所有事情都丢给模型。模型负责最擅长的部分:理解上下文、分类、抽取。程序负责稳定性:模板管理、字段兜底、Markdown 渲染、文件输出。
工程结构如下:
meeting-minutes-agent/
agent.py
meeting_agent/
agent.py
llm_client.py
models.py
prompts.py
renderer.py
templates.py
samples/
project_weekly.txt
requirement_review.txt
tech_review.txt
tests/
test_agent.py
README.md
llm_client.py 使用 OpenAI-compatible Chat Completions 接口,不绑定某个 SDK。只要你的模型服务兼容 /chat/completions,就可以通过环境变量切换。
$env:OPENAI_API_KEY="你的 API Key"
$env:OPENAI_BASE_URL="https://api.openai.com/v1"
$env:OPENAI_MODEL="gpt-4.1-mini"
模板设计
模板不是为了把输出做漂亮,而是为了约束信息结构。
代码里内置了六类模板:
TEMPLATES = {
"project_weekly": "项目周会纪要",
"requirement_review": "需求评审纪要",
"tech_review": "技术方案评审纪要",
"customer_sync": "客户沟通纪要",
"retrospective": "复盘会议纪要",
"decision_meeting": "决策会议纪要",
}
比如技术方案评审模板关注方案背景、技术决策、风险与行动项;需求评审模板关注需求背景、讨论要点、评审结论和未决问题。模板的差异会进入 prompt,让模型在抽取前先理解“这是什么会”。
让模型输出稳定 JSON
纪要 Agent 最怕模型输出一大段自然语言,后续程序没法稳定处理。所以 prompt 里明确要求:
1. 只输出 JSON,不要输出 Markdown。
2. 不要编造原文不存在的信息;缺失字段填“待补充”。
3. meeting_type 必须从固定枚举中选择。
4. action_items 每项必须包含 task、owner、deadline、priority、status。
期望 JSON 结构如下:
{
"meeting_type": "requirement_review",
"topic": "会员积分一期需求评审",
"time": "2026-06-01 14:00",
"location": "会议室 A",
"host": "陈敏",
"recorder": "赵磊",
"participants": ["陈敏", "赵磊", "刘洋"],
"background": "评审会员积分一期需求范围。",
"summary": "会议确认积分获取、消耗和过期规则,折扣叠加规则待确认。",
"discussion_points": ["积分获取按实际支付金额计算"],
"decisions": ["一期支持积分抵扣,不支持积分转赠"],
"risks": ["折扣叠加规则影响结算口径"],
"open_questions": ["优惠券和积分是否可同时使用"],
"action_items": [
{
"task": "确认折扣叠加规则",
"owner": "刘洋",
"deadline": "2026-06-03",
"priority": "高",
"status": "待处理"
}
],
"next_meeting": "待补充"
}
程序拿到 JSON 后,再用本地渲染器填入 Markdown 模板。这样做的好处是:模型负责理解,程序负责格式。
核心代码
Agent 主流程很短:
class MeetingMinutesAgent:
def __init__(self, llm_client, output_dir="outputs"):
self.llm_client = llm_client
self.output_dir = Path(output_dir)
def run(self, raw_notes: str) -> Path:
messages = [
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": build_user_prompt(raw_notes)},
]
raw_result = self.llm_client.complete_json(messages)
minutes = _parse_minutes(raw_result)
output = render_minutes(minutes)
self.output_dir.mkdir(parents=True, exist_ok=True)
path = self.output_dir / f"{_slug(minutes.topic)}.md"
path.write_text(output, encoding="utf-8")
return path
这段代码刻意没有复杂框架。因为这类 Agent 的第一版,最重要的是把边界划清楚:
- Prompt 负责约束模型行为。
- LLM Client 负责调用模型。
- Template 负责会议类型和结构。
- Renderer 负责输出格式。
- Agent 负责串联流程。
renderer.py
from meeting_agent.models import MinutesTemplate
TEMPLATES = {
"project_weekly": MinutesTemplate(
key="project_weekly",
title="项目周会纪要",
focus="同步进度、风险、阻塞和下周计划。",
sections=["会议总结", "项目进展", "关键结论", "风险与阻塞", "待办事项", "下次会议"],
),
"requirement_review": MinutesTemplate(
key="requirement_review",
title="需求评审纪要",
focus="确认需求范围、业务规则、争议点和变更项。",
sections=["会议总结", "需求背景", "讨论要点", "评审结论", "未决问题", "待办事项"],
),
"tech_review": MinutesTemplate(
key="tech_review",
title="技术方案评审纪要",
focus="记录技术方案、架构决策、风险、评审意见和行动项。",
sections=["会议总结", "方案背景", "讨论要点", "技术决策", "风险与阻塞", "待办事项"],
),
"customer_sync": MinutesTemplate(
key="customer_sync",
title="客户沟通纪要",
focus="沉淀客户诉求、承诺事项、风险提醒和跟进动作。",
sections=["会议总结", "客户诉求", "沟通要点", "确认事项", "风险提醒", "跟进事项"],
),
"retrospective": MinutesTemplate(
key="retrospective",
title="复盘会议纪要",
focus="还原目标、结果、问题原因和改进动作。",
sections=["会议总结", "目标与结果", "问题复盘", "原因分析", "改进动作", "后续跟踪"],
),
"decision_meeting": MinutesTemplate(
key="decision_meeting",
title="决策会议纪要",
focus="记录决策背景、备选方案、最终决定和影响范围。",
sections=["会议总结", "决策背景", "备选方案", "最终决定", "影响范围", "待办事项"],
),
}
def choose_template(meeting_type: str) -> MinutesTemplate:
return TEMPLATES.get(meeting_type, TEMPLATES["project_weekly"])
def template_catalog() -> str:
lines = []
for template in TEMPLATES.values():
lines.append(f"- {template.key}: {template.title},适合{template.focus}")
return "\n".join(lines)
运行
进入工程目录:
cd meeting-minutes-agent
配置环境变量后运行:
python agent.py --sample project_weekly
python agent.py --sample requirement_review
python agent.py --sample tech_review
处理自己的会议记录:
python agent.py --input my_meeting.txt
输出文件会生成在 outputs/ 目录。
企业落地还要补什么
这份源码是最小可运行版本。进入企业场景,通常还要补五类能力。
第一,人工确认。待办事项、负责人、截止时间最好进入确认页,让记录人一键修改后再发布。
第二,权限和脱敏。会议记录可能包含客户信息、价格、合同条款和人事信息。上传前或入库前要做敏感字段识别。
第三,模板配置化。不同部门的纪要格式不一样,模板应该从配置中心或数据库读取,而不是长期写死在代码里。
第四,质量校验。可以增加一个二次检查 Agent,专门判断纪要是否遗漏结论、是否编造信息、待办是否缺负责人。
第五,办公系统集成。Markdown 可以继续转换为 Word,也可以对接飞书、钉钉、企业微信或知识库,形成从会议到任务跟踪的闭环。
小结
会议纪要 Agent 的核心不是“总结会议”,而是把会议记录变成可执行的信息结构。
一个实用的实现路径是:让大模型做理解和抽取,让程序做模板、校验和渲染。这样既能利用大模型的语义能力,又能保留工程系统需要的稳定性。
更多推荐




所有评论(0)