Appearance
案例2 在应用网站中接入织信全局智能体
适用对象:织信应用开发者、网站模块开发者和负责集成的技术人员。
目标是在某个应用的网站模块中提供智能体会话,完整沿用工作台的会话、模型、技能、专家、知识库、附件、流式输出和历史记录调用方式。网站负责自己的页面布局,服务端仍使用工作台相同的智能体会话服务。
本文介绍如何在应用网站中复用工作台智能体的完整调用链,包括接入协议、开发步骤、代码示例和验收要求。示例中的页面和适配器需要结合实际部署完成开发、构建与联调。
应用效果
下面以已完成的“智能问数”应用为例,展示在应用网站中使用织信全局智能体的效果。用户可以在网站内选择模型和应用查询范围,通过自然语言提问,并从最近提问中继续已有会话。
智能问数首页
首页提供常用问题入口、最近提问和连接状态,用户无需切换到工作台即可开始对话。

选择应用范围并输入问题
发送前选择本次查询的应用范围,输入具体业务问题。图中展示的是选择范围和填写问题的状态。

在同一会话中继续追问
已有会话展示了基于上一轮结果继续计算客户占比的过程,回答同时列出计算方式、数据来源和统计时间。截图中的数字仅用于展示该会话的回答效果,不代表当前实时统计。

1. 接入结论
工作台“智能体会话”的核心调用链是:
text
网站页面获取当前登录态和应用上下文
→ 用户选择模型、权限、技能、专家、知识库
→ 首次发送时 POST /informatclaw/session,取得 sessionId
→ GET /informatclaw/session/{sessionId}/stream 建立 SSE
→ POST /informatclaw/session/{sessionId}/input 发送消息
→ 转换原始 SSE 事件并更新会话界面
→ 后续消息沿用同一个 sessionId
→ 重新进入时读取历史消息、状态,并恢复 SSE网站模块应复用这条调用链。不要把 informat.aiagent.completions、chatCompletions 或 /aiagent/chat 当作工作台会话接口。它们不能直接替代本文描述的工作台会话协议。
目前网站 RPC 中有 systemService.getToken()、systemService.getApp() 等基础方法,没有已核实的 informat.agent.createSession() 一类现成网站 SDK。下文使用现有 RPC 获取上下文,再直接调用工作台 HTTP 接口;如需封装 SDK,应保留相同协议和行为。
2. 用户如何配置自己的应用智能体
以“应用内知识问答与业务助手”为例:
- 在目标应用中新建或选择网站模块,设置聊天首页,并上传 HTML、CSS、JavaScript 资源。已有网站可增加“智能助手”页面或侧栏。
- 在团队中配置可用模型,并向目标用户授予相应 AI 使用权限。仅能进入应用,不代表一定可以使用工作台会话引擎;创建会话还会检查团队授权等条件。
- 准备允许使用的技能、专家、知识库,并确认这些资源已向目标用户开放。
- 网站页面通过 RPC 读取当前应用,把该应用作为会话的关联应用。需要应用内专用助手时,页面固定应用入口,不提供任意切换应用的操作。
- 用户首次发送问题时创建
type=default的会话,并传当前应用appId、所选权限和模型。 - 每次发送问题都按工作台格式提交本轮选择的技能、专家、知识库及附件。
- 发布网站所属应用,使用普通业务账号验证聊天、历史恢复和权限边界。
提示词示例:
你是本应用的业务助手。用户提到“当前应用”时,以当前关联应用为准。回答业务问题时优先使用本次选定的知识库;需要查询业务数据时使用当前用户有权访问的数据。资料不足时说明缺少什么。执行数据修改前清楚说明修改对象和内容。
这类文字用于定义助手职责。实际访问权限由服务端校验,不能只靠提示词控制。
3. 网站页面如何取得登录态
3.1 从应用内部打开网站
从织信应用内部打开网站模块时,可以通过平台提供的 RPC 脚本使用 systemService 和 appService,获取当前登录态和应用信息。
加载与当前部署版本匹配的 postmessage-rpc.js、rpc.js,等待 rpc-ready,再读取上下文。不要直接访问父页面 Vue 实例,也不要猜测 localStorage 中 token 的键名。
html
<!-- 以下路径适用于平台静态资源暴露在站点根目录的部署;
使用子路径部署时,应配置为该部署实际的资源地址。 -->
<script src="/js/postmessage-rpc.js"></script>
<script src="/js/rpc.js"></script>
<script src="./main.js"></script>javascript
/**
* 等待平台父页面完成网站 RPC 初始化。
* 仅适用于在织信应用内部以网站模块方式打开的页面。
*/
function waitForPlatformRpc() {
return new Promise(resolve => eventService.onceEvent('rpc-ready', resolve));
}
/**
* 读取当前用户登录凭据、应用和平台服务地址。
* token 只保存在运行时内存中,禁止写入控制台、静态文件或聊天正文。
*/
async function loadAgentContext() {
await waitForPlatformRpc();
const [token, app, serverUrl] = await Promise.all([
systemService.getToken(),
systemService.getApp(),
systemService.getServerUrl()
]);
if (!token || !app || !app.id) {
throw new Error('请从已登录的织信应用内打开智能助手页面');
}
return { token, app, serverUrl };
}网站资源的典型地址为 /web{dbIndex}/website/{appId}/{websiteId}/。从页面路径可以识别当前网站的数据库路由前缀;不要把所有环境固定成 web0。
serverUrl 是平台服务根地址。存在网关前缀、独立资源域或反向代理的环境,应显式配置并核实会话服务根地址,不能仅使用 iframe 所在域名推断。
3.2 直接打开网站 URL 或嵌入外部系统
独立打开网站地址时,不一定有父页面 RPC,也不一定具有有效登录态。本文的 RPC 初始化代码不能原样用于这种入口。
如需外部系统使用,必须另外完成登录集成、服务地址和跨域配置,再以合法的当前用户 token 调用同一套会话接口。不能把管理员 token、模型 API Key 或 X-INFORMAT-AGENT-TOKEN 放进网站资源。
工作台 HTTP 接口使用的是用户登录 token;X-INFORMAT-AGENT-TOKEN 属于智能体内部工具回调凭据,两者用途不同。
4. 服务地址和会话接口
会话接口的基础路径为 /web{dbIndex}/informatclaw,其中 {dbIndex} 使用当前部署的数据库路由编号。存在网关前缀时,应使用管理员提供的实际访问地址。
下文用 BASE 表示已确认的完整服务地址,例如 https://informat.example.com/web0/informatclaw。
所有下列请求均带 ?token=<当前用户登录token>;已有查询参数时使用 &token=...,token 必须经过 URL 编码。
| 功能 | 方法 | BASE 后的路径 | 请求或说明 |
|---|---|---|---|
| 创建会话 | POST | /session?type=default&aiModelKey=<模型key> | JSON 创建参数;返回 {sessionId} |
| 我的会话 | GET | /sessions?typeList=default&appId=<应用ID>&pageIndex=1&pageSize=20 | 返回 {list,count,pageIndex,pageSize} |
| 历史消息 | GET | /session/{id}/messages?pageIndex=1&pageSize=50 | 返回分页消息及总数 |
| 实时输出 | GET | /session/{id}/stream | text/event-stream,使用 EventSource |
| 发送消息 | POST | /session/{id}/input | JSON 消息体;接受成功返回 {ok:true} |
| 会话状态 | GET | /session/{id}/status | 用于恢复运行状态和用量等信息;按当前返回结构解析 |
| 停止生成 | POST | /session/{id}/stop | 停止当前执行,保留会话 |
| 删除会话 | POST | /session/{id}/delete | 关闭并删除会话,用户明确操作后调用 |
| 置顶 | POST | /session/{id}/pin | 更新列表顺序 |
| 取消置顶 | POST | /session/{id}/unpin | 更新列表顺序 |
| 重命名 | POST | /session/{id}/updateThreadName | { "name": "售后问题分析" } |
| 切换权限 | POST | /session/{id}/permissionMode | { "permissionMode": "readonly" } |
| 切换关联应用 | POST | /session/{id}/app | { "appId": "<应用ID>" } |
| 删除指定消息 | POST | /messages/delete | 消息数字 ID 数组,如 [101,102] |
普通会话使用 owner 接口。/shared/session/{id}/messages、stream、status 用于经授权的管理只读场景,不可用来绕过会话归属限制。
4.1 首次创建参数
http
POST BASE/session?type=default&aiModelKey=<模型key>&token=<用户token>
Content-Type: application/jsonjson
{
"appId": "<当前应用ID>",
"permissionMode": "readonly"
}可选创建参数包括 appName、appDefineId、expertId、expertTeamId、skillList、kbFolderList、appKbList,资源字段应使用与本轮输入相同的序列化约定。按实际功能传入,不要把示例占位符发送到服务端。
网站普通聊天沿用工作台的 type=default。codestudio、createApp 等是其他业务场景,不能因为聊天界面位于网站模块就使用 codestudio。
模型通过查询参数 aiModelKey 指定,传模型的 key,不是模型记录 id。工作台首次发送后锁定本会话模型;用户需要切换模型时新建会话。
“新建会话”按钮先创建前端空白状态,用户真正发送第一条消息时才调用创建接口,避免留下大量空会话。
4.2 每轮输入参数
json
{
"message": "请根据本次选择的知识库回答报销规则",
"skillList": "<技能key1>,<技能key2>",
"expertId": "<专家ID>",
"kbFolderList": "[\"<团队知识库ID>\"]"
}| 字段 | 格式 | 含义 |
|---|---|---|
message | 字符串 | 正文,含工作台格式的应用上下文和附件引用 |
skillList | 逗号分隔的字符串 | 多个技能使用 key,不能传技能对象数组 |
expertId | 字符串 | 所选专家 ID |
expertTeamId | 字符串 | 所选专家团队 ID;需该部署启用功能 |
kbFolderList | JSON 数组的字符串 | 团队知识库 ID 列表,例如 JSON.stringify(ids) |
appKbList | 字符串化资源列表 | 应用知识库选择;当前后端按关联应用解析,集成时复用现有应用知识库处理逻辑 |
insertTestData | 字符串 | 特定业务入口使用的选项;普通网站聊天不需要传 |
输入字段按字符串格式提交,因此不要直接传 kbFolderList: ["id"]。技能、知识库可以多选;专家与专家团队应按页面支持的选择规则提交,避免同时传相互冲突的选择。
清空专家与“不改变专家”不是同一语义。工作台清空选择时会使用 expertId: "";没有该字段可能继续沿用已有状态。知识库的未传、空列表和专家默认知识库也有不同处理,必须复用选择状态的构造逻辑,并验证清空后的实际范围。
技能、专家和知识库必须通过上述结构化字段提交,不能只把显示名称拼进提示词来模拟选择。
4.3 首轮应用上下文
工作台不仅设置会话 appId,还会在新会话第一条消息前注入以下上下文。要模仿工作台,网站也应保留这一行为:
text
【当前关联应用上下文】
用户已在创建会话前选择关联应用:<应用名称>
appId: <当前应用ID>
appDefineId: <应用定义ID,存在时填写>
当用户说“当前系统”“这个系统”“当前应用”“有哪些表/页面/字段”等未明确指定范围的问题时,默认只针对上述关联应用处理;不要先遍历全公司或所有应用,除非用户明确要求查看所有应用。
【用户原始问题】
<用户输入>后续轮次不用重复加入这段首轮上下文。聊天气泡可以只展示用户原始问题,读取历史时将上下文说明与用户正文分开展示。
appId 是关联上下文,不应被理解为“服务端保证只能访问此应用”的独立安全沙箱。网站隐藏应用切换入口也不能替代服务端权限控制;若业务要求严格禁止跨应用访问,需要另行核实或增强服务端范围约束。
5. SSE 输出必须按工作台协议处理
创建成功后订阅:
javascript
const source = new EventSource(
`${BASE}/session/${encodeURIComponent(sessionId)}/stream?token=${encodeURIComponent(token)}`
);工作台服务在创建成功后建立连接,随后提交 /input。网站可以等待连接 open 再发送,以减少首轮连接建立期间的展示空窗;恢复时仍需读取历史和状态。
5.1 原始事件与界面事件是两层协议
SSE 的 message 通道承载原始 JSON,其中常见类型是:
| 原始类型 | 网站需要执行的操作 |
|---|---|
system / init | 展示初始化、模型和能力等状态 |
stream_event | 处理消息开始和文本增量,例如 event.delta.type=text_delta |
assistant | 解析 message.content 中的文本、工具调用等内容块 |
user 中的 tool_result | 回填对应工具调用结果,展示成功或失败 |
result | 处理执行结果、耗时、用量和错误标记 |
replay_start、replay_end | 处理当前轮事件回放,与历史消息协调,避免重复 |
done | 一轮结束,恢复输入状态 |
error | 展示业务错误并解除等待状态 |
expert_team_runtime | 专家团队运行进度,部署启用时处理 |
此外还要监听 SSE 命名事件 done 和 error。同一轮可能同时出现 message 中的 type=done 和命名 done,结束处理必须幂等。
不要把原始 assistant 当成可直接追加的纯文本。文本增量和最终快照可能表示同一段输出,如果两者都直接追加,会出现答案重复。
5.2 将事件呈现为聊天内容
网站需要根据事件类型呈现文本、执行状态、工具调用及结果、文件链接和用户交互卡片。文本增量用于更新当前回答,完整消息用于校准最终内容,结束事件用于恢复输入状态。
对于需要用户回答的交互,将用户答案作为后续消息提交。不要自行假设存在新的“工具确认 HTTP 接口”。文件和链接应单独展示,错误应显示为明确的失败状态。
下面示例中的 onRawEvent 是网站自行处理事件的位置,需要根据第 5.1 节实现解析、去重和页面更新。
6. 网站侧最小协议适配示例
下面的类演示创建、SSE、输入和停止的调用方式。要达到完整工作台体验,还需按第 5、8、9 节实现事件解析、历史恢复、能力选择及附件上传。它不是已经发布的官方 SDK。
javascript
/**
* 网站页面中的工作台会话协议适配器。
* 每个实例管理一个 sessionId 和一条 SSE 连接。
* baseUrl 由宿主提供,已包含正确的 web{dbIndex} 路由前缀。
*/
class WorkbenchAgentClient {
/**
* @param {Object} options 接入配置。
* @param {string} options.baseUrl 会话服务根地址。
* @param {string} options.token 当前登录用户 token,只保存在内存。
* @param {Function} options.onRawEvent 原始 JSON 事件回调,由网站解析并更新页面。
* @param {Function} options.onError 业务及连接错误回调。
* @param {Function} options.onDone 本轮结束回调,宿主应幂等恢复输入状态。
*/
constructor({ baseUrl, token, onRawEvent, onError, onDone }) {
this.baseUrl = baseUrl.replace(/\/$/, '');
this.token = token;
this.onRawEvent = onRawEvent;
this.onError = onError;
this.onDone = onDone;
this.sessionId = null;
this.source = null;
}
/** 为同一服务下的请求加上当前用户 token,保留已有查询参数。 */
url(path, query = {}) {
const url = new URL(this.baseUrl + path);
Object.entries(query).forEach(([key, value]) => {
if (value != null && value !== '') url.searchParams.set(key, String(value));
});
url.searchParams.set('token', this.token);
return url.toString();
}
/**
* 执行 JSON 请求,同时检查 HTTP 错误和 HTTP 200 下的业务失败。
* 不记录完整 URL,以免把查询参数中的 token 写入日志。
*/
async request(path, { method = 'GET', query = {}, body } = {}) {
const response = await fetch(this.url(path, query), {
method,
headers: body === undefined ? {} : { 'Content-Type': 'application/json' },
body: body === undefined ? undefined : JSON.stringify(body)
});
if (!response.ok) throw new Error(`会话请求失败,HTTP ${response.status}`);
const data = await response.json();
if (data && data.ok === false) throw new Error(data.message || '会话请求被拒绝');
return data;
}
/**
* 首条消息发送前创建会话;后续调用返回已有 ID。
* 外层页面需要禁用重复提交,避免并发创建两个会话。
*/
async create({ appId, aiModelKey, permissionMode = 'readonly', ...capabilities }) {
if (this.sessionId) return this.sessionId;
const result = await this.request('/session', {
method: 'POST',
query: { type: 'default', aiModelKey },
body: { appId, permissionMode, ...capabilities }
});
if (!result.sessionId) throw new Error('创建会话未返回 sessionId');
this.sessionId = result.sessionId;
console.info('[website-agent] session-created', { sessionId: this.sessionId, appId });
return this.sessionId;
}
/**
* 建立 SSE 并等待连接就绪。连接中断时由 EventSource 自动重连。
* 正式实现还需接入工作台的状态同步、重连上限和历史去重策略。
*/
connect() {
if (!this.sessionId) return Promise.reject(new Error('请先创建或恢复会话'));
this.detach();
return new Promise((resolve, reject) => {
let opened = false;
const source = new EventSource(this.url(`/session/${this.sessionId}/stream`));
this.source = source;
const timer = setTimeout(() => {
if (!opened) {
source.close();
if (this.source === source) this.source = null;
reject(new Error('会话连接超时,请重试'));
}
}, 15000);
source.onopen = () => {
opened = true;
clearTimeout(timer);
resolve();
};
source.onmessage = event => {
let raw;
try { raw = JSON.parse(event.data); }
catch (error) {
this.onError?.(new Error('会话事件格式异常'));
return;
}
this.onRawEvent?.(raw);
if (raw.type === 'done') this.onDone?.();
if (raw.type === 'error') this.onError?.(new Error(raw.message || '智能体执行失败'));
};
source.addEventListener('done', () => this.onDone?.());
source.addEventListener('error', event => {
if (event.data) {
this.onError?.(new Error(event.data));
} else if (opened) {
this.onError?.(new Error('实时连接中断,正在尝试重连'));
}
});
});
}
/**
* 提交本轮正文和能力参数。返回只表示输入被接受,最终回答通过 SSE 接收。
* 正文中的首轮应用上下文、附件引用由上层按工作台规则生成。
*/
async send(message, capabilities = {}) {
if (!this.sessionId) throw new Error('请先创建或恢复会话');
return this.request(`/session/${this.sessionId}/input`, {
method: 'POST', body: { ...capabilities, message }
});
}
/** 停止当前生成,保留会话和已经保存的历史。 */
async stop() {
if (!this.sessionId) return;
return this.request(`/session/${this.sessionId}/stop`, { method: 'POST' });
}
/** 页面退出或切换会话时仅断开连接,不向服务端删除会话。 */
detach() {
this.source?.close();
this.source = null;
}
}调用顺序示例:
javascript
// BASE 必须由当前部署和网站运行上下文正确解析。
// handleRawEvent 根据事件类型更新聊天内容,不能把原始 JSON 当作最终答案。
const client = new WorkbenchAgentClient({
baseUrl: BASE,
token: context.token,
onRawEvent: handleRawEvent,
onDone: finishCurrentRound,
onError: showAgentError
});
await client.create({
appId: context.app.id,
aiModelKey: selectedModel.key,
permissionMode: 'readonly'
});
await client.connect();
await client.send(firstMessageWithAppContext, {
skillList: selectedSkillKeys.join(','),
kbFolderList: JSON.stringify(selectedKnowledgeBaseIds)
});BASE、context、selectedModel、选择列表以及回调均由实际页面提供。普通续聊使用 client.send(),不要再次创建会话。
7. 配置可选模型与能力
页面需要提供与当前用户权限一致的模型、技能、专家和知识库选项。接入前由管理员准备以下配置:
| 选择项 | 网站需要的数据 | 提交时使用的值 |
|---|---|---|
| 模型 | 名称、模型 key、可用状态 | aiModelKey 使用模型 key |
| 技能 | 名称、技能 key、可用状态 | skillList 使用技能 key 列表 |
| 专家 | 名称、专家 ID、职责说明 | expertId 使用专家 ID |
| 专家团队 | 名称、团队 ID、可用状态 | expertTeamId 使用团队 ID |
| 团队知识库 | 名称、知识库 ID、说明 | kbFolderList 使用知识库 ID 列表 |
可以先为网站配置一组已授权的固定选项,贯通完整会话。如果需要动态展示可用资源,应使用当前部署提供的资源查询接口;具体访问方式由管理员或交付人员提供,不要自行猜测接口路径。
显示名称用于用户选择,提交时必须使用对应的 key 或 ID。资源配置不能替代服务端授权;资源停用或用户失去权限时,页面应显示实际返回的错误并允许重新选择。
8. 附件与工作台保持一致
工作台先上传附件,再将下载 URL 写入 message。不是直接向 /input 发送文件二进制,也不是传一个未经后端读取的 files 数组。
上传请求:
text
POST <服务根地址>/web{dbIndex}/file/company_upload
Content-Type: multipart/form-data,由浏览器自动生成 boundary
表单字段:file、token
成功响应中读取 data.pathjavascript
/** 上传附件,读取工作台上传响应中的存储路径。 */
async function uploadAgentFile(uploadUrl, token, file) {
const form = new FormData();
form.append('file', file, file.name);
form.append('token', token);
const response = await fetch(uploadUrl, { method: 'POST', body: form });
if (!response.ok) throw new Error(`附件上传失败,HTTP ${response.status}`);
const result = await response.json();
if (!result.data?.path) throw new Error('附件上传未返回文件路径');
return result.data.path;
}附件下载地址格式为 <服务根地址>/web0/file/company_download/<filePath>,其中 filePath 是上传成功返回的路径。附件消息尾部为:
text
请分析这份材料,"attachmentList":<完整下载URL1>,<完整下载URL2>正文和附件标记之间使用中文逗号,标记后的冒号是中文冒号,多个 URL 用英文逗号连接。构造消息时保留 "attachmentList": 的约定。上传使用当前 dbIndex,下载例子使用现有工作台的 /web0/ 约定,配置时应分别确认上传与下载地址。
文件未上传成功前禁止发送。页面还应提供图片和附件预览、移除附件以及上传失败提示。展示附件标题时使用安全的文本渲染。
9. 历史记录、恢复与生命周期
- 页面初始化查询自己的
typeList=default会话,应用专用页面增加appId筛选。 - 用户选择会话后,读取历史消息第一页,并支持继续读取更早消息。工作台默认每页 50 条,不能只读第一页就当作完整记录。
- 解析历史消息中的用户正文、附件、能力选择和工具执行记录,并转换为页面中的聊天内容。
- 读取
/status,恢复运行状态及当前模型、权限等实际信息,再连接该sessionId的 SSE。 - 将历史消息与 SSE 回放协调,处理
replay_start/replay_end、重复快照及消息 ID,避免恢复后消息重复。 - 切换会话时取消旧的历史加载,断开旧 SSE 连接,防止迟到响应写入新会话。
- 页面卸载只断开连接。用户点击“停止”才调用
/stop,用户点击“删除会话”才调用/delete。 - 会话不存在或没有权限时显示明确状态;不要静默创建空会话覆盖旧会话缓存。
本地缓存会话 ID 时使用用户、团队、应用、网站模块共同组成缓存键,避免同一浏览器切换账号后串会话。缓存的是索引信息,服务端会话归属检查始终是最终依据。
appId 筛选用于按应用查看会话,不代表同一应用下的多个网站助手已相互隔离。若需要网站级隔离,应在接入前与管理员确认服务端支持的隔离方案;仅用浏览器缓存区分不构成服务端隔离。
10. 权限与错误处理
工作台当前会话页提供三种权限模式:
| 显示名称 | 接口值 | 用途 |
|---|---|---|
| 只读模式 | readonly | 对话、上传文件、外网访问等允许能力 |
| 数据模式 | dataAssistant | 在授权范围内读写应用数据 |
| 完全访问权限 | adminAssistant | 在授权范围内进行管理操作 |
普通会话页面使用上表中的权限模式,不应混入设计器专用权限选项。
权限模式限定本会话能力,不会扩大用户已有权限。新会话把选择写入创建参数;已存在会话通过 /permissionMode 更新,并采用服务端返回的规范化模式。正在生成时应按工作台行为禁用切换。
实现时必须处理:
- HTTP 非 2xx:结束等待,显示请求失败。
- HTTP 200 但
{ok:false,code,message}:按业务失败处理,不能继续一直显示“正在思考”。 - SSE 命名
error带data:显示服务端错误。 - SSE 连接错误没有
data:按连接中断处理,重连后同步状态和历史,不能把它当作最终模型回答。 - 模型不可用、团队未授权、额度不足、技能或专家无权限:保留用户草稿,提示实际失败原因。
- 删除、停止、断开连接的语义不同,不能在页面销毁时误删会话。
记录 sessionId、应用 ID、请求操作、HTTP 状态、连接状态、完成和停止等关键日志;不要记录 token、完整带 token 的 URL、模型密钥或全部上传内容。模型输出的 Markdown、链接和 HTML 应经过安全渲染处理,避免直接执行输出中的脚本。
11. 完整聊天页面需要提供的功能
除基本问答外,与工作台一致的页面还需要提供以下能力:
- 会话列表:新建、选择、置顶、重命名、删除,以及分页加载。
- 会话设置:模型、关联应用和权限模式。
- 能力选择:技能、专家、专家团队及知识库,支持查看与清空选择。
- 消息展示:流式文本、工具执行状态、文件链接和交互卡片。
- 附件操作:上传、预览、移除及失败提示。
- 生命周期:停止生成、切换会话、历史恢复和断线恢复。
- 会话导出:导出用户可见的完整内容,并保留必要的附件引用。
如需提供“核验会话”,应另行接入当前部署支持的核验服务,展示报告、证据和反馈。核验不是 /input 的普通参数,也不能仅通过发送一句“请核验”替代。
网站页面自行实现布局和事件处理,按本文协议调用会话服务。接入示例仅覆盖通信基础,完整功能需要结合实际需求开发和验收。
12. 发布前验收清单
完成网站集成后,使用普通业务账号逐项验收。工作台功能可作为对照基线,网站中的同名入口应具备相同的调用语义。
| 验收项 | 应达到的结果 |
|---|---|
| 会话列表 | 显示当前账号自己的历史会话,并正确筛选当前应用 |
| 新会话与首轮输入 | 首次发送才创建会话,列表出现新会话并收到答案 |
| 多轮上下文 | 沿用同一会话,后续问题能引用上一轮信息 |
| 执行过程与完成状态 | 展示初始化、工具执行和结果,完成后恢复输入 |
| 技能选择 | 多选、清空和本轮参数准确生效 |
| 知识库问答 | 使用所选知识库并提供资料依据,清空后范围符合预期 |
| 专家与专家团队 | 正确应用所选身份、职责和资源范围;未启用的功能不展示 |
| 权限切换 | 三种模式按用户授权生效,不能通过前端参数扩大权限 |
| 模型选择与锁定 | 首轮使用所选模型,之后锁定;更换模型需新建会话 |
| 关联应用 | 首轮上下文正确,切换后按服务端实际范围处理 |
| 附件与图片 | 上传、解析、预览、移除、下载和失败提示正确 |
| 停止与运行中输入 | 停止后可继续;运行中输入行为与工作台一致 |
| 历史与断线恢复 | 刷新、切换、重连后记录完整且不重复 |
| 会话管理 | 置顶、取消置顶、重命名和删除仅作用于指定会话 |
| 导出与会话核验 | 内容完整,核验报告、证据和反馈入口按权限工作 |
| 数据与管理操作 | 操作对象正确,用户权限有效,关键过程可追踪 |
| 登录失效与额度不足 | 解除等待状态,保留草稿并显示明确原因 |
| 多账号与多网站 | 会话索引不串用,服务端归属检查有效 |
建议的首轮验收
先使用只读模式,依次验证普通问答、多轮上下文、所选知识库问答和专家职责。随后验证附件、恢复和会话管理,最后再在测试应用中验证数据与管理操作。

