它打不开了,帮我看一下。

企业产品里的很多任务,都从这样一句缺少上下文的话开始。

有一次,我把一份 AI 诊断产品的初步设计交给生成式工具做页面。几分钟后,页面里出现了候选场景、五段推理过程、置信度、知识命中和一组漂亮的决策卡。

它比我的原稿更像一套成熟产品。

我顺着页面逐项往后问:置信度由谁计算?候选场景从哪里来?链路节点有没有完整配置?用户没有提供时间,日志检索该查哪个窗口?

很多问题没有答案。页面已经替后端作出了决定,数据和规则还没跟上。

最后,我们删掉了一部分看起来很聪明的内容,只保留轻量候选、缺失信息提示和用户确认。这个删改把注意力带回了一个更基础的问题:当用户只说一句含糊的话时,系统究竟拿什么去驱动后面的工具、知识和流程?

在这篇笔记里,我暂且把这个对象称为 可执行上下文(Executable Context),用来指代一份可确认、可执行、可追溯的任务上下文。

✦ 核心判断

企业 Agent 的第一层产品能力,是把模糊意图整理成一份可确认、可执行、可追溯的任务上下文。聊天、表单、工具、RAG 和评测都围绕这份上下文协作。

一句话为什么还不能执行

用户很少会按系统需要的格式描述问题。

在故障诊断里,他可能只说:

验收环境里登录一直失败,页面提示网络异常,帮我看一下。

这句话表达了困扰,还没有形成任务。系统至少需要继续确认:

  • 哪个环境和业务场景
  • 大致发生在什么时间
  • 有什么可以检索的关键字
  • 用户看到的是页面提示、接口错误,还是一段日志
  • 哪些应用或节点可能相关
  • 当前证据能支持多强的结论

同样的问题也会出现在其他企业场景。

销售说帮我看看这个客户,合同人员说这条有风险,客服说用户一直投诉扣费,运营说昨天转化突然掉了。人能凭上下文理解这些话,系统需要一份明确的任务对象,才能决定下一步查什么、问什么、调用什么。

如果没有这个对象,每个环节都会重新猜一遍用户的意思。对话猜一次,工具参数再猜一次,报告生成时又猜一次。最后的答案可能很流畅,执行链路里却混入了几套不同的假设。

一份 Context Contract 应该有什么

我在光溯的公开 Demo 里,把自然语言入口和结构化检索入口汇入同一份 DiagnosticContext。换到其他领域,可以把它改名为 TaskContextCaseContextOpportunityContext。名称并不重要,重要的是它成为系统各环节共享的合同。

下面是一份经过简化的通用结构:

task_id: TASK-001
raw_input:
  text: "验收环境里登录一直失败,页面提示网络异常"
  attachments: []

intent:
  type: "incident_diagnosis"
  source: "model_extraction"
  confidence: "medium"

facts:
  environment:
    value: "验收环境"
    status: "confirmed"
    source: "user"
  business_scenario:
    value: "登录"
    status: "extracted"
    source: "user_text"
  time_window:
    value: null
    status: "missing"
  searchable_key:
    value: null
    status: "missing"

candidates:
  - id: "SCENE-LOGIN-01"
    label: "移动端登录"
    status: "awaiting_confirmation"

execution:
  current_stage: "context_completion"
  allowed_next_actions:
    - "ask_for_time_window"
    - "ask_for_searchable_key"
    - "confirm_candidate_scene"

evidence: []
decision:
  conclusion: null
  strength: "insufficient"
  next_actions: []

这份结构包含五类信息:

  1. 原始输入:保留用户最初说了什么,避免后续只剩模型摘要。
  2. 事实槽位:记录字段值、来源和确认状态。
  3. 候选与不确定性:系统可以提出可能性,同时保留用户确认权。
  4. 执行状态:明确当前阶段和允许发生的下一步动作。
  5. 证据与决策:结论必须能回到日志、文档、工具结果或用户确认。

这也是合同一词的含义。前端知道该展示哪些待确认字段,Workflow 知道下一步可以走哪条边,Tool 知道参数从哪里取,RAG 知道需要检索哪个领域,Trace 和 Eval 也能读取同一份状态。

把信息分成五种状态

很多 Agent 产品只给字段加一个 confidence。一个 0.87 的数字看起来精确,却没有告诉用户这个字段来自哪里,也没有说明接下来能否使用。

我更倾向于先区分信息状态:

状态 含义 产品动作
observed 工具或附件中直接观察到 保留原始来源,可进入证据池
extracted 模型从用户输入中提取 展示给用户,按风险决定是否确认
confirmed 用户或确定性系统已确认 可作为后续执行参数
inferred 系统结合多项证据推断 展示依据与结论强度,不覆盖事实
missing 当前任务需要但尚未获得 发起追问、换工具,或进入降级路径

这几个状态解决了一个常见混乱:系统识别到什么、用户确认了什么、工具证明了什么、模型推断了什么,应该分别记录。

比如页面提示网络异常,只能作为用户观察到的现象。网络工具返回连通性正常后,系统仍需检查目标服务和应用依赖。它不能因为提示里有网络两个字,就提前把问题归为网络故障。

不确定性应该改变界面

不确定性很难靠一个百分比被用户理解。它更适合直接改变下一步交互。

  • 缺少关键字段:继续追问。
  • 出现多个合理候选:展示少量候选,让用户确认或拒绝。
  • 工具结果冲突:保留候选集合,提示需要补充证据。
  • 证据不足:明确无法收敛,转人工或结束任务。
  • 高风险写操作:在执行前展示对象、影响范围和回退方式。

这个设计让 Human-in-the-loop 成为流程的一部分。用户的确认直接承担三件事:修正上下文、控制风险、产生新的标注数据。

同一个上下文,服务两类用户

企业软件里常见两类用户。

一类用户知道业务现象,不熟悉系统结构。他们适合从自然语言开始,由 Agent 帮忙补齐条件。

另一类用户熟悉应用、字段和工具。他们更希望直接选择环境、节点、时间窗口和检索条件。

这两类入口可以共存:

flowchart LR
    A["自然语言 / 截图"] --> C["Context Builder"]
    B["结构化表单 / 专业检索"] --> C
    C --> D{"关键字段是否足够"}
    D -->|否| E["追问 / 候选确认"]
    E --> C
    D -->|是| F["Task Context"]
    F --> G["Workflow 路由"]
    F --> H["Tools"]
    F --> I["RAG"]
    G --> J["Evidence Pool"]
    H --> J
    I --> J
    J --> K["Decision / Next Action"]
    F --> L["Trace & Eval"]
    J --> L
    K --> L

自然语言入口帮助用户构造上下文,结构化入口让专家直接编辑上下文。后续执行层只接收同一种任务对象。这样做能减少重复逻辑,也让历史任务可以在两种入口之间恢复和继续。

让上下文成为单一事实源

一份字段表很容易写。真正困难的是约束每个组件如何读写它。

我会给 Context Contract 加五条规则。

1. 保留原始值,也保留标准值

用户说四套环境,系统可以映射成标准环境 ID。两者都要保留。原始值用于回放和解释,标准值用于工具调用。

2. 每个字段都记录来源

来源至少要区分用户、附件解析、模型提取、知识检索、确定性工具和人工审核。最终报告引用证据时,系统才知道哪些内容可以支撑结论。

3. 组件只写自己的字段

场景识别模块写候选场景,日志工具写日志证据,根因推理写候选结论。下游组件不静默改写上游事实。发生冲突时新增一条状态或证据,并在整合阶段处理。

4. 下一步动作由状态约束

当时间窗口缺失时,系统可以追问,也可以先做低成本预检。它不能悄悄补一个时间继续执行。对高风险场景,allowed_next_actions 还能接权限和审批策略。

5. 评测读取同一份上下文

评测不能只比较最终答案。它还要检查:关键字段有没有识别,工具参数是否来自已确认信息,必备证据是否出现,禁止断言有没有进入结论,跳过某个分支时是否记录了原因。

当 Trace 和 Eval 使用同一份 Context,失败才有机会被归因到具体环节。检索没命中、工具没执行、字段抽错和模型推理失误,会留下不同的痕迹。

这套方法如何迁移

可执行上下文是一种领域无关的产品抽象。变化的是字段和工具,稳定的是组织方式。

场景 原始输入 Context 中的关键字段 后续动作
客服 Agent 用户说又被扣费了 账户、订单、扣费时间、渠道、历史工单 查账单、匹配政策、生成处理建议
销售 Copilot 帮我看看这个客户 客户阶段、近期互动、关键人、机会金额、风险 拉取 CRM、补充信息、生成跟进计划
合同审查 这条有风险吗 条款类型、主体、金额、期限、适用模板、风险偏好 检索制度、比对模板、提交法务确认
运营分析 Agent 昨天转化掉了 指标口径、时间范围、渠道、实验、分群 查询数据、拆解漏斗、生成假设
IT 诊断 Agent 登录一直失败 环境、场景、时间窗、关键字、链路节点 查日志、查服务、检索知识、形成证据链

迁移时可以先问四个问题:

  1. 用户最常带着什么样的模糊输入进来?
  2. 哪些字段缺失时,系统必须停下来确认?
  3. 哪些信息来自事实工具,哪些只能由模型推断?
  4. 最终结论需要引用哪些证据,才能进入下一步业务动作?

这四个问题往往比先选框架更早决定产品形态。

代价与边界

Context Contract 会增加前期设计成本。团队需要维护 schema、字段状态、来源、迁移版本和读写权限。简单问答或低风险创作工具未必需要这套结构。

当任务具备以下特征时,这笔成本更容易得到回报:

  • 输入长期不完整,需要多轮补充
  • 任务会调用多个系统或工具
  • 结论影响真实业务动作
  • 过程需要审计、回放或人工接管
  • 产品需要通过评测持续迭代

光溯的公开 Demo 目前用一条匿名案例验证这套思路。真实生产接入还需要权限、数据治理、异步任务、监控和更完整的评测集。这些工作不会被一份漂亮的 Context Schema 自动解决。

它至少让所有人看见同一件事:我们已经知道什么,还缺什么,接下来凭什么行动。