别把 AI 查询结果只塞进聊天框:SessionView 与业务页面接线

0 阅读4分钟

已有订单或工单页面时,AI 查询的难点不是多一个聊天框,而是结果怎样回到当前业务对象。本文给出事件、工具结果和 queryId 的最小接线契约。

把 AI 查询接进已有订单或工单页面时,最容易犯的错误是把所有内容都拼进聊天气泡。更可靠的接线方式是让三条数据流各司其职:模型消息负责解释,Tansr 会话事件负责过程状态,业务接口负责可核对记录。页面通过稳定的查询标识把它们重新组合。

从事件流得到界面状态

Tansr 的会话事件会描述一轮运行的边界,以及工具提出、开始、完成或失败等阶段。应用可以用 createSessionView 把事件归约成不可变的视图快照,再将快照通过自己的状态管理或 Electron IPC 交给界面。不要在渲染层自己拼接 msg.text.delta 来推断工具是否完成,也不要用“模型说成功”替代业务回执。

事件到界面的映射可以先定成下面这样:

事件或视图状态产品区域可做的动作
用户问题和文本增量聊天区继续追问或修改筛选
tool.proposed、tool.started工具卡显示正在查询,必要时显示等待授权
tool.completed、tool.failed工具卡和任务面板展示结果摘要或可恢复错误
view.messages、view.tools、view.errors页面状态层更新聊天、任务卡和错误横幅
业务服务返回的 recordIds订单/工单列表刷新行、打开详情、继续原操作

SessionView 只负责把运行事件投影成可呈现的会话状态。recordIds、租户范围和业务状态仍由工具 handler 调用的业务服务决定。

工具结果要能被页面消费

下面是接线示意,省略模型和令牌配置;它展示 API 形状与责任边界,不是完整上线教程。

const lookupTickets = defineTool({
  name: 'lookup_tickets',
  description: '查询当前登录租户可见的工单;不修改工单。',
  readOnly: true,
  parameters: {
    status: { type: 'string', description: '工单状态' },
    customerId: { type: 'string', description: '当前页面的客户标识' }
  },
  handler: async (args) => ticketService.search({
    tenantId: auth.tenantId,
    userId: auth.userId,
    status: args.status,
    customerId: args.customerId
  })
});

const session = await createSession({
  client,
  tools: { custom: [lookupTickets] }
});
const view = createSessionView(session);

业务服务返回值应面向两种消费者设计:模型需要能解释的字段,页面需要能定位的字段。一个可用的查询结果至少包含 queryId、recordIds、snapshotAt 和 rows。queryId 由应用在发起页面查询时生成,不能让模型自由改写;recordIds 也不是授权令牌,页面打开详情前仍要走原业务入口。

处理当前对象和过期结果

页面查询存在竞态:用户先查客户 A,随后切换到客户 B;A 的网络响应可能晚于 B。应用应在本地保存当前 queryId,只接受相同 queryId 的结果:

const queryId = crypto.randomUUID();
currentQueryId = queryId;
session.send(JSON.stringify({ queryId, customerId }));

function applyResult(result) {
  if (result.queryId !== currentQueryId) return;
  renderRows(result.recordIds, result.rows);
}

这段判断只解决页面覆盖问题,不解决业务授权或重复写入。工具是只读查询时,业务服务仍要检查租户、角色和记录归属;如果后续增加提交、分派或通知工具,还要为业务意图设计幂等键、权威查询和用户确认。

错误和权限要显示在正确的位置

工具参数不合法、查询无权访问、没有匹配记录和网络失败不是同一种状态。Tansr 会把工具阶段和错误带入事件流,应用应把可恢复错误显示在任务面板,把需要用户补充的信息放回聊天,把业务权限拒绝交给原有权限界面。未接入 askUser 时,涉及确认的工具可能按 fail-closed 规则被拒绝;不要把拒绝渲染成空结果。

如果页面只需要一次固定查询和摘要,直接调用模型 API 加业务查询通常更短;只有在需要多轮追问、动态选择工具、过程展示或统一会话状态时,接入 Tansr 的运行链才有明确复用点。采用 SDK 不会自动提供页面、登录、业务服务或权限规则。

最小验收集

开发时用脱敏演示服务验证:创建只读工具后,SessionView 能收到开始和完成状态;工具结果中的 recordIds 能打开同一条演示记录;切换客户后旧 queryId 不覆盖新结果;参数错误、无权访问和空结果在界面上能区分。这个验证检查的是接线契约,不能替代真实业务系统的并发、权限和数据质量测试。

接口依据见 Tansr 的会话与事件流、defineTool 和平台装配说明。示意代码省略真实模型、令牌和业务服务配置;上线前仍需在自己的 Node.js 或 Electron 宿主中验证。