Compare commits

..

13 Commits

Author SHA1 Message Date
V-LiuShuang eee6640952 add 2026-09-18 10:23:50 +08:00
V-LiuShuang 37ebd8715f Merge branch 'main' of https://git.jkwlstv.cn/doc/tmp 2026-09-16 15:32:40 +08:00
V-LiuShuang 55d8ed8e28 add 2026-09-16 15:32:28 +08:00
8ga c3dc494f2d 更新 sql.md 2026-09-15 11:50:34 +08:00
8ga 3c0a740e91 更新 sql.md 2026-09-15 11:50:16 +08:00
8ga de02fa7817 更新 sql.md 2026-09-15 11:47:16 +08:00
8ga d3215e4fdc 更新 sql.md 2026-09-15 11:39:54 +08:00
8ga 0aa670000c 更新 sql.md 2026-09-15 11:38:19 +08:00
8ga 304250da43 更新 sql.md 2026-09-15 11:37:35 +08:00
8ga 27e90e99ee 更新 msg.md 2026-09-11 17:36:41 +08:00
8ga 205c6870ca 更新 v260930.md 2026-09-11 17:35:09 +08:00
8ga 0703252426 更新 v260930.md 2026-09-11 17:34:45 +08:00
8ga 17ba3dc05b 更新 v260930.md 2026-09-11 17:34:08 +08:00
4 changed files with 1230 additions and 10 deletions
+993
View File
@@ -0,0 +1,993 @@
# Harness Chat 接口文档
`POST /harness/chat`
## 1. 接口说明
- 路径:`/harness/chat`
- 方法:`POST`
- 内容类型:`application/json`
- 返回类型:`Flux<AgentEvent>`(**流式响应**,支持 SSE 与 JSON 数组两种方式)
- 功能:向智能体发送一条用户输入,返回一段**细粒度智能体事件流**。调用方按事件类型逐条解析即可渲染「思考中 / 正在调用工具 / 流式输出答案 / 需要人工确认」等 UI 状态。
> 源码位置:`mis-common/mis-common-harness/java/com/lcfc/harness/chat/HarnessChatGateway.java#L18-L23`
>
> ```java
> @PostMapping("/chat")
> public Flux<AgentEvent> chat(@RequestBody AgentChatRequest request) {
> ChatUiChannel channel = HarnessAgent.builder().build().channel(ChatUiChannel.create());
> SendOptions sendOptions = SendOptions.of(request.getUserId(), request.getSessionId());
> return channel.sendStream(sendOptions, request.getInput());
> }
> ```
## 2. 请求
### 2.1 请求头
| Header | 值 | 说明 |
| --- | --- | --- |
| `Content-Type` | `application/json` | 必填 |
| `Accept` | `text/event-stream``application/json` | 决定响应格式(见 §3 |
### 2.2 请求体(`AgentChatRequest`
| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `sessionId` | String | ✅ | 会话 ID;同一用户不同会话相互隔离 |
| `userId` | String | ✅ | 用户 ID;用于智能体命名空间隔离 / 会话路由 |
| `input` | String | ✅ | 用户输入内容 |
| `chatModel` | Object | ❌ | 聊天模型配置(`name``stream``temperature` |
`chatModel` 结构:
| 字段 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `name` | String | - | 模型名称,如 `gpt-oss-120b` |
| `stream` | Boolean | `true` | 是否流式 |
| `temperature` | Double | `0.2` | 温度 |
### 2.3 请求示例
```json
POST /harness/chat
Host: localhost:8080
Content-Type: application/json
Accept: text/event-stream
{
"sessionId": "sess-20260918-001",
"userId": "user-10001",
"input": "帮我梳理今天的任务清单,生成一份 markdown 并保存到工作区",
"chatModel": {
"name": "gpt-oss-120b",
"stream": true,
"temperature": 0.2
}
}
```
> ⚠️ 注意:当前实现中 `chatModel` 并未被使用(`HarnessAgent.builder().build()` 未传入模型配置)。如需按请求指定模型,需要扩展 `HarnessChatGateway`。
## 3. 响应
### 3.1 格式一:SSE(推荐,`Accept: text/event-stream`
每发生一个事件,服务端推送一条 `data:`,事件之间以空行分隔:
```
data:{"type":"AGENT_START","id":"4f9c1e2d8a7b4c5d9e0f1a2b3c4d5e6f","createdAt":"2026-09-18T02:30:45.123456Z","sessionId":"sess-20260918-001","replyId":"reply-7f3a91","name":"assistant","role":"assistant"}
data:{"type":"THINKING_BLOCK_START","id":"...","createdAt":"...","replyId":"reply-7f3a91","blockId":"blk-001"}
data:{"type":"TEXT_BLOCK_DELTA","id":"...","createdAt":"...","replyId":"reply-7f3a91","blockId":"blk-002","delta":"已完成"}
```
### 3.2 格式二:JSON 数组(默认 / `Accept: application/json`
整个事件流序列化为一个 JSON 数组,随事件产生逐个写出:
```json
[
{ "type": "AGENT_START", "...": "..." },
{ "type": "THINKING_BLOCK_START", "...": "..." },
{ "type": "TEXT_BLOCK_DELTA", "...": "..." }
]
```
### 3.3 HTTP 状态
| 状态码 | 说明 |
| --- | --- |
| `200` | 正常,返回事件流 |
| `400` | 校验失败(`sessionId` / `userId` / `input` 为空时抛 `400 Bad Request` |
| `500` | 智能体执行异常(模型未配置、会话中断等) |
## 4. 事件通用结构
所有事件(`AgentEvent`)都包含以下通用字段,通过 `type` 字段区分具体事件类型:
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `type` | String | **类型判别器**,取值见 §5 |
| `id` | String | 事件唯一 ID(32 位十六进制,无连字符 UUID) |
| `createdAt` | String | 事件创建时间,ISO-8601 格式(如 `2026-09-18T02:30:45.123456Z` |
| `source` | String | 事件来源路径。顶层智能体事件为 `null`;子智能体转发的事件为 `main/researcher` 形式。**无值时缺省(不输出)** |
| `metadata` | Object | 附加元数据,**空时不输出** |
`type` / `id` / `createdAt` 必现;其余字段视事件类型而定。以下各事件示例均基于同一会话回环 `"replyId":"reply-7f3a91"`
## 5. AgentEvent 类型详解与数据示例
### 5.1 AGENT_START — 智能体开始处理
表示一次智能体调用开始。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `sessionId` | String | 会话 ID |
| `replyId` | String | 本轮回复 ID,用于关联同一轮事件 |
| `name` | String | 智能体名称 |
| `role` | String | 默认 `"assistant"` |
```json
{
"type": "AGENT_START",
"id": "4f9c1e2d8a7b4c5d9e0f1a2b3c4d5e6f",
"createdAt": "2026-09-18T02:30:45.123456Z",
"sessionId": "sess-20260918-001",
"replyId": "reply-7f3a91",
"name": "assistant",
"role": "assistant"
}
```
### 5.2 THINKING_BLOCK_START — 思考块开始
模型开始推理(ReAct 的 reasoning 阶段)。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `replyId` | String | 回复 ID |
| `blockId` | String | 思考块 ID |
```json
{
"type": "THINKING_BLOCK_START",
"id": "1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d",
"createdAt": "2026-09-18T02:30:45.200000Z",
"replyId": "reply-7f3a91",
"blockId": "blk-001"
}
```
### 5.3 THINKING_BLOCK_DELTA — 思考内容增量
逐段推送思考内容。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `replyId` | String | 回复 ID |
| `blockId` | String | 思考块 ID |
| `delta` | String | 增量文本 |
```json
{
"type": "THINKING_BLOCK_DELTA",
"id": "2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e",
"createdAt": "2026-09-18T02:30:45.210000Z",
"replyId": "reply-7f3a91",
"blockId": "blk-001",
"delta": "用户希望将任务清单整理成 markdown 文件并保存,需要先规划目录结构。"
}
```
### 5.4 THINKING_BLOCK_END — 思考块结束
```json
{
"type": "THINKING_BLOCK_END",
"id": "3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f",
"createdAt": "2026-09-18T02:30:45.350000Z",
"replyId": "reply-7f3a91",
"blockId": "blk-001"
}
```
### 5.5 MODEL_CALL_START — 模型调用开始
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `replyId` | String | 回复 ID |
```json
{
"type": "MODEL_CALL_START",
"id": "4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f90",
"createdAt": "2026-09-18T02:30:45.180000Z",
"replyId": "reply-7f3a91"
}
```
### 5.6 MODEL_CALL_END — 模型调用结束(含 token 用量)
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `replyId` | String | 回复 ID |
| `usage` | Object | token 用量统计 |
`usage` 结构:
```json
{
"type": "MODEL_CALL_END",
"id": "5e6f7a8b9c0d1e2f3a4b5c6d7e8f9001",
"createdAt": "2026-09-18T02:30:45.680000Z",
"replyId": "reply-7f3a91",
"usage": {
"inputTokens": 1250,
"outputTokens": 320,
"cachedTokens": 512,
"time": 0.482,
"totalTokens": 1570
}
}
```
| usage 字段 | 类型 | 说明 |
| --- | --- | --- |
| `inputTokens` | Integer | 输入 token 数(含缓存部分) |
| `outputTokens` | Integer | 输出 token 数 |
| `cachedTokens` | Integer | 命中 prompt 缓存的输入 token 数(来自 inputTokens 的子集) |
| `time` | Number | 本次调用耗时(秒) |
| `totalTokens` | Integer | `inputTokens + outputTokens`(派生字段) |
### 5.7 TOOL_CALL_START — 工具调用开始
模型决定调用某个工具(ReAct 的 acting 阶段)。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `replyId` | String | 回复 ID |
| `toolCallId` | String | 工具调用 ID |
| `toolCallName` | String | 工具名 |
```json
{
"type": "TOOL_CALL_START",
"id": "6f7a8b9c0d1e2f3a4b5c6d7e8f900112",
"createdAt": "2026-09-18T02:30:45.700000Z",
"replyId": "reply-7f3a91",
"toolCallId": "call_9f2c4d",
"toolCallName": "shell_execute"
}
```
### 5.8 TOOL_CALL_DELTA — 工具入参流式增量
工具参数以 JSON 字符串形式分片送达。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `replyId` | String | 回复 ID |
| `toolCallId` | String | 工具调用 ID |
| `toolCallName` | String | 工具名 |
| `delta` | String | 入参 JSON 片段 |
```json
{
"type": "TOOL_CALL_DELTA",
"id": "7a8b9c0d1e2f3a4b5c6d7e8f90011223",
"createdAt": "2026-09-18T02:30:45.720000Z",
"replyId": "reply-7f3a91",
"toolCallId": "call_9f2c4d",
"toolCallName": "shell_execute",
"delta": "{\"command\":\"cat /tasks.json > "
}
```
```json
{
"type": "TOOL_CALL_DELTA",
"id": "8b9c0d1e2f3a4b5c6d7e8f9001122334",
"createdAt": "2026-09-18T02:30:45.730000Z",
"replyId": "reply-7f3a91",
"toolCallId": "call_9f2c4d",
"toolCallName": "shell_execute",
"delta": "\\\"/workspace/tasks.md\"}"
}
```
### 5.9 TOOL_CALL_END — 工具调用结束
```json
{
"type": "TOOL_CALL_END",
"id": "9c0d1e2f3a4b5c6d7e8f900112233445",
"createdAt": "2026-09-18T02:30:45.740000Z",
"replyId": "reply-7f3a91",
"toolCallId": "call_9f2c4d",
"toolCallName": "shell_execute"
}
```
### 5.10 TOOL_RESULT_START — 工具执行结果开始
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `replyId` | String | 回复 ID |
| `toolCallId` | String | 工具调用 ID |
| `toolCallName` | String | 工具名 |
| `metadata` | Object | 可选,如携带 `taskId` 等转发元数据(缺省) |
```json
{
"type": "TOOL_RESULT_START",
"id": "0d1e2f3a4b5c6d7e8f90011223344556",
"createdAt": "2026-09-18T02:30:46.050000Z",
"replyId": "reply-7f3a91",
"toolCallId": "call_9f2c4d",
"toolCallName": "shell_execute"
}
```
### 5.11 TOOL_RESULT_TEXT_DELTA — 工具结果文本增量
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `replyId` | String | 回复 ID |
| `toolCallId` | String | 工具调用 ID |
| `toolCallName` | String | 工具名 |
| `delta` | String | 结果文本片段 |
```json
{
"type": "TOOL_RESULT_TEXT_DELTA",
"id": "1e2f3a4b5c6d7e8f9001122334455667",
"createdAt": "2026-09-18T02:30:46.060000Z",
"replyId": "reply-7f3a91",
"toolCallId": "call_9f2c4d",
"toolCallName": "shell_execute",
"delta": "exit_code=0\n"
}
```
```json
{
"type": "TOOL_RESULT_TEXT_DELTA",
"id": "2f3a4b5c6d7e8f9001122334455667788",
"createdAt": "2026-09-18T02:30:46.070000Z",
"replyId": "reply-7f3a91",
"toolCallId": "call_9f2c4d",
"toolCallName": "shell_execute",
"delta": "任务清单已保存到 /workspace/tasks.md"
}
```
### 5.12 TOOL_RESULT_DATA_DELTA — 工具结果二进制数据增量
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `replyId` | String | 回复 ID |
| `toolCallId` | String | 工具调用 ID |
| `toolCallName` | String | 工具名 |
| `data` | Object | 一个多态 ContentBlock`type` 判别器),常见为 `data` 类型携带 base64 数据 |
`data``type` 取值:`text` / `thinking` / `image` / `audio` / `video` / `tool_use` / `tool_result` / `hint` / `data`
```json
{
"type": "TOOL_RESULT_DATA_DELTA",
"id": "3a4b5c6d7e8f900112233445566778899",
"createdAt": "2026-09-18T02:30:46.080000Z",
"replyId": "reply-7f3a91",
"toolCallId": "call_9f2c4d",
"toolCallName": "render_chart",
"data": {
"type": "data",
"source": {
"type": "base64",
"media_type": "image/png",
"data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=="
},
"id": "d4a3b2c1d5e6f7a8b9c0d1e2f3a4b5c6",
"name": "chart.png"
}
}
```
> URL 型数据源示例:`"source": { "type": "url", "url": "https://cdn.example.com/tmp/chart.png", "mime_type": "image/png" }`
### 5.13 TOOL_RESULT_END — 工具结果结束(含执行状态)
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `replyId` | String | 回复 ID |
| `toolCallId` | String | 工具调用 ID |
| `toolCallName` | String | 工具名 |
| `state` | String | 执行结果:`success` / `error` / `interrupted` / `denied` / `running` |
```json
{
"type": "TOOL_RESULT_END",
"id": "4b5c6d7e8f90011223344556677889900",
"createdAt": "2026-09-18T02:30:46.150000Z",
"replyId": "reply-7f3a91",
"toolCallId": "call_9f2c4d",
"toolCallName": "shell_execute",
"state": "success"
}
```
**失败示例(state = error):**
```json
{
"type": "TOOL_RESULT_END",
"id": "5c6d7e8f9001122334455667788990011",
"createdAt": "2026-09-18T02:30:47.200000Z",
"replyId": "reply-7f3a91",
"toolCallId": "call_9f2c4d",
"toolCallName": "shell_execute",
"state": "error"
}
```
### 5.14 DATA_BLOCK_START — 二进制数据块开始
用于向用户直接推送二进制内容(图片 / 音频 / 视频 / 文件),通常出现在最终答案阶段。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `replyId` | String | 回复 ID |
| `blockId` | String | 数据块 ID |
```json
{
"type": "DATA_BLOCK_START",
"id": "6d7e8f900112233445566778899001122",
"createdAt": "2026-09-18T02:30:48.000000Z",
"replyId": "reply-7f3a91",
"blockId": "blk-003"
}
```
### 5.15 DATA_BLOCK_DELTA — 二进制数据块增量
`delta` 为二进制内容的 **base64** 分片。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `replyId` | String | 回复 ID |
| `blockId` | String | 数据块 ID |
| `delta` | String | base64 数据分片 |
```json
{
"type": "DATA_BLOCK_DELTA",
"id": "7e8f90011223344556677889900112233",
"createdAt": "2026-09-18T02:30:48.010000Z",
"replyId": "reply-7f3a91",
"blockId": "blk-003",
"delta": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=="
}
```
### 5.16 DATA_BLOCK_END — 二进制数据块结束
```json
{
"type": "DATA_BLOCK_END",
"id": "8f9001122334455667788990011223344",
"createdAt": "2026-09-18T02:30:48.100000Z",
"replyId": "reply-7f3a91",
"blockId": "blk-003"
}
```
### 5.17 TEXT_BLOCK_START — 文本块开始
```json
{
"type": "TEXT_BLOCK_START",
"id": "900112233445566778899001122334455",
"createdAt": "2026-09-18T02:30:47.500000Z",
"replyId": "reply-7f3a91",
"blockId": "blk-002"
}
```
### 5.18 TEXT_BLOCK_DELTA — 文本块流式增量(最终答案)
前端据此逐字渲染智能体回复。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `replyId` | String | 回复 ID |
| `blockId` | String | 文本块 ID |
| `delta` | String | 文本增量 |
```json
{
"type": "TEXT_BLOCK_DELTA",
"id": "a011223344556677889900112233445566",
"createdAt": "2026-09-18T02:30:47.510000Z",
"replyId": "reply-7f3a91",
"blockId": "blk-002",
"delta": "已完成,"
}
```
```json
{
"type": "TEXT_BLOCK_DELTA",
"id": "b112233445566778899001122334455667",
"createdAt": "2026-09-18T02:30:47.520000Z",
"replyId": "reply-7f3a91",
"blockId": "blk-002",
"delta": "任务清单已保存至 /workspace/tasks.md"
}
```
### 5.19 TEXT_BLOCK_END — 文本块结束
```json
{
"type": "TEXT_BLOCK_END",
"id": "c223344556677889900112233445566778",
"createdAt": "2026-09-18T02:30:47.600000Z",
"replyId": "reply-7f3a91",
"blockId": "blk-002"
}
```
### 5.20 AGENT_RESULT — 智能体最终结果(含完整 Msg)
`AGENT_END` 之前发出,携带本轮最终回复消息 `Msg`。调用方可以从事件流直接取结果,无需另外订阅返回值。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `result` | Object | 最终消息体(多态,`role` 为判别器:`USER` / `ASSISTANT` / `SYSTEM` / `TOOL` |
`result`Msg)字段:
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `id` | String | 消息 IDUUID |
| `name` | String | 消息发送方名称,可为 `null` |
| `role` | String | 角色:`USER` / `ASSISTANT` / `SYSTEM` / `TOOL` |
| `content` | Array | 内容块数组(多态,`type` 判别器) |
| `metadata` | Object | 元数据,如 `agentscope_generate_reason` |
| `timestamp` | String | 消息时间戳,格式 `yyyy-MM-dd HH:mm:ss.SSS` |
| `usage` | Object | token 用量(同 §5.6),可为 `null` |
```json
{
"type": "AGENT_RESULT",
"id": "d33445566778899001122334455667788",
"createdAt": "2026-09-18T02:30:48.200000Z",
"result": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "assistant",
"role": "ASSISTANT",
"content": [
{
"type": "text",
"text": "已完成,任务清单已保存至 /workspace/tasks.md"
}
],
"metadata": {
"agentscope_generate_reason": "MODEL_STOP"
},
"timestamp": "2026-09-18 10:30:48.200",
"usage": {
"inputTokens": 1250,
"outputTokens": 320,
"cachedTokens": 512,
"time": 2.46,
"totalTokens": 1570
}
}
}
```
> 多模态回复的 `content` 举例(图片 + 文本混排):
> ```json
> "content": [
> { "type": "text", "text": "这是生成的图表:" },
> { "type": "data", "source": { "type": "url", "url": "https://cdn.example.com/chart.png", "mime_type": "image/png" }, "id": "d4a3b2c1d5e6f7a8b9c0d1e2f3a4b5c6", "name": "chart.png" }
> ]
> ```
### 5.21 AGENT_END — 智能体结束处理
```json
{
"type": "AGENT_END",
"id": "e455667788990011223344556677889900",
"createdAt": "2026-09-18T02:30:48.300000Z",
"replyId": "reply-7f3a91"
}
```
### 5.22 EXCEED_MAX_ITERS — ReAct 循环超过最大迭代次数
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `replyId` | String | 回复 ID |
| `maxIters` | Integer | 配置的最大迭代次数 |
| `currentIter` | Integer | 实际到达的迭代次数 |
```json
{
"type": "EXCEED_MAX_ITERS",
"id": "f566778899001122334455667788990011",
"createdAt": "2026-09-18T02:30:52.000000Z",
"replyId": "reply-7f3a91",
"maxIters": 10,
"currentIter": 10
}
```
### 5.23 REQUIRE_USER_CONFIRM — 需要用户确认工具调用(HITL 暂停)
智能体在执行敏感工具前暂停,等待用户逐条确认(前端应弹出授权窗口)。工具调用状态为 `asking`
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `replyId` | String | 回复 ID |
| `toolCalls` | Array | 待确认的 `ToolUseBlock` 列表 |
`ToolUseBlock` 字段:`id``name``input`Map)、`content`(流式原始内容,可空)、`metadata``state``pending` / `asking` / `allowed` / `submitted` / `finished`)。
```json
{
"type": "REQUIRE_USER_CONFIRM",
"id": "6778899001122334455667788990011223",
"createdAt": "2026-09-18T02:30:45.750000Z",
"replyId": "reply-7f3a91",
"toolCalls": [
{
"id": "call_9f2c4d",
"name": "shell_execute",
"input": {
"command": "rm -rf /workspace/old/"
},
"content": null,
"metadata": {},
"state": "asking"
},
{
"id": "call_5a1b02",
"name": "http_post",
"input": {
"url": "https://api.example.com/orders",
"body": "{\"id\": 10086}"
},
"content": null,
"metadata": {},
"state": "asking"
}
]
}
```
### 5.24 USER_CONFIRM_RESULT — 用户确认结果回传
用户对 `REQUIRE_USER_CONFIRM` 的响应结果(同一会话的下一轮调用事件流中可能出现)。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `replyId` | String | 回复 ID |
| `confirmResults` | Array | `ConfirmResult` 列表 |
`ConfirmResult` 字段:
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `confirmed` | Boolean | 是否批准 |
| `toolCall` | Object | 对应的 `ToolUseBlock`(用户可修改入参) |
| `rules` | Array | 用户新增的权限规则(允许后续免确认),可为空 |
```json
{
"type": "USER_CONFIRM_RESULT",
"id": "7889900112233445566778899001122334",
"createdAt": "2026-09-18T02:31:05.000000Z",
"replyId": "reply-7f3a91",
"confirmResults": [
{
"confirmed": true,
"toolCall": {
"id": "call_9f2c4d",
"name": "shell_execute",
"input": {
"command": "rm -rf /workspace/old/"
},
"content": null,
"metadata": {},
"state": "asking"
},
"rules": [
{
"tool_name": "shell_execute",
"rule_content": "rm -rf /workspace/*",
"behavior": "allow",
"source": "userSettings"
}
]
},
{
"confirmed": false,
"toolCall": {
"id": "call_5a1b02",
"name": "http_post",
"input": {
"url": "https://api.example.com/orders",
"body": "{\"id\": 10086}"
},
"content": null,
"metadata": {},
"state": "asking"
},
"rules": null
}
]
}
```
### 5.25 ALL_TOOLS_DENIED — 本轮所有工具均被拒绝
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `deniedToolCalls` | Array | 被拒绝的 `ToolUseBlock` 列表 |
```json
{
"type": "ALL_TOOLS_DENIED",
"id": "89900112233445566778899001122334455",
"createdAt": "2026-09-18T02:31:05.100000Z",
"deniedToolCalls": [
{
"id": "call_5a1b02",
"name": "http_post",
"input": {
"url": "https://api.example.com/orders",
"body": "{\"id\": 10086}"
},
"content": null,
"metadata": {},
"state": "asking"
}
]
}
```
### 5.26 REQUIRE_EXTERNAL_EXECUTION — 需要外部(进程外)执行工具
工具需由调用方在进程外执行,智能体暂停等待结果。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `replyId` | String | 回复 ID |
| `toolCalls` | Array | 待外部执行的 `ToolUseBlock` 列表 |
```json
{
"type": "REQUIRE_EXTERNAL_EXECUTION",
"id": "9001122334455667788990011223344556",
"createdAt": "2026-09-18T02:30:45.900000Z",
"replyId": "reply-7f3a91",
"toolCalls": [
{
"id": "call_0f3e9a",
"name": "human_approval_flow",
"input": {
"title": "发布订单 10086 到生产环境"
},
"content": null,
"metadata": {},
"state": "pending"
}
]
}
```
### 5.27 EXTERNAL_EXECUTION_RESULT — 外部执行结果回传
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `replyId` | String | 回复 ID |
| `toolResults` | Array | `ToolResultBlock` 列表 |
`ToolResultBlock` 字段:`id``name``output`ContentBlock 数组)、`metadata``state``success` / `error` / `interrupted` / `denied` / `running`)。
```json
{
"type": "EXTERNAL_EXECUTION_RESULT",
"id": "a112233445566778899001122334455667",
"createdAt": "2026-09-18T02:31:20.000000Z",
"replyId": "reply-7f3a91",
"toolResults": [
{
"id": "call_0f3e9a",
"name": "human_approval_flow",
"output": [
{
"type": "text",
"text": "审批人张三已批准,订单 10086 已发布。"
}
],
"metadata": {},
"state": "success"
}
]
}
```
### 5.28 REQUEST_STOP — 请求暂停执行
中间件 / 权限引擎要求智能体在当前步骤结束后暂停(如预算超限、合规审查点)。调用方可在下一轮使用相同 `sessionId` 继续该会话,待执行的工具调用会自动恢复。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `reason` | String | 停止原因(人类可读) |
| `generateReason` | String | 停止原因枚举名:`MODEL_STOP` / `TOOL_CALLS` / `STRUCTURED_OUTPUT` / `TOOL_SUSPENDED` / `REASONING_STOP_REQUESTED` / `ACTING_STOP_REQUESTED` / `PERMISSION_ASKING` / `MIDDLEWARE_STOP_REQUESTED` / `ALL_TOOLS_DENIED` / `INTERRUPTED` / `MAX_ITERATIONS`,默认 `MIDDLEWARE_STOP_REQUESTED` |
```json
{
"type": "REQUEST_STOP",
"id": "b223344556677889900112233445566778",
"createdAt": "2026-09-18T02:30:49.000000Z",
"reason": "单轮 token 消耗超过预算上限 100K,已暂停"
}
```
```json
{
"type": "REQUEST_STOP",
"id": "c334455667788990011223344556677889",
"createdAt": "2026-09-18T02:30:49.100000Z",
"reason": "权限引擎要求用户确认高风险操作",
"generateReason": "PERMISSION_ASKING"
}
```
### 5.29 SUBAGENT_EXPOSED — 子智能体对外暴露
通过 `agent_spawn(expose_to_user=true)` 生成的子智能体成为可寻址的独立会话入口,SSE 消费端据此在 UI 渲染新的会话卡片。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `subagentId` | String | 子智能体实例 ID |
| `agentId` | String | 子智能体定义 ID |
| `sessionId` | String | 子智能体会话 ID |
| `label` | String | 展示名称 |
```json
{
"type": "SUBAGENT_EXPOSED",
"id": "d445566778899001122334455667788990",
"createdAt": "2026-09-18T02:31:02.000000Z",
"subagentId": "sub-0a1b2c3d",
"agentId": "data-analyst",
"sessionId": "sess-sub-88",
"label": "数据分析助手"
}
```
### 5.30 HINT_BLOCK — 一次性提示块
一次性完整下发(不流式),用途包括团队消息、后台工具结果、用户打断等。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `replyId` | String | 回复 ID |
| `blockId` | String | 提示块 ID |
| `hintSource` | String | 来源(团队消息发送者姓名、`system``null` |
| `hint` | String | 完整提示内容 |
```json
{
"type": "HINT_BLOCK",
"id": "e556677889900112233445566778899001",
"createdAt": "2026-09-18T02:31:03.000000Z",
"replyId": "reply-7f3a91",
"blockId": "blk-hint-01",
"hintSource": "alice",
"hint": "alice 加入了会话,可以开始协作。"
}
```
### 5.31 CUSTOM — 自定义扩展事件
业务中间件用于推送自有状态(未知 `name` 前端应跳过不报错)。约定 `name``state_updated`(任务/权限状态变化)、`team_updated`(团队变更)等。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `name` | String | 事件名 |
| `value` | Object | 任意 JSON 负载 |
```json
{
"type": "CUSTOM",
"id": "f667788990011223344556677889900112",
"createdAt": "2026-09-18T02:31:04.000000Z",
"name": "task_progress",
"value": {
"taskId": "task-201",
"progress": 66,
"status": "RUNNING",
"detail": "正在生成页面截图"
}
}
```
```json
{
"type": "CUSTOM",
"id": "a778899001122334455667788990011223",
"createdAt": "2026-09-18T02:31:04.500000Z",
"name": "team_updated",
"value": {
"action": "MEMBER_ADDED",
"member": "bob",
"teamId": "team-007"
}
}
```
## 6. 典型一轮完整事件流(SSE,按顺序)
以「用户要求整理任务清单并保存为 markdown」为例(含工具调用):
```text
data:{"type":"AGENT_START","id":"...","createdAt":"...","sessionId":"sess-20260918-001","replyId":"reply-7f3a91","name":"assistant","role":"assistant"}
data:{"type":"MODEL_CALL_START","id":"...","createdAt":"...","replyId":"reply-7f3a91"}
data:{"type":"THINKING_BLOCK_START","id":"...","createdAt":"...","replyId":"reply-7f3a91","blockId":"blk-001"}
data:{"type":"THINKING_BLOCK_DELTA","id":"...","createdAt":"...","replyId":"reply-7f3a91","blockId":"blk-001","delta":"先读取任务源文件,再生成 markdown"}
data:{"type":"THINKING_BLOCK_END","id":"...","createdAt":"...","replyId":"reply-7f3a91","blockId":"blk-001"}
data:{"type":"MODEL_CALL_END","id":"...","createdAt":"...","replyId":"reply-7f3a91","usage":{"inputTokens":520,"outputTokens":80,"cachedTokens":0,"time":0.41,"totalTokens":600}}
data:{"type":"TOOL_CALL_START","id":"...","createdAt":"...","replyId":"reply-7f3a91","toolCallId":"call_9f2c4d","toolCallName":"shell_execute"}
data:{"type":"TOOL_CALL_DELTA","id":"...","createdAt":"...","replyId":"reply-7f3a91","toolCallId":"call_9f2c4d","toolCallName":"shell_execute","delta":"{\"command\":\"cat /tasks.json\"}"}
data:{"type":"TOOL_CALL_END","id":"...","createdAt":"...","replyId":"reply-7f3a91","toolCallId":"call_9f2c4d","toolCallName":"shell_execute"}
data:{"type":"TOOL_RESULT_START","id":"...","createdAt":"...","replyId":"reply-7f3a91","toolCallId":"call_9f2c4d","toolCallName":"shell_execute"}
data:{"type":"TOOL_RESULT_TEXT_DELTA","id":"...","createdAt":"...","replyId":"reply-7f3a91","toolCallId":"call_9f2c4d","toolCallName":"shell_execute","delta":"3 个任务待办..."}
data:{"type":"TOOL_RESULT_END","id":"...","createdAt":"...","replyId":"reply-7f3a91","toolCallId":"call_9f2c4d","toolCallName":"shell_execute","state":"success"}
data:{"type":"MODEL_CALL_START","id":"...","createdAt":"...","replyId":"reply-7f3a91"}
data:{"type":"MODEL_CALL_END","id":"...","createdAt":"...","replyId":"reply-7f3a91","usage":{"inputTokens":1600,"outputTokens":330,"cachedTokens":512,"time":1.8,"totalTokens":1930}}
data:{"type":"TEXT_BLOCK_START","id":"...","createdAt":"...","replyId":"reply-7f3a91","blockId":"blk-002"}
data:{"type":"TEXT_BLOCK_DELTA","id":"...","createdAt":"...","replyId":"reply-7f3a91","blockId":"blk-002","delta":"已完成,"}
data:{"type":"TEXT_BLOCK_DELTA","id":"...","createdAt":"...","replyId":"reply-7f3a91","blockId":"blk-002","delta":"任务清单已保存至 /workspace/tasks.md"}
data:{"type":"TEXT_BLOCK_END","id":"...","createdAt":"...","replyId":"reply-7f3a91","blockId":"blk-002"}
data:{"type":"AGENT_RESULT","id":"...","createdAt":"...","result":{"id":"550e8400-e29b-41d4-a716-446655440000","name":"assistant","role":"ASSISTANT","content":[{"type":"text","text":"已完成,任务清单已保存至 /workspace/tasks.md"}],"metadata":{"agentscope_generate_reason":"MODEL_STOP"},"timestamp":"2026-09-18 10:30:48.200","usage":{"inputTokens":1600,"outputTokens":330,"cachedTokens":512,"time":1.8,"totalTokens":1930}}}
data:{"type":"AGENT_END","id":"...","createdAt":"...","replyId":"reply-7f3a91"}
```
事件一般顺序:`AGENT_START``MODEL_CALL_*` / `THINKING_BLOCK_*` / `TOOL_CALL_*` / `TOOL_RESULT_*` 可能多轮循环) → `TEXT_BLOCK_*``AGENT_RESULT``AGENT_END`。涉及 HITL 时会插入 `REQUIRE_USER_CONFIRM`(见 §5.23)。
## 7. 注意事项
1. **延续会话**:同一 `(userId, sessionId)` 组合的上下文会自动累积;不同会话互不干扰。`REQUEST_STOP``REQUIRE_USER_CONFIRM` 暂停后,用相同 `sessionId` 再发一次请求即可恢复执行。
2. **事件 ID**`id` 为 32 位十六进制(无连字符 UUID),可用于调试与去重;`createdAt` 为 ISO-8601UTC)。
3. **未知事件**:前端对 `type: CUSTOM` 中未知的 `name` 应静默跳过;对表外未知 `type` 应尽量容忍(服务端可能升级新增事件)。
4. **空字段省略**:顶层事件的 `source``metadata` 及无值字段在 JSON 中缺省(`NON_NULL` 策略);`Msg` 内部字段(如 `name``usage`)则为 `null` 或对象。
+1
View File
@@ -0,0 +1 @@
123
+205 -5
View File
@@ -1,11 +1,211 @@
# SQL
# 目录
常用的脚本。
- [查智能体用户数](#查智能体用户数)
- [查客户端是否登录](#查客户端是否登录)
- [查智能体对话日志](#查智能体对话日志)
- [查智能体信息](#查智能体信息)
- [查智能体使用数据](查智能体使用数据)
- [查项目统计数据](#查项目统计数据)
- [新增devco账号](#新增devco账号)
- [查paw-agent信息](#查paw-agent信息)
## 查智能体用户数
## 查智能体用户数
```sql
select '单智能体' AS agent_type, agent.agent_id, agent.agent_name, IFNULL(aus.user_num,0) AS user_num from `agent` AS agent left join agent_usage_stats AS aus ON agent.agent_id = aus.agent_id where agent.del_flag = '0'
select
'单智能体' AS agent_type,
agent.agent_id,
agent.agent_name,
IFNULL (aus.user_num, 0) AS user_num
from
`agent` AS agent
left join agent_usage_stats AS aus ON agent.agent_id = aus.agent_id
where
agent.del_flag = '0'
UNION ALL
select '多智能体' AS agent_type, ma.agent_id, ma.agent_name, IFNULL(maus.user_num,0) AS user_num from `multi_agent_main` AS ma left join agent_usage_stats AS maus ON ma.agent_id = maus.agent_id where ma.del_flag = '0';
select
'多智能体' AS agent_type,
ma.agent_id,
ma.agent_name,
IFNULL (maus.user_num, 0) AS user_num
from
`multi_agent_main` AS ma
left join agent_usage_stats AS maus ON ma.agent_id = maus.agent_id
where
ma.del_flag = '0';
```
## 查客户端是否登录
```sql
select
*
from
`mis-cloud-claw`.`sys_logininfor`
where
client_key = (
select
client_key
from
`mis-cloud-claw`.`sys_client`
where
`client_id` = '客户端ID'
);
```
## 查智能体对话日志
1. 查询所有切片号,假设查询出来的`part`是[1,2]
```sql
select part from log_agent_chat where del_flag = '0';
```
2. 根据切片号查询并合并各个切片表的数据
```sql
select * from log_agent_chat_1 where chat_window_id = ID
UNION ALL
select * from log_agent_chat_2 where chat_window_id = ID
```
## 查智能体信息
必须提供**智能体ID**,在不明确用户查询的是单智能体还是多智能体时,友好的询问要查询哪种智能体。
1. 查询单智能体信息
```sql
with agent_info AS (
select
agent_id,
agent_name,
system_prompt,
`description`,
max_messages,
max_tokens,
kb_uuids,
kb_configs,
kb_similarity_threshold,
kb_top_k,
kb_max_recall_toekn,
llm_name,
long_term_memory,
case kb_mode when '1' then '直接检索' when '2' then 'tool检索' else '' end AS kb_mode,
case kb_search_type when '0' then '向量检索' when '1' then '混合检索' when '2' then '智能检索' else '' end AS kb_search_type
from mis-agent.agent
where agent_id = <ID>
),
agent_skill AS (
select
<ID> AS agent_id,
GROUP_CONCAT(skill_name) AS skill_names
from mis-mcp.skill
where skill_id in (
select skill_id from mis-agent.agent_skill_mapping
where agent_id = <ID>
)
),
agent_mcp_tool AS (
select
<ID> AS agent_id,
GROUP_CONCAT(tool_name) AS tool_names
from mis-mcp.map_tools
where mcp_server_uuid in (
select mcp_server_uuid from mis-agent.agent_tool_mapping
where relate_agent_id = <ID>
)
)
select * from agent_info AS a
left join agent_skill AS b on a.agent_id = b.agent_id
left join agent_mcp_tool AS c on a.agent_id = c.agent_id
```
2. 查询多智能体信息
```sql
select * from mis-agent.agent_release_info where release_id in (
select
release_id
from mis-agent.multi_agent_sub
where main_agent_id = <ID>
)
```
## 查智能体使用数据
必须提供**智能体ID**。
```sql
select * from mis-agent.agent_usage_stats_daily where agent_id = <ID> order by daily desc
```
## 查项目统计数据
必须提供**项目名称**。
1. 查询项目注册表,判断是否包含该项目。用户提供的项目名称大概率是模糊的,比如"认证"、"ebiz",要根据语义判断究竟是哪一个,如果猜不准就询问一下用户是哪个。
```sql
select * from mis-agent.project_stats_registry
```
**重要:`project_stats_registry`里的`id`字段,称为项目ID,或者叫project_id,后面的步骤需要用到。**
2. 查询项目统计数据
```sql
select * from mis-agent.project_data_stats_daily where project_id = <project_id>
```
## 新增devco账号
用户的输入格式如下。
```text
devco
username1
username2
username3
```
- 在用户的输入中,`devco`是触发d当前技能的关键词。
- **从第二行开始,去掉空白行以后,每一个都是用户名。**如果用户提供的用户名存在重复,请忽略大小写保留1个即可。
- `client_id``state`字段是固定值,用户名对应的是`account`字段。
**在`mis-dev`资源下的`mis-cloud-paw`库中执行**批量插入sql,示例:
```sql
INSERT INTO external_login_client_account (client_id, account, state) VALUES
('226c18408b5705449f37b621a432a6d3', 'username1', 1),
('226c18408b5705449f37b621a432a6d3', 'username2', 1),
('226c18408b5705449f37b621a432a6d3', 'username3', 1);
```
## 查paw-agent信息
`mis-dev`资源下,根据用户名(username)查询paw-agent信息,如果用户没有提供username,友好的提问要查哪个用户的,一个可用的username示例:`Agnes2.wang`
1. 根据用户提供的`username`查询`user_id`,只会查出来1行数据,示例:
```sql
select user_id from `mis-cloud-claw`.`sys_user` where user_name = '{username}';
```
2. 根据`user_id`查询agent信息,可能返回多行数据,使用markdown表格的形式展示每一行的数据,示例:
```sql
select
agent_id,
agent_mode,
publish_status,
publish_scope,
published_at,
version_lane,
key_scope_default
from
`mis-paw-claw`.`agent`
where
create_by = < user_id >;
```
+31 -5
View File
@@ -24,12 +24,38 @@ CREATE TABLE `mis-debugging`.`work_sheet` (
`finish_time` DATETIME NULL COMMENT '执行结束时间',
PRIMARY KEY (`id`),
KEY idx_task_id(`task_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='工单表';
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='工单表':
```
## Nacos
## 集成Harness
```yml
xx:
yy: zz
### Nacos
参见`qas`环境的`se-harness-agent.yml`配置文件。
### 新建的表
`agentscope-java`源码提取而来。
```sql
CREATE TABLE IF NOT EXISTS agent_skill (
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL UNIQUE,
description TEXT NOT NULL,
skill_content LONGTEXT NOT NULL,
source VARCHAR(255) NOT NULL,
metadata_json LONGTEXT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS agent_skill_resource (
id BIGINT NOT NULL,
resource_path VARCHAR(500) NOT NULL,
resource_content LONGTEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id, resource_path),
FOREIGN KEY (id) REFERENCES agent_skill (id) ON DELETE CASCADE
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
```