声明式Agent配置、热重载机制、DataAgent(NL2SQL)与VoiceAgent(语音通道)
传统方式定义 Agent 需要编写 Java 代码(@Component + 继承 AbstractLlmAgent),对于运营/产品人员门槛较高。AgentSpec 提供声明式 YAML 配置,无需 Java 代码即可定义 Agent,大幅降低新 Agent 的创建门槛。
内置示例文件:项目在 hub-api/src/main/resources/agent-specs/ 下提供了 2 个开箱即用的示例:
translator-agent.yml(翻译助手)和 writer-agent.yml(写作助手),
展示了声明式 Agent 的完整字段用法(含 display 前端元数据)。
启用 agent.defaults.agent-spec.enabled=true 后自动加载注册。
# agents/deep_research.agent.yml
agent:
id: "deep_research"
name: "深度研究Agent"
model: "gpt-4o"
runtime-mode: "graph-parallel"
max-iterations: 15
system-prompt: |
你是专业研究分析师...
tools: [web_search, web_reader, note_taking]
interceptors: [todo-list, context-editing]
hooks: [summarization]
| 字段 | 必填 | 说明 | 默认值 |
|---|---|---|---|
id | 是 | Agent 唯一标识,全局不可重复 | - |
name | 是 | Agent 显示名称 | - |
model | 否 | 使用的 LLM 模型 | default-model |
runtime-mode | 否 | 执行模式:react / graph-parallel | react |
max-iterations | 否 | 最大 ReAct 循环次数 | 10 |
system-prompt | 是 | 系统提示词(支持多行) | - |
tools | 否 | 工具列表(匹配 ToolProvider 注册名) | [] |
interceptors | 否 | 拦截器列表 | [] |
hooks | 否 | Hook 列表 | [] |
AgentSpec 启动加载流程:
Application Startup
│
▼
┌─────────────────────────────────────────────────────┐
│ ① Startup Scan │
│ 扫描 classpath:/agents/*.agent.yml │
│ 扫描 config/agents/*.agent.yml │
└──────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────┐
│ ② Parse YAML │
│ SnakeYAML 解析 → AgentSpec POJO │
└──────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────┐
│ ③ Validate │
│ ├── Schema 校验(必填字段检查) │
│ ├── 引用校验(tools/interceptors 是否已注册) │
│ └── ID 冲突检查(是否与代码定义的 Agent 重复) │
└──────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────┐
│ ④ Create Bean │
│ 根据 Spec 动态创建 AgentBean │
│ 注入 model / tools / interceptors / hooks │
└──────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────┐
│ ⑤ Register │
│ 注册到 AgentRegistry,可通过 agentId 路由 │
└─────────────────────────────────────────────────────┘
基于 Java WatchService 监听 agent spec 目录的文件变更,实现运行时热重载:
热重载流程:
FileWatcher (WatchService)
│ 检测到 .agent.yml 文件变更
▼
┌─────────────────────────────────────────────────────┐
│ ① Detect Changes │
│ ENTRY_MODIFY / ENTRY_CREATE / ENTRY_DELETE │
└──────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────┐
│ ② Reload │
│ 重新解析变更的 YAML 文件 │
│ 校验新配置的合法性 │
└──────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────┐
│ ③ Recreate Agent Bean │
│ 旧 Bean 标记为 deprecated(引用计数 > 0 时延迟销毁)│
│ 新 Bean 注册到 AgentRegistry │
│ 新请求路由到新实例 │
└─────────────────────────────────────────────────────┘
| 配置来源 | 优先级 | 说明 |
|---|---|---|
| AgentSpec YAML | 最低 | 声明式 spec 文件中的配置 |
| agent-config.yml | 中 | 全局 Agent 配置文件 |
| Per-agent override | 高 | 针对特定 Agent 的覆盖配置 |
| 代码 Bean 定义 | 最高 | @Component 注解的 Java 代码定义 |
DataAgent 将用户的自然语言问题转换为 SQL 查询,自动执行并格式化返回结果。适用于业务数据查询、报表生成等场景。
| 防护层 | 机制 | 说明 |
|---|---|---|
| SQL 注入检测 | 语法分析 | 解析 SQL AST,检测异常结构 |
| 语句白名单 | 仅 SELECT | 禁止 UPDATE / DELETE / DROP / INSERT |
| 字段脱敏 | ACL 控制 | 敏感列(密码、身份证)自动隐藏 |
| 查询超时 | 30s 限制 | 防止慢查询拖垮数据库 |
| 结果集限制 | 最大 1000 行 | 强制 LIMIT,防止大数据量返回 |
| 只读连接 | Read Replica | 使用只读数据库副本 |
DataAgent NL2SQL 执行流程:
User: "上个月销售额最高的 5 个产品是什么?"
│
▼
┌─────────────────────────────────────────────────────┐
│ ① Intent Parse(意图解析) │
│ 识别:查询类型=聚合排序、时间=上月、实体=产品 │
│ 确认目标表:products, orders │
└─────────��────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────┐
│ ② SQL Generation(SQL 生成) │
│ LLM + Schema 上下文 → 生成 SQL │
│ SELECT p.name, SUM(o.amount) as total │
│ FROM orders o JOIN products p ON o.product_id=p.id│
│ WHERE o.created_at >= '2026-03-01' │
│ GROUP BY p.name ORDER BY total DESC LIMIT 5 │
└──────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────┐
│ ③ Safety Check(安全检查) │
│ ├── 白名单检查:仅 SELECT ✅ │
│ ├── 注入检测:无异常结构 ✅ │
│ ├── EXPLAIN 分析:无全表扫描 ✅ │
│ └── 字段 ACL:隐藏敏感列 ✅ │
└──────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────┐
│ ④ Sandbox Execute(沙箱执行) │
│ 只读连接 → PreparedStatement → 超时 30s │
│ 并发控制:最多 5 个同时查询 │
└──────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────┐
│ ⑤ Result Format(结果格式化) │
│ 表格渲染 + 自然语言总结 │
│ "上月销售额 TOP5:1. 产品A (¥128万)..." │
└─────────────────────────────────────────────────────┘
VoiceAgent 为 Agent 系统增加语音交互能力,通过 ASR(自动语音识别)和 TTS(文本转语音)实现全链路语音对话。
VoiceAgent 全链路流程:
🎤 用户语音输入
│
▼
┌─────────────────────────────────────────────────────┐
│ ① ASR(Automatic Speech Recognition) │
│ 支持:Whisper ASR │
│ 流式:音频分片 → 增量转写 │
│ 输出:"帮我查一下今天的天气" │
└──────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────┐
│ ② Text Processing │
│ ASR 文本 → 等同文本输入 │
│ 共享 ConversationHistory(与文本 Agent 同源) │
│ 进入标准 Agent 执行流程 │
└──────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────┐
│ ③ Agent Processing │
│ ReAct Loop / Graph 执行 │
│ 流式响应生成 │
└──────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────┐
│ ④ TTS(Text-to-Speech) │
│ 支持:MiniMax TTS │
│ 分句合成:第一句完成即播放 │
│ 流式输出:边生成边合成边播放 │
└──────────────────┬──────────────────────────────────┘
▼
🔊 语音播放给用户
| 阶段 | 流式策略 | 延迟优化 |
|---|---|---|
| ASR | 音频分片(chunk)→ 增量转写 | 不等完整语音,边听边转 |
| Agent | 首 Token 流式响应 | 不等完整生成,首 Token 即返回 |
| TTS | 分句合成 | 第一句准备好即播放,不等全文 |
| 传输 | WebSocket 长连接 | 避免 HTTP 握手开销 |
# application.yml — AgentSpec 相关配置
agent:
spec:
enabled: true
scan-paths:
- classpath:/agents/
- config/agents/
hot-reload:
enabled: true
watch-interval: 5s # 文件变更检测间隔
graceful-shutdown: true # 优雅切换(等待活跃对话结束)
# DataAgent 配置
agent:
data-agent:
enabled: true
datasource: read-replica # 使用只读数据库副本
query-timeout: 30s # 查询超时
max-rows: 1000 # 最大返回行数
max-concurrent: 5 # 最大并发查询数
allowed-statements: [SELECT] # 允许的 SQL 语句类型
redacted-columns: # 脱敏字段列表
- password
- id_card
- bank_card
# VoiceAgent 配置
agent:
voice-agent:
enabled: true
asr:
provider: whisper
language: zh
streaming: true
tts:
provider: minimax
voice-id: "female-yujie"
speed: 1.0
streaming: true
active_conversations > 0 时延迟销毁旧实例。具体流程:FileWatcher 检测到变更 → 创建新 Agent Bean → 新请求路由到新实例 → 旧实例引用计数归零后 GC 回收。类似于 Kubernetes 的滚动更新策略。
/api/admin/agents/spec-status 查看所有 Spec 的加载状态和错误详情。