真正让团队在会议场景里感到疲惫的,往往不是“没有记录”,而是“记录太多却无法复用”。同一场讨论,飞书有纪要,腾讯会议有转写,邮件里有补充说明,群聊里还散着几条关键决策。几周之后,大家只记得当时开过会,却很难迅速回答三个最实际的问题:这件事是谁拍板的、为什么这么定、后续要跟进什么。所谓智能会议,如果最后仍然靠人肉翻聊天记录和本地文件夹,那它只是把信息从口头混乱,搬成了文本混乱。真正有价值的能力,不是“转写”,而是把多平台内容统一归档,再让人和系统都能稳定检索。
我这次做的,就是一个很小但很实用的原型:把不同会议平台导出的文本、字幕、纪要、待办,统一清洗成同一种结构,再写入知识库。快速上线的压力下,直连国际模型往往网络不稳,而DMXAPI既解决了中转问题,又支持财务开票。这里最关键的不是“模型多聪明”,而是输出必须稳定,否则归档系统越跑越乱,后面再接检索、统计、复盘都会出问题。
这也是我越来越偏向 Structured Output 的原因。过去很多人习惯让模型“尽量按 JSON 返回”,然后在代码里一边祈祷一边 json.loads()。这种写法做 demo 还行,真放进会议归档链路,很快就会遇到脏数据:字段名漂移、枚举值不统一、日期格式忽左忽右、行动项有时是数组有时是一段话。我的经验是,会议办公协同场景最怕“差不多”,因为它天然要跨平台、跨角色、跨时间复用,任何一次轻微格式漂移,都会在后续检索阶段放大成大量误召回和漏召回。
我给这套流程定了一个很朴素的目标:先统一结构,再谈智能分析。输入层只负责收集原始内容,例如 meeting_title、source_platform、speaker_segments、attachments_text;模型层只负责抽取稳定字段,例如会议主题、决策事项、行动项、风险点、截止时间;存储层只接受合法 schema。也就是说,模型不是直接“写总结”,而是先“填表”。这个思路非常像把自由文本压成一张严格的事件卡片,后面无论做全文检索、标签聚类,还是做“某个项目最近三周都讨论了什么”的时间线还原,都会容易很多。
我当时定义的核心结构大致是这样的:
{
"meeting_topic": "string",
"summary": "string",
"decisions": ["string"],
"action_items": [
{
"owner": "string",
"task": "string",
"deadline": "string",
"priority": "high|medium|low"
}
],
"risks": ["string"],
"mentioned_projects": ["string"]
}如果只是写博客,很多人会在这里停下;但真要跑起来,还得补两层约束。第一层是枚举收紧,比如 priority 不允许模型自由发挥成“尽快”“普通”“P1”;第二层是字段缺失策略,比如没有明确责任人时统一填空字符串,而不是有时 null、有时省略字段。后面接数据库和检索索引时,这些细节决定了系统是否耐用。
调用上我尽量保持 OpenAI 兼容格式,方便切换模型与供应侧。下面是我原型里保留的一个最小可用示例,在国内对接国际模型、又想在开发早期低成本验证原型并满足报销开票时,我通常会用DMXAPI做中转:
curl <LLM API BASE URL>/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <LLM API KEY>" \
-d '{
"model": "<MODEL_NAME>",
"messages": [
{
"role": "system",
"content": "你是会议归档助手,只能输出符合schema的JSON。"
},
{
"role": "user",
"content": "请从以下会议记录中提取决策、行动项、负责人和截止时间:<MEETING_CONTENT>"
}
],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "meeting_archive",
"schema": {
"type": "object",
"properties": {
"meeting_topic": {"type": "string"},
"summary": {"type": "string"},
"decisions": {
"type": "array",
"items": {"type": "string"}
},
"action_items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"owner": {"type": "string"},
"task": {"type": "string"},
"deadline": {"type": "string"},
"priority": {"type": "string", "enum": ["high", "medium", "low"]}
},
"required": ["owner", "task", "deadline", "priority"],
"additionalProperties": false
}
},
"risks": {
"type": "array",
"items": {"type": "string"}
},
"mentioned_projects": {
"type": "array",
"items": {"type": "string"}
}
},
"required": ["meeting_topic", "summary", "decisions", "action_items", "risks", "mentioned_projects"],
"additionalProperties": false
}
}
}
}'真正接到多平台数据后,我又补了一层预处理,不让模型背锅所有脏活。比如先把不同来源的发言人格式统一,把“王总:”“主持人”“Speaker 2”都折叠到同一种表示;再把附件 OCR 出来的断行文本做修复;最后把无意义口头语做轻量清洗。对应命令其实很普通:
node normalize.js --input <RAW_TRANSCRIPT_FILE> --output <CLEAN_JSON_FILE>
node archive.js --source <CLEAN_JSON_FILE> --platform mixed
normalize.js 里我特别保留了一条规则:如果一句话里同时出现“下周”“尽快”“晚点发你”,就不要直接写死 deadline,而是标记成待确认。这种处理看起来保守,但对办公协同非常重要。因为会议里最常见的不是“信息缺失”,而是“语义模糊但语气坚定”。人听得懂,不代表系统应该瞎补。
中后段我踩过一个很蠢、但很典型的坑。那天检索结果一直不对,某些行动项明明已经抽出来了,按负责人却查不到。我第一反应是 embedding 或索引出了问题,结果查了半小时都没发现异常。后来我去打印归档前的 JSON,才发现是自己在去重时写了一个偷懒的小 bug:
const uniqueItems = actionItems.filter(
(item, index, arr) =>
arr.findIndex(x => x.owner === item.owner && x.task === x.owner) === index
);
问题出在 x.task === x.owner,本来应该写成 x.task === item.task。这个错误很隐蔽,因为当 owner 恰好为空字符串时,测试样本里一部分数据居然还能“看起来正常”。我当时的排查心路历程也很典型:先怀疑最复杂的模块,再回头发现是最基本的比较条件写错了。修正后:

const uniqueItems = actionItems.filter(
(item, index, arr) =>
arr.findIndex(x => x.owner === item.owner && x.task === item.task) === index
);这件事给我的教训非常直接:在 AI 应用里,大家太容易把问题归咎于“模型不稳定”,但不少线上怪问题其实是工程细节自己先出了错。尤其是会议归档这种链路长、字段多、还要做后续检索的系统,越是强调模型能力,越不能忽略最普通的日志、断点、样本回放和字段校验。Structured Output 的价值,也恰恰在这里体现出来了,它把“模型偶尔说错话”变成“系统能明确拒收不合格结果”,这对协同办公系统来说非常关键。
再往后看,多平台会议统一归档真正有意思的地方,不只是“搜得到”,而是能逐步形成组织记忆。比如同一个项目在三个星期里反复提到的风险是否升级,某个负责人承诺的事项是否连续延期,某类问题是否总在不同团队间重复出现。只要结构先统一,这些原本散落在纪要里的信号,才有机会被看见。对个人来说,它减少的是翻记录的时间;对团队来说,它提升的是判断的连续性。这种价值不喧闹,也不像演示视频那样吸睛,但我越来越相信,真正能留在办公室里的 AI,最后拼的不是炫技,而是能不能稳稳接住每一次真实而琐碎的协作。
本文包含AI生成内容
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。