ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Friend 任务捕获不变量 INV-TASK-2 深度解析:捕获只提议、绝不代写任务

Friend 任务捕获不变量 INV-TASK-2 深度解析:捕获只提议、绝不代写任务 Friend 任务捕获不变量 INV-TASK-2 深度解析捕获只提议、绝不代写任务【免费下载链接】FriendAI that sees your screen, listens to your conversations and tells you what to do项目地址: https://gitcode.com/GitHub_Trending/fr/Friend本篇文章围绕 FriendOmi开源仓库中 product/invariants/task-capture-suggestion-only.md 这条被锁定locked的核心不变量展开。它回答一个关键工程问题当 AI 全天候监听对话、连续采样屏幕时如何保证自动捕获的任务永远不会绕过用户直接写进任务列表。读完本文你将掌握捕获策略capture policy的全部输出与信号设计、桌面端与移动端截然不同的任务落盘分界、以及仓库用静态守卫脚本与行为测试锁死这条不变量的完整方案。不变量是什么为什么需要只提议这条铁律一句话定义INV-TASK-2 的完整陈述是屏幕捕获、主动捕获proactive capture和桌面对话捕获永远不会直接写入任务。每一条由此派生的任务都是一条待定pending的 Candidate只有经过一次明确的用户手势才能变成行动项action item没有人处理的 Candidate 会过期失效而不是无限累积。对于没有 Suggested 表面的客户端系统根本不会向其提议其对话提取只写出保守提示词conservative prompt认可的内容没有任何内容符合条件时就什么都不写。翻译成工程语言捕获只负责生成提议propose采纳只能由用户完成accept写库只存在于携带真实用户手势的通道中。数据驱动的起因这份文档之所以被定义为 locked 不变量是因为 2026-08-20 在一次 dogfood内部自用账号上的实测数据触发了告警124 个存活行动项中只有 3 个携带sourcemanual手动来源353 个被接受的 Candidate 中有 340 个是在创建后两秒内被接受的——这不是人类手势而是机器自动接受1,014 个 Candidate 处于 pending 状态且没有过期机制以每天约 100 条的速度增长共有四条独立的代码路径在直接写入自动任务且每一条都是回退路径fallback而非正常路径happy path。这个体量是屏幕捕获的固有属性屏幕捕获是连续采样的天然高产。与之对比对话提取被对话本身所限制并且由提示词把关——提示词只承认明确的 Hey Omi 指令和少数具体承诺否则什么都不返回。但问题在上一级还存在2026-08-23 到 2026-08-30 期间每一台手机、吊坠pendant和手表产生的对话都生成了 Candidate然而没有任何移动端界面可以渲染这些提议它们只在两天后默默过期。这就是本不变量要消灭的失败模式——提议发到了一个无处可看的地方等于制造了一个看不见的丢失任务。十条 MUST NOT可执行的红线清单原文档给出了一组可直接作为代码评审标准的禁令逐条继承并展开如下#禁令工程含义1返回含义为立即创建任务的捕获策略结果auto_accept_silent与create_direct这两个 outcome是被删除的不是被禁用的2在同一请求内创建 Candidate 并接受它任何表面surface都不得创建即接受3在提议表面上当 Candidate 路径不可用/被禁用/出错时回退到行动项写入器应该延迟并重试静默silence是正确的失败方式4让 rollout、workflow 模式或能力默认值把捕获路由到写入器控制端点在其自身读取失败时上报的off必须是无害的inert绝不能变成legacy staging5在捕获投递客户端上暴露接受路径一条可以接受的管道最终一定会被接线使用6让一条被拒绝的提取项拖累其兄弟项进入写入器策略拒绝是**逐条per item**的不是整批的7向没有 Suggested 表面的客户端提议一个无处渲染的 Candidate 既是丢失的任务还浪费存储8给写入表面使用宽松提取提示词没有评审队列时提示词本身就是过滤器9让后端与桌面捕获策略分叉它们共享同一个冻结的 fixture这九条原文第 10 条为 Surfaces 分界见下节共同构成一个自洽的捕获侧零写入权体系策略层删除创建性 outcome、提取层禁止接受调用、客户端协议不暴露 accept、manifest 不允许捕获源声明创建锚点、失败一律静默重试而非降级写库。策略核心实现capture_policy.py 的输出空间仓库用一份确定性共享策略统一所有提取表面实现在 backend/utils/task_intelligence/capture_policy.py。模块 docstring 直接声明了不变量 I1自动提取的任务永远不会被写入用户任务列表。任何会产生工作的捕获结果都是一条用户必须显式接受Add to Tasks的提议。这里刻意不存在含义为立即写任务的 outcome——携带真实用户手势的表面手动创建、chat/MCP 工具调用、开发者 API不运行本策略。全部策略输出CapturePolicyResultoutcome触发信号对应的 CandidateActionpending_candidate显式指令 / 清晰承诺 / 直接请求 / 推断下一步且通过用户捕获底线create新建提议propose_enrichmentduplicate_of重复承诺update扩充既有任务propose_updaterefines_task细化既有任务updatepropose_completionalready_done已完成complete中断方式inline_reviewignore公开广播无人点名、低置信度、无具体交付物、非本人承诺等无直接丢弃不生成提议用户捕获底线_meets_user_capture_floor策略中唯一的硬门槛函数四条必须同时满足owner user第一人称承诺不是转述他人concrete_deliverable is True存在具体交付物且必须是显式 True见下节失败关闭capture_confidence 0.8ownership_confidence 0.8。置信度下限常量MINIMUM_CAPTURE_CONFIDENCE 0.8在 capture_policy.py 定义同时被 What Matters Now 短名单资格recommendations.py 中的MINIMUM_CAPTURE_CONFIDENCE复用。判定顺序优先级从高到低run_capture_policy的判定链是顺序敏感的从源码可见capture_policy.pyalready_done→propose_completionduplicate_of→propose_enrichmentrefines_task→propose_updateexplicit_command→ 通过底线则pending_candidate否则ignore显式口头指令不是环境噪音必须先于 public_broadcast 评估防止第一个产出该信号的 producer 丢掉已通过提取器的指令public_broadcast且无direct_mention→ignoreclear_commitment且 owner 为 user → 无具体交付物则ignore通过底线则pending_candidatedirect_request通过底线 →pending_candidateinferred_next_step通过底线 →pending_candidate推断工作没有比直接请求更弱的通道故意拒绝模糊、无人认领、低置信度的模型建议其余一律ignore。值得注意的注释级设计意图最强的第一人称具体承诺也仅仅换来一条建议suggestion——置信度只决定这条提议值不值得浮出水面永远不能决定它是否可以绕过用户I1。信号输入BackendCaptureSignals 与失败关闭原则策略的输入是一个冻结的信号模型 BackendCaptureSignalsConfigDict(extraforbid)多传字段直接报错explicit_command、clear_commitment、direct_request、inferred_next_step四类捕获意图capture_kindconcrete_deliverable是否具体交付物owner任务归属人TaskOwner枚举public_broadcast/direct_mention公开广播与点名already_done、duplicate_of、refines_task更新类信号capture_confidence/ownership_confidence默认 0.5范围 [0, 1]。两个关键设计点失败关闭fail closed的concrete_deliverable在 conversation_capture_policy.py 中_concrete_deliverable只在提取给出显式True时才成立任何缺失/模糊值都视为 False——宁可不提议不可误提议。唤醒词裁决门WakeWordCaptureGate对话提取中确定性匹配器先定位 Hey Omi 段再由 LLM 裁决器 adjudicate_wake_word_invocations 二次确认。只有明确的不利裁决才把explicit_command降级为direct_request超时、provider 抖动、无重叠调用都保持提取器的原始判定。信号翻译函数capture_signals_for_action_item与端到端评分入口evaluate_action_item_capture_policy位于同一文件保证生产捕获与离线评估hermetic evaluation走同一条受支持策略边界——模块刻意零数据库、零持久化依赖。对话提取适配器逐条拒绝绝不拖累兄弟项conversation_capture.py 是通用 Candidate 生命周期的对话提取适配器核心入口process_before_legacy的 docstring 直接复述不变量对话提取永不写action_item。每条 item 都成为 pending Candidate只有通过显式 Add to Tasks 手势才能进入任务列表。策略拒绝是逐条处理的不是按对话处理的被忽略的 item 只是不被提议不再把兄弟项拖到绕过用户的写入器上。实现细节conversation_capture.py逐条决策先为每条 item 计算_semantic_key规范化描述 owner candidate_action target_task_id due_at 的联合键并统计语义出现次数_semantic_occurrences再逐条跑_capture_decision幂等键conversation:{conversation_id}:item:{purpose}:{semantic_key}:{occurrence}保证重试/重复提取不会生成重复 Candidate提议落库通过candidate_service.create_candidate写入绝不调用任何 accept 路径兼容回退全部置空reconcile_after_legacy与legacy_document_ids返回 None——旧版写完 action_item 再补 sidecar的路径被整体关闭。对应的候选写入端在 database/candidates.py 与 candidate_service.pycreate_candidate需要idempotency_key与account_generationCandidates 的三种动作在 models/candidate.py 定义为create / update / complete。表面的分界线谁提议谁直接写原文档的 Surfaces 一节将系统划分成两半在范围内提议侧受共享捕获策略约束桌面对话提取、共享捕获策略与 Candidate 生命周期桌面屏幕提取、Candidate 投递与建议时刻suggestion moment桌面上的 Suggested 任务投影以及对话摘要行动项列表无 Suggested 表面的客户端上的对话提取——属于写入半场writing half只涉及来源谓词source predicate与保守提示词。范围外直接写不受捕获策略约束Chat、MCP、开发者 API、手动创建——这些通道携带真实用户手势按设计直接写入。这条分界在源码中有一处精确落点process_conversation.py 的_proposes_task_candidatesdef _proposes_task_candidates(conversation: Any) - bool: Whether this conversations action items become Candidates instead of tasks. return getattr(conversation, source, None) ConversationSource.desktop桌面来源的对话 → 提取结果变成 Candidate提议手机、吊坠、手表等其他一切客户端 → 没有 Suggested 表面可渲染提议提取器承认什么、写什么就是什么写任务。这正是文档对无 Suggested 表面的客户端不提议在代码里的具象化谓词按 conversation source 分流。来源清单 manifest写入锚点被结构性禁止backend/config/task_intelligence_sources_v1.json 用policy_class字段给每个任务来源贴标签direct_command携带用户手势允许声明action_items_db.create_action_item等写入锚点如mobile_manual、desktop_manual、chat_voice_tools、mcp_tools、developer_api、mobile_conversation_extractionshared_capture_policy受共享捕获策略约束不得声明任何 create 锚点。其中backend_conversation_extraction与desktop_screen_extraction都是shared_capture_policy前者的写入锚点仅限删除/更新/完成等维护性操作无 create后者TaskAssistant.swift的writer_anchors直接是空数组[]。此外goal_ai_progress、canonical_candidate_resolution同样归属共享策略——任何提议侧来源若在 manifest 里偷偷声明 create 锚点静态守卫会当场失败见下节。桌面端屏幕捕获适配器与 Suggested 表面屏幕提取适配器协议里根本没有 accept桌面屏幕提取适配器 ScreenCandidateAdapter.swift 定义了投递客户端协议protocol CanonicalScreenCandidateClient { func create( _ candidate: OmiAPI.CandidateCreate, idempotencyKey: String, accountGeneration: Int ) async throws - CanonicalScreenCandidateState }该协议只暴露create没有accept——MUST NOT 第 5 条不要暴露接受路径的直接实现一条能接受accept的投递管道迟早会被接线成自动接受。代码注释I1同时声明屏幕读出的任何指令都只能进入ScreenCaptureOutcome提议不得创建任务。屏幕侧还有TaskLegacyEffectGate读取 workflow control 的workflowMode确保没有任何 workflow 模式允许 legacy 效果生效。Suggested 任务投影接受是唯一手势桌面端的建议任务存储 SuggestedTasksStore.swift 中的SuggestedTasksClient协议完整呈现了提议侧 手势侧的职责分离listCanonicalCandidates(status:limit:)拉取候选acceptCanonicalCandidate/rejectCanonicalCandidate用户的接受/拒绝手势registerTaskIntervention、recordTaskFeedback干预与反馈回传。对应的 Swift 测试 TaskIntelligenceContractFixtureTests.swift 从三处锁死行为没有 workflow 模式允许 legacy 效果投递在两次尝试中都让提议保持 pendingXCTAssertEqual(beforeCrash?.status, .pending)捕获管道没有任何接受方式——客户端协议不再提供。保守提示词写入表面的过滤器MUST NOT 第 8 条说没有评审队列时提示词就是过滤器。这在 conversation_processing.py 中有直接对应task_intelligence_capture布尔开关由_proposes_task_candidates注入决定提取提示词的两种模式约 L756-L813捕获模式桌面capture clear commitments and direct requests——承认明确承诺与直接请求保守模式无 Suggested 表面客户端apply the conservative legacy task filter、When in doubt, DONT extract - be conservative and selective、Be conservative only with model-inferred next steps。换句话说桌面靠界面承载提议移动端靠更严的提示词把不可见提议提前过滤掉——两条路线最终都指向用户看不到的东西不许落成任务。守护体系一份冻结 fixture 六组测试 静态守卫原文档的 Guard tests 一节列出的守护全部存在于仓库中守护类型验证内容.github/scripts/check_task_capture_authority.py静态无创建性 outcome、提取侧无 accept、捕获客户端无 accept、共享策略来源无 create 锚点.github/scripts/test_check_task_capture_authority.py静态证明守卫对每个真实出现过的缺陷形态都会失败backend/tests/unit/test_conversation_suggestion_visibility.py行为每种被承认的捕获类型都能到达 Suggested 表面backend/tests/unit/test_backend_candidate_capture.py行为桌面对话提议但绝不接受/写入被拒绝项单独丢弃其他客户端对话写任务且不提议backend/tests/unit/test_task_intelligence_contract_freeze.py契约冻结 fixture 的 outcome 与创建性 outcome 保持不相交backend/tests/unit/test_process_conversation_usage_context.py行为捕获上报本身不可用时仍不触碰写入器TaskIntelligenceContractFixtureTests.swift契约无 workflow 模式允许 legacy 效果投递后提议保持 pending静态守卫如何工作check_task_capture_authority.py 是 stdlib-only、无网络、由.github/checks-manifest.yaml接线的 CI 守卫检查四类结构事实每类都是真实发生过的缺陷形态Python 策略用正则匹配CapturePolicyResult(后紧跟auto_accept_silent/create_direct的构造——注意是匹配构造而非单词因为合法文件可以在注释里解释这两个 outcome 为何不存在对话适配器禁止出现candidate_service.accept_candidate(调用Swift 屏幕适配器禁止return .autoAcceptSilent/.createDirect且CanonicalScreenCandidateClient协议体内禁止声明func accept(来源 manifest任何policy_class shared_capture_policy的来源若声明action_items_db.create_action_item/create_action_items_batch创建锚点即失败——提议源无法在不触发守卫的前提下获得写入器。冻结的 fixturecapture_v2.jsonbackend/tests/unit/fixtures/task_intelligence/capture_v2.json 是后端与桌面共享的冻结捕获契约policy_version: capture.v2其中的 outcome 期望是行为测试与 Swift 契约测试的共同输入。从 fixture 可见代表性用例的期望结果用例信号特征期望 outcomeexplicit_create显式指令pending_candidateclear_commitment / immediate_commitment清晰承诺pending_candidateclear_commitment_low_confidence承诺但低于置信底线ignoreclear_commitment_without_deliverable承诺但无具体交付物ignoreunaccepted_request未获接受的请求pending_candidateowned_direct_request_at_confidence_floors刚好踩在置信底线上pending_candidateowned_direct_request_below_ownership_floor归属置信度不足ignoreinferred_next_step推断步骤模糊ignoreowned_concrete_inferred_next_step本人 具体交付物 高置信pending_candidateduplicate_commitment重复承诺propose_enrichmentrefinement细化既有任务propose_updatealready_done已完成propose_completioninline_reviewpublic_channel_not_owned公开频道非本人ignore同一 fixture 还包含唤醒词丢弃用例wake_word_discard_cases验证含 Hey Omi 标记的短指令不被整体丢弃与唤醒词裁决用例如embedded_command_mid_meeting一场 120 秒会议中只有meeting-18段命中命令。行为测试 test_backend_candidate_capture.py 默认构造ConversationSource.desktop对话文件头注释this file covers the surface that still proposes Candidates并通过_save_action_items同时跑通桌面提议与移动端写任务两条路径。路径清单与 PR 规则触碰以下路径的 PR 必须在 PR 描述中标注不变量 IDINV-TASK-2backend/utils/task_intelligence/capture_policy.pybackend/utils/task_intelligence/conversation_capture.pybackend/utils/task_intelligence/backend_capture.pybackend/utils/conversations/process_conversation.pybackend/database/candidates.pybackend/routers/candidates.pybackend/routers/staged_tasks.pybackend/config/task_intelligence_sources_v1.jsonbackend/tests/unit/fixtures/task_intelligence/capture_v2.jsondesktop/macos/Desktop/Sources/ProactiveAssistants/Assistants/TaskExtraction/目录desktop/macos/Desktop/Sources/MainWindow/Tasks/SuggestedTasksStore.swift小结一条不变量如何塑造整套任务体系INV-TASK-2 的工程价值可以浓缩为三层不可能策略层不可能输出创建性结果删除而非禁用auto_accept_silent/create_direct、提取层不可能调用接受conversation_capture.py无 accept 调用、客户端协议不可能暴露接受路径CanonicalScreenCandidateClient只有create。再叠加 manifest 对捕获源 create 锚点的结构性禁止、保守提示词对无评审界面客户端的过滤以及桌面提议、移动端写库的 source 谓词分流最终形成一套无论哪条代码路径都绕不过用户的手势闭环机器负责发现与提议用户负责裁决与落库过期负责清场。对于正在设计 AI 主动式任务系统的团队这套确定性共享策略 冻结契约 fixture 静态结构守卫 双端契约测试的组合是极具参考价值的模板。【免费下载链接】FriendAI that sees your screen, listens to your conversations and tells you what to do项目地址: https://gitcode.com/GitHub_Trending/fr/Friend创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表