Mock 适配器

Mock 适配器(createMockAdapter)不连接后端,按脚本回放对话,用于本地开发、演示和测试,不用于生产环境。这一页说明怎么用它在不连后端的情况下看效果,以及怎么演示后端缺少某项能力时界面的样子。

结论

  • createMockAdapter() 不传参数就具备它实现了的全部能力:停止、重新生成、编辑后重发、历史。
  • 要演示「后端没有某项能力」时,把那一项传 false。
  • 所有数据都在内存里,刷新页面或重建适配器实例后回到预置内容;仅重建运行时而保留实例时,仍可读取该实例的内存历史。
quick-start.tsx
import { useDemoSessions } from '../sessions';

import { Chatkit, SessionList } from '@volcengine/chatkit';
import { createMockAdapter } from '@volcengine/chatkit/adapters/mock';
import '@volcengine/chatkit/styles.css';
import { useState } from 'react';

// 整个应用一个适配器实例,引用要稳定(模块级或 useMemo):引用一变运行时就会重建。
// Mock 适配器不连后端,自带三个预置会话,发送后按脚本回放「思考 → 调工具 → 流式回答」。
const adapter = createMockAdapter();

// 最小接入:适配器 → useChatSessions → 会话列表和聊天区用同一个返回值。随便发一句话试试。
export default function QuickStart() {
  const { chat: sessions, listProps } = useDemoSessions({ adapter });
  const [open, setOpen] = useState(false);
  return (
    <div className="demo-column demo-session-layout" data-placement="left" data-open={open}>
      {/* demo-session-* 是示例页的响应式样式:窄屏默认收起列表,聊天区保持全宽。 */}
      <div className="demo-bar demo-session-toggle-bar">
        <button
          type="button"
          className="demo-chip"
          aria-expanded={open}
          aria-controls="quick-start-sessions"
          onClick={() => setOpen(value => !value)}
        >
          {open ? '收起会话' : '全部会话'}
        </button>
      </div>
      <div className="demo-row">
        <div id="quick-start-sessions" className="demo-session-sidebar">
          <SessionList {...listProps} style={{ width: '100%' }} />
        </div>
        <div className="demo-main">
          <Chatkit sessions={sessions} settings={{ welcome: '有什么可以帮忙的?' }} />
        </div>
      </div>
    </div>
  );
}
三个预置会话;发一句话是默认场景:思考、调工具、流式回答新窗口打开

用法

adapters.ts
import { createMockAdapter } from '@volcengine/chatkit/adapters/mock';

// 不传参数:停止、重新生成、编辑后重发、历史、会话全部具备
export const full = createMockAdapter();

// 演示后端没有会话接口:会话列表不出现,界面是单个对话
export const withoutSessions = createMockAdapter({});

// 演示后端只能对话:回答下方没有重新生成,用户消息不能编辑,打开会话是空的
export const chatOnly = createMockAdapter({
  abort: false,
  regenerate: false,
  edit: false,
  history: false,
});

// 指定回放的场景,pace: 0 不等待直接跑完(测试用)
export const scripted = createMockAdapter({ getScenarioId: () => 'all-tools', pace: 0 });

和真实适配器的区别

项目真实适配器Mock 适配器
能力怎么给给了能力函数才有已实现的默认开启,传 false 关闭
请求由接入方的函数发给后端没有请求,按脚本回放
会话与历史来自后端在内存里
续接、插话给了 resume、steer 才有没有实现

写法不同的原因:没有后端,也就没有函数可给。它的用途是不用任何配置就看到完整的效果。

演示能力缺失

传入界面上
createMockAdapter()已实现的功能,受界面配置约束
{ history: false }打开会话是空的
{ regenerate: false }回答下方没有重新生成
{ edit: false }用户消息上没有编辑
{ abort: false }不显示停止按钮

接真实后端之前,用它确认每项能力缺失时界面是不是可以接受,再决定要后端实现哪些。

选项

类别选项作用
能力abort传 false:不提供停止能力
能力regenerate传 false:没有重新生成
能力edit传 false:没有编辑后重发
能力history传 false:没有历史
回放pace节奏倍率:1 是真实的节奏,0 不等待直接跑完(测试用)
回放getScenarioId每次发送时取一次场景编号。不传时按输入里的关键词选
回放transformOutput每个脚本步骤经转换;历史中的已录制回答步骤也会回放,返回内容变更,用来演示业务卡片
其他onError(error: unknown) => void,接收内容转换错误;不同于联网适配器的三参数回调
其他now取当前时间,测试里换成固定的时钟

会话

预置三个会话,各带几条历史消息:「CSS 层叠层怎么用」「周报草稿」「接口排查」。 示例应用自己维护目录、创建、改名和删除;适配器只维护消息历史,不提供目录接口。

场景

不传 getScenarioId 时,输入里带「失败」进入失败场景,其余是默认场景。用 getScenarioId 指定别的场景:

场景编号内容
agent-loop(默认)三轮「思考、调工具、回答」
all-tools每种内置工具各显示一次
markdownMarkdown 的全部元素
long-reasoning很长的思考过程
run-failed运行失败
context-compaction上下文压缩的系统提示
custom-data回答里的业务数据
product-tools业务自己的工具
slow-abortable一直运行到被停止

各项能力的行为

能力行为
重新生成同一份输入再回放一次,结尾注明是第几版
编辑后重发从那一轮起的内容被替换,用新的输入回放
历史每个会话的内容存在内存里,打开会话时读回来
附件支持图片、PDF、文本、音视频、ZIP 和常见 Office 文件。附件显示在用户消息上

它实现与联网适配器相同的 Core 契约,并参与一致性测试。它不模拟真实鉴权、网络中断、订阅、续接或远端取消确认,不能代替真实后端验收。历史返回消息但不返回轮次终态快照,重建运行时后的历史操作不应等同于刚执行完的轮次。

场景目录 MOCK_SCENARIOS 的每项仅含 id、label、checklist。将选中的 ID 通过 getScenarioId 提供给工厂;默认 ID 为 DEFAULT_MOCK_SCENARIO_ID。