--- author: 华钟民 created_at: 2026-05-23 purpose: 在 AI 配置管理页面为场景绑定表和接口工作流表各增加行内测试按钮,工作流测试独立走 endpoint 直调链路 --- # AI 配置行内测试功能设计 ## 1. 问题背景 当前 web-admin 后台「AI 配置管理」页面中: - **场景绑定 Tab**:只有顶部工具栏的全局「流式测试」按钮,需要手动选择场景 - **接口工作流 Tab**:没有任何测试功能 需要在两个表的每行操作列增加「测试」按钮,让用户直接对某一行进行测试。 ## 2. 设计方案 ### 2.1 场景绑定表 — 行内测试 - 每行操作列增加「测试」按钮 - 点击后打开现有测试对话框(`testDialog`),自动填入该行的 `sceneCode` - 后续流程不变,走 `sceneCode → resolveTarget → adapter` 链路 ### 2.2 接口工作流表 — 行内测试 工作流测试独立于场景,直接基于 endpoint 调用。 #### 后端新增 **`AiRuntimeService` 接口**: ```java // 非流式 endpoint 测试 AiRuntimeTestResponse testEndpoint(String endpointId, Map inputs); // 流式 endpoint 测试(SSE 回调) void invokeEndpointStream(String endpointId, Map inputs, Consumer consumer); ``` **`AiRuntimeServiceImpl` 实现**: - 根据 `endpointId` 查 endpoint(需 enabled)→ 查 provider(需 enabled)→ 调 adapter - 不做场景相关的输入注入(不注入 socialInsightContext 等) - 做基本的 userId 注入(从 UserContextHolder 获取) - 记录 callLog,但 sceneCode 字段为空或填 endpointCode - 复用 `RuntimeTarget` 类的类似逻辑,新建 `EndpointTarget` 内部类 **`AiRoutingController` 新增接口**: ```java @PostMapping("/endpoint/test") public Result endpointTest(@RequestBody JSONObject payload) // payload: { endpointId: "xxx", inputs: { ... } } @PostMapping("/endpoint/stream") public SseEmitter endpointStream(@RequestBody JSONObject payload) // payload: { endpointId: "xxx", inputs: { ... } } ``` #### 前端新增 **API 层**(`web-admin/src/api/aiconfig.ts`): ```typescript // 非流式 endpoint 测试 export function testEndpointRuntime(data: { endpointId: string; inputs: Record }) { return request({ url: '/ai/endpoint/test', method: 'post', data, timeout: 60000 }) } // 流式 endpoint 测试 export async function streamEndpointRuntime( data: { endpointId: string; inputs: Record }, onEvent: (event: AiRuntimeStreamEvent, output: string) => void ) ``` **UI 层**(`AiRoutingList.vue`): - 接口工作流表操作列增加「测试」按钮 - 点击打开新对话框 `endpointTestDialog`,标题「接口测试」 - 对话框内容: - 显示接口名称(只读) - 入参 JSON 框,**自动填入该 endpoint 的 `defaultInputs`**(如果有),否则填默认模板 `{}` - 非流式/流式测试结果展示区(和现有测试对话框一样的布局) - 底部:「关闭」「非流式测试」「流式测试」按钮 - 场景绑定表操作列增加「测试」按钮 - 点击打开现有 `testDialog`,自动填入该行的 `sceneCode` - 现有顶部工具栏的「流式测试」按钮保留不变 ### 2.3 数据流 ``` 场景绑定行内测试: 用户点击「测试」→ openRuntimeTest(row.sceneCode) → testDialog 打开 → 输入 params → 流式: streamAiRuntime({ sceneCode, inputs }) → /ai/runtime/stream → AiRuntimeService.invokeStream() 非流式: testAiRuntime({ sceneCode, inputs }) → /ai/runtime/test → AiRuntimeService.test() 接口工作流行内测试: 用户点击「测试」→ openEndpointTest(row) → endpointTestDialog 打开 → defaultInputs 已填入 → 流式: streamEndpointRuntime({ endpointId, inputs }) → /ai/endpoint/stream → AiRuntimeService.invokeEndpointStream() 非流式: testEndpointRuntime({ endpointId, inputs }) → /ai/endpoint/test → AiRuntimeService.testEndpoint() ``` ## 3. 文件清单 | 操作 | 文件 | |------|------| | 修改 | `backend-single/src/main/java/com/emotion/service/AiRuntimeService.java` | | 修改 | `backend-single/src/main/java/com/emotion/service/impl/AiRuntimeServiceImpl.java` | | 修改 | `backend-single/src/main/java/com/emotion/controller/AiRoutingController.java` | | 修改 | `web-admin/src/api/aiconfig.ts` | | 修改 | `web-admin/src/views/aiconfig/AiRoutingList.vue` | ## 4. 风险 - endpoint 测试不经过场景绑定,因此不会有场景相关的输入注入(如 socialInsightContext)。这是预期行为——endpoint 测试关注的是接口本身是否通 - endpoint 的 `defaultInputs` 可能不完整,用户仍可手动修改入参 - 新增两个后端接口,需确保权限校验和现有 `/ai/runtime/*` 接口一致(走同一个 Admin 鉴权)