Tana:把会议结论变成可确认、可追踪的动作
Tana 是团队 AI 会议平台,将通话、转写、文档和任务连在一起。讨论可以形成待确认的动作,接受后送到连接的工作工具,并持续显示执行结果。
先尝试拆解问题、设计和实现,再展开思路,检查状态、边界与取舍,并设计验证用例。思路提供分析路径,不给出完整实现。
01
代码思考进阶
三方合并怎样保留同事与 AI 各自的改动?
练习场景
AI 根据旧文档提出字段修改时,同事可能已经改了当前文档。设计一个纯内存“三方合并”分析器:同时看原始版本 base、当前版本 current、AI建议版本 proposed,保留互不冲突的改动,并找出需要人决定的字段。它只生成合并建议,不保存文档、不调用外部工具。这是自拟协议,不是 Tana 的内部实现。
输入与判定
- base、current、proposed 都是 JS Map,每份最多100,000个条目。键为非空字符串;值只能为字符串、安全整数、布尔值或null。拒绝NaN、Infinity、对象、数组、undefined等其他值。三份Map及其值只读。
- “键不存在”与“键存在且值为null”不同。比较字段状态时,先比较存在性;都存在时用严格相等比较值,数字0与-0视为相等,false与0不同。没有嵌套对象、数组合并、字段改名或文本行内合并。
- 对三份输入的每个键:若current和proposed相同,直接保留该状态;否则若current等于base,采用proposed;否则若proposed等于base,保留current;三者均不能按以上规则处理时,标记冲突。删除也按“不存在”这个状态参与比较。
- 遍历顺序是base中的键顺序,再接current中新出现的键,最后接proposed中新出现的键,每个键只出现一次。无冲突时输出mergedEntries及相对current的changes;changes包含set(key,value)或delete(key),沿用此顺序。mergedEntries不包含最终不存在的键。
- 若有任何冲突,只输出所有冲突及每份版本的存在性和值,不输出mergedEntries或changes,避免把半份建议当作整体结果。输入非法则返回带版本/字段位置的错误,连冲突列表也不返回。完整校验三份Map后再分析;空Map合法。
- 总条目数为n,输入键和值字符串的总字符长度为L。任意合法键包括__proto__都按普通ID处理,输出使用条目数组或安全容器。
小例子
base按顺序为 title=旧标题、owner=小林、priority=2、note=null。 current按顺序为 title=旧标题、owner=小梅、priority=2、note=null、tag=web。 proposed按顺序为 title=新标题、owner=小林、priority=1;没有note和tag键。
请给出mergedEntries和changes,并解释为什么同事新增的tag被保留、note被删除、owner不会被AI旧值覆盖。
独立检查变体:(a) proposed.owner改为小周;(b) current.note改为“需要回电”,proposed仍删除note;(c) current.title也改为新标题;(d)任一值为NaN。说明哪些返回合并、哪些返回冲突、哪些属于非法输入。
交付物
描述状态表示、完整校验、稳定键顺序、字段判定和全有或全无的输出方案。至少列出四个不变量,分析n和L的时间空间;可以讨论JS Map或Rust中的可选值,不给完整代码或逐行伪代码。
查看思路
- 把缺失作为独立状态。 先用Map.has判断存在性,再读取值;不能用null或undefined替代“没有这个键”。验证三份输入的所有键和值,非法输入优先于冲突分析。
- 建立稳定的键并集。 依次扫描base、current、proposed,用集合记录已见键,保留首次出现顺序。用户键不写入普通对象属性,__proto__不会成为特殊通道。
- 区分共同结果、单方变化和冲突。 current与proposed一致时无需争执;只有AI改过就采用AI,只有同事改过就保留同事;两边相对base作了不同变化才交给人。缺失状态让新增、删除与null都遵守同一套判定。
- 相对current生成变化,冲突时整体不提交。 主例合并为title=新标题、owner=小梅、priority=1、tag=web;changes依次是set title、set priority、delete note。tag在base和proposed都缺失,属于同事单方新增。a冲突owner;b冲突note;c仍可合并但changes不再包含title;d是输入错误,不返回冲突或部分结果。
- 验证不变量与成本。 current=proposed时changes为空;proposed=base时保留current;current=base时采用proposed;任一冲突不输出部分合并;输入不变且顺序稳定。平均Map/集合操作下O(n)次结构操作,每个字段只作常数次状态与值比较,字符工作按L计,期望O(n+L)时间及O(n+L)空间。冲突清单不意味着可以自动覆盖并发变化;真正保存仍需另行检查版本。