已有订单或工单页面时,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 形状与责任边界,不是完整上线教程。
ts
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 的结果:
ts
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 宿主中验证。