# Teach Agent Hub

基于 Node.js Monorepo 的首版工程骨架，后端使用 NestJS，前端使用 Vue3，对齐架构图中的网关层、Agent 中台、执行层、可观测性和运维控制台。

## 目录结构

```
apps/
	agent-gateway/    # API Gateway + 多工控机连接/会话/策略 + 实时通道(WS/SSE)
	agent-service/    # Planner/Runtime/Model Router + Guard/Memory/Registry/Policy + AUBO MCP tool-rpc 执行
	log-agent/        # 日志接收与 trace 维度查询
	admin-web/        # Vue3 控制台（IPC连接/会话/任务/实时流/人工接管）
packages/
	contracts/        # 前后端共享 DTO、事件、错误码
	sdk/              # http/ws/event-bus 客户端封装
infra/
	observability/    # otel collector + prometheus 基础配置
docs/
	架构图.dot
```

## 已落地接口（首批）

### agent-gateway

- POST /api/v1/ipc/connect
- GET /api/v1/ipc/connections
- DELETE /api/v1/ipc/connections/:connectionId
- POST /api/v1/sessions
- GET /api/v1/sessions/:sessionId
- POST /api/v1/commands/dispatch
- POST /api/v1/policy/check
- POST /api/v1/policy/confirm
- GET /api/v1/audit/events
- GET /api/v1/realtime/stream (SSE)
- POST /api/v1/realtime/events/publish (internal runtime trace uplink)

### agent-service

- POST /internal/v1/planner/plan
- POST /internal/v1/runtime/tasks
- POST /internal/v1/runtime/tasks/:taskId/cancel
- GET /internal/v1/runtime/tasks/:taskId
- POST /internal/v1/model/asr/transcribe
- POST /internal/v1/model/llm/parse-intent
- POST /internal/v1/model/router/invoke
- POST /internal/v1/model/multimodal/understand
- POST /internal/v1/policy/check
- GET /internal/v1/registry/skills
- GET /internal/v1/registry/skills/:skillId
- POST /internal/v1/registry/skills/resolve

### log-agent

- POST /internal/v1/logs/ingest
- GET /internal/v1/traces/:traceId
- GET /internal/v1/metrics/overview

## 快速启动

1. 安装依赖

```bash
pnpm install
```

2. 启动所有服务

```bash
pnpm dev
```

3. 或分别启动

```bash
pnpm --filter @teachagenthub/agent-gateway dev
pnpm --filter @teachagenthub/agent-service dev
pnpm --filter @teachagenthub/log-agent dev
pnpm --filter @teachagenthub/admin-web dev
```

默认端口见 `.env.example`。

语音自动收敛阈值可通过环境变量 `GATEWAY_ASR_SILENCE_TIMEOUT_MS` 调整（单位毫秒，默认 2400，最小 500）。

Skill 驱动框架可通过环境变量 `AGENT_SKILL_FRAMEWORK` 切换（`openclaw` / `hermes` / `native`，默认 `hermes`）。
Skill 目录和模块细分见 `docs/skill-catalog.md`。
Runtime 任务返回 `executionReport`，包含每个 skill 节点的状态、重试次数、耗时和输出结果。
执行中的 skill 节点状态会通过 realtime 通道推送，前端聊天页可实时显示节点运行态。
前端聊天页右侧为按 `taskId` 分组的技能执行时间线面板（甘特式），展示 started/completed/failed/skipped 节点进度。
Agent Runtime Executor 已改为直接调用 AUBO MCP JSON-RPC `tools/call`，通过 `AGENT_AUBO_MCP_RPC_URL` 指向外部部署的 MCP 服务。

模型层支持通过 Qwen 在线 API 进行语义理解（文本/语音/视频统一语义入口），并在输出前执行结构化 JSON 校验与重试。
当 `QWEN_API_KEY` 未配置时，模型层自动回退到本地规则解析。

Qwen 相关环境变量：

- `QWEN_API_BASE_URL`（默认 `https://dashscope.aliyuncs.com/compatible-mode/v1`）
- `QWEN_API_KEY`
- `QWEN_MODEL`（默认 `qwen3.6`）
- `QWEN_ASR_DISABLE_REALTIME`（默认 `true`，开启后录音结束再整段音频识别）
- `QWEN_TIMEOUT_MS`（默认 `12000`）
- `QWEN_RETRY_MAX`（默认 `2`）
- `QWEN_RETRY_BACKOFF_MS`（默认 `250`）

AUBO MCP 执行相关环境变量：

- `AGENT_AUBO_MCP_RPC_URL`（默认 `http://127.0.0.1:8822/mcp`）
- `AGENT_AUBO_MCP_TRANSPORT`（`http` 或 `rpcurl`，默认 `http`）
- `AGENT_AUBO_MCP_SERVERS_FILE`（`rpcurl` 模式下使用，指向 MCP 通用 `mcpServers` 配置文件）
- `AGENT_AUBO_MCP_SERVERS_JSON`（可选，`rpcurl` 模式下可直接传 JSON 字符串）
- `AGENT_AUBO_MCP_SERVER_NAME`（默认 `remote_aubo_mcp`）
- `AGENT_AUBO_RPCURL_BIN`（默认 `rpcurl`）
- `AGENT_AUBO_RPCURL_EXTRA_ARGS_JSON`（可选，JSON 数组，按需追加 rpcurl 参数）
- `AGENT_AUBO_MCP_TIMEOUT_MS`（默认 `12000`）
- `AGENT_AUBO_MCP_API_KEY`（可选）
- `AGENT_AUBO_KNOWLEDGE_DIR`（默认 `./knowledge/aubo`）

`rpcurl` 模式示例：

```bash
export AGENT_AUBO_MCP_TRANSPORT=rpcurl
export AGENT_AUBO_MCP_SERVERS_FILE=./apps/agent-service/config/mcp.servers.json
export AGENT_AUBO_MCP_SERVER_NAME=remote_aubo_mcp
pnpm --filter @teachagenthub/agent-service dev
```

一期本地知识库目录（文件检索，不依赖向量库）：

- `knowledge/aubo/tools/*.json`：工具定义与别名。
- `knowledge/aubo/args/*.json`：参数规则（类型、范围、必填）。
- `knowledge/aubo/risk/*.json`：风险策略（是否二次确认）。
- `knowledge/aubo/examples/*.json`：召回样例（支持正负样本）。

`agent-service` 会优先加载上述文件知识库；若加载失败或为空，会自动回退到内置默认规则，保证无破坏迁移。

文档 RAG 离线流水线（抓取 + 切片 + 向量索引）：

- 数据源配置文件：`knowledge/aubo/docs/rag.sources.json`
- 增量构建（默认，仅重抓变更页面）：`pnpm rag:build`
- 全量重建：`pnpm rag:build:full`
- 产物文件：`knowledge/aubo/docs/rag.index.json`
- 增量缓存：`knowledge/aubo/docs/rag.cache.json`
- 本地检索验证：`pnpm rag:query -- "ROS2 集成步骤"`

构建调优参数（适用于大规模站点）：

- `--concurrency <n>`：抓取并发数（默认 6）
- `--retry-max <n>`：失败重试次数（默认 2）
- `--retry-backoff-ms <ms>`：指数退避基数（默认 300）

文档回答模板已升级为：`结论 + 关键段落 + 原文链接 + 命中置信度 + 命中文档类别统计 + 版本时间`。

可选环境变量：

- `GATEWAY_DOCS_KNOWLEDGE_FILE`：文档目录索引（默认 `knowledge/aubo/docs/default.docs.json`）
- `GATEWAY_DOCS_RAG_INDEX_FILE`：向量索引文件（默认 `knowledge/aubo/docs/rag.index.json`）

## 端到端联调（最小可复现）

以下脚本覆盖链路：`commands/dispatch -> agent-service runtime executor -> MCP tools/call`。

1. 启动服务（至少 `agent-gateway`、`agent-service`）

```bash
pnpm --filter @teachagenthub/agent-gateway dev
pnpm --filter @teachagenthub/agent-service dev
```

2. 启动本地 mock AUBO MCP JSON-RPC 服务

```bash
pnpm e2e:mock-mcp
```

3. 运行联调脚本

```bash
pnpm e2e:dispatch
```

联调脚本会验证三个场景：

- 低风险工具调用：应通过。
- 高风险工具调用（未确认）：应被拦截，并返回 `POLICY_CONFIRM_REQUIRED`。
- 高风险工具调用（`highRiskConfirmed=true`）：应通过。

前端内嵌语音助手模式（示教器内嵌）配置：

- `VITE_EMBEDDED_ASSISTANT_MODE`（默认 `true`）：启用后自动连接本机 `127.0.0.1` 并自动创建会话，跳过工控机连接页。
- `VITE_GATEWAY_BASE_URL`（默认 `http://127.0.0.1:3000`）：内嵌前端调用网关地址。

内嵌模式下，前端会将 runtime 事件通过 `window.parent.postMessage` 透传给宿主示教器，消息结构：

```json
{
	"source": "teachagenthub-assistant",
	"kind": "runtime-event",
	"event": { "type": "device.command.accepted", "payload": {} }
}
```

会话与聊天记录持久化：

- 同一 IPC 会复用稳定 `sessionId`（例如 `sess_127_0_0_1`），不会因前端刷新而变更。
- 聊天消息（用户输入、语义结果、执行结果、助手回复）落库到 SQLite `voice_chat_record` 表。
- 历史查询接口：`GET /api/v1/sessions/:sessionId/chat-records`
- SQLite 路径可配置：`GATEWAY_SQLITE_PATH`（默认 `./data/gateway.db`）

## 典型调用流程（无登录）

1. 连接工控机

```bash
curl -X POST http://localhost:3000/api/v1/ipc/connect \
	-H "Content-Type: application/json" \
	-d '{"ipcIp":"192.168.1.10","name":"line-a-ipc"}'
```

2. 基于连接创建会话

```bash
curl -X POST http://localhost:3000/api/v1/sessions \
	-H "Content-Type: application/json" \
	-d '{"connectionId":"<connectionId>","targetType":"agv"}'
```

3. 定向下发指令（网关统一编排）

```bash
curl -X POST http://localhost:3000/api/v1/commands/dispatch \
	-H "Content-Type: application/json" \
	-d '{"sessionId":"<sessionId>","text":"move agv to station-a"}'
```

## 下一步建议

- 增加统一鉴权中间件（JWT 校验 + RBAC + 设备绑定）。
- 增加 AUBO MCP 工具参数级别的安全白名单和租户隔离策略。
- 在各服务增加 OpenTelemetry SDK，打通 traceId 跨服务传播。
- 补充 E2E 场景：成功链路、模型失败、执行超时、策略确认。
