AI Coding:Gaia支持AI Agent自动化编排工作流
项目信息
gaia-workflow-engine:https://github.com/boommanpro/gaia-workflow-engine
技术选型 & 技术架构
为什么选prompt + 提示词工程 + 向量 + 图 :综合全部技术,手搓在非SOTA模型汇总,Agent表现怎么样,如何优化,还有一个原因就是确实在开源场景没有可以直接使用的Agent Managed + Skill的解决方案。
结论:效果还不错,使用ds flash 可以一把梭10多个节点的创建、测试、全流程闭环。
Gaia AI Agent 能力与架构
一个基于 LLM Function Calling 的工作流智能体,通过自然语言对话实现 工作流创建、节点编排、模板管理与调试运行。复合工具设计 + RAG 增强 + 上下文压缩 + 可观测调试面板,构建完整的 Agent 闭环体验。
产品概览与核心能力
Gaia AI Agent 定位为「工作流引擎的 AI Copilot」。用户通过对话即可完成 从 0 到 1 的工作流搭建,AI 自动规划步骤、创建节点、测试运行、迭代调优, 全过程可观察、可回溯、可编辑。
🧩 八大核心能力模块
AI 智能对话
自然语言驱动的交互方式,支持多轮上下文与 SSE 流式输出。
- SSE 流式 token 响应
- ::options 选项化交互
- 自动生成会话标题
- Markdown 渲染输出
画布节点编排
在工作流画布上增删改节点、连线、自动布局、运行测试。
- 12 种节点类型全覆盖
- 占位符 $0/$1 引用
- 自动布局优化
- 单节点 / 全工作流测试
createPlan 分步执行
复杂任务先制定计划,再逐步执行,每步可重试可调整。
- LLM 节点创建后必测
- 失败回滚 updateNode
- PlanCard 可视化
- 历史刷新不丢失
RAG 知识增强
向量 + 关键词双层检索,节点知识库完整注入,图谱补充。
- Embedding 余弦相似度
- 关键词 LIKE 降级兜底
- 节点知识库 (40条) 全量注入
- 知识图谱子图检索
复合工具系统
6 大复合工具,20+ 子动作,DB-first 热更新定义。
- navigate / query / manage
- canvas / createPlan / executeStep
- 三级权限 (会话→全局→默认)
- 工具 schema 内联节点提示
会话与历史管理
多会话独立管理,调试信息与会话绑定,DB 持久化。
- 首次打开自动建会话
- 标题双击编辑 / 自动生成
- 会话详情回溯导出 cURL
- 调试信息 localStorage + DB 双层
调试观测面板
完整记录 LLM 输入输出,上下文加载细节,点击跳转。
- context_loaded 全字段
- debug_request 完整 messages+tools
- Raw 面板自动换行
- 消息可点击跳转条目
配置管理中心
模型/提示词/知识库/工具/权限/图谱 6 大 Tab 在线编辑。
- LLM 配置即时生效
- Embedding 独立 + 降级
- AI 辅助生成内容
- 工具定义 DB 热刷新
🔁 业务主流程:用户对话 → 工作流落地
从用户发出一句自然语言,到最终一个可运行工作流呈现在画布上的完整业务链路。
🎯 支持的 12 种画布节点
| 节点类型 | 图标 | 核心功能 | 关键字段 (data 简写) |
|---|---|---|---|
start | 🟢 | 工作流入口,定义工作流输入 schema | outputs 定义输出字段 (JSON Schema) |
end | 🔴 | 工作流出口,汇聚最终结果 | inputsValues.result 使用 ref 引用上游 |
llm | 🤖 | 调用大模型完成生成/分类/总结任务 | prompt, systemPrompt, temperature, modelName, apiKey, apiHost |
code | 💻 | 执行 Java / JS 代码,处理数据变换 | script.{language, content}, outputs |
http | 🌐 | 发起 HTTP 请求调用外部 API | method, url, headers, body, timeout |
condition | 🔀 | 单条件 true/false 两分支路由 | conditions[].{left{ref}, operator, value} |
branches | 🌳 | 多分支条件判断,N 条输出端口 | branches[].{conditions, targetPort} |
loop | 🔁 | 对数组进行循环迭代处理 | loopFor{ref}, loopOutputs |
variable | 📦 | 赋值 / 变换中间变量 | inputsValues, outputs |
string-format | 🔤 | SpEL 表达式字符串格式化 | script.content SpEL: 'Result: ' + #start.text |
assignee | 👤 | 标记节点负责人 (组织协作) | owner, dueDate |
comment | 💬 | 画布注释,不参与执行 | text, color |
🛠️ 6 大复合工具与 20+ 子动作矩阵
| 复合工具 | 子动作 (action) | 默认策略 | 工具组 | 功能说明 |
|---|---|---|---|---|
navigate |
home · admin · releases · editor · templateEditor |
always | navigation | 路由跳转,携带 workflowCode / templateCode |
query |
workflows · templates · logs · workflowDetail · nodeDetail · availableVariables |
always | query | 只读查询,返回资源列表或详情 |
manage |
createWorkflow · createTemplate · saveWorkflow · deleteWorkflow |
always | write | 工作流 / 模板的增删改写操作 |
canvas |
addNode · updateNode · deleteNode · connect · disconnect · autoLayout · runWorkflow · runNode |
always | canvas | 画布上的节点、连线、测试操作 |
createPlan |
— (steps 数组参数) | always | plan | 制定多步执行计划,返回 steps 列表不执行 |
executeStep |
— (stepIndex 数字参数) | always | plan | 执行 createPlan 中的第 N 步,根据结果决定下一步 |
⚙️ Agent 配置中心 · 6 大管理模块
LLM 模型配置
在线编辑,保存后即时生效(无缓存)
- apiHost / apiKey
- model / temperature
- maxTokens / contextWindow
Embedding 配置
独立于 LLM,留空自动复用 LLM 配置
- 启用 / 禁用开关
- 独立 apiHost / apiKey / model
- 不支持时自动关键词降级
提示词 & 知识库
系统提示词 DB 存储,覆盖 classpath 默认
- 提示词:新建 / 重命名 / 删除
- 知识库分块 CRUD
- AI 辅助生成内容按钮
工具定义管理
DB-first 加载,修改后 refresh() 热更新
- 工具名 / 描述 / 参数 schema
- 默认权限策略
- pageContexts 页面过滤
权限策略设置
三级权限层级:会话级 > 全局 > 默认
- always 自动执行
- confirm 每次确认
- forbid 禁止执行
知识图谱
节点 + 边 的概念图,用于检索上下文补充
- 图谱节点 CRUD (title/type/properties)
- 图谱边 CRUD (source/type/target)
- 按关键词检索邻居子图
技术栈与系统架构
前后端分离 + SSE 流式通信 + DB-first 配置热加载。后端 Spring Boot (Java) 负责 LLM 编排、RAG 检索、工具注册与持久化;前端 React 18 + Semi UI 负责对话面板、 画布操作、调试面板与配置管理。
🏗️ 整体技术栈
☕ 后端 (Spring Boot)
- Java 17 + Spring Boot 3.x
- MyBatis-Plus + MySQL (agent 系列表)
- HttpURLConnection 原生调用 LLM (零依赖)
- SseEmitter 流式推送
- Hutool JSON (JSONObject/JSONArray)
- Executors.newCachedThreadPool 异步
⚛️ 前端 (React)
- React 18 + TypeScript
- React Router 6 + Context 状态管理
- Semi Design (字节跳动 UI 库)
- Rsbuild 构建 + Tailwind CSS
- nanoid 生成唯一 ID
- React Flow (画布底层引擎)
📐 系统分层架构图
🔍 AgentChatService · 对话主流程详解
📥 chat() 入口方法 (15 步)
-
保存用户消息
saveMessage() 写入 agent_message,支持多模态 images 数组
-
异步生成会话标题
首条消息触发 tryAutoGenerateTitle(),LLM 压缩为 ≤15 字
-
加载模型配置
modelConfigService.getLlmConfig(),DB 优先 yml 兜底
-
加载历史消息
loadMessages(),最近 200 条 + user 边界截断防悬空 tool
-
系统提示词装配
DB agent_config → classpath prompt-zh.md,追加 pageContext
-
RAG 知识库检索
buildRagContext():向量余弦相似度 TOP3 → 降级关键词 LIKE
-
节点知识库注入
buildNodeKnowledgeContext(),agent_config 40 条 node_knowledge 按 locale 过滤
-
知识图谱检索
buildGraphContext(),按关键词匹配节点 + 邻居边
-
模板参考加载
buildTemplateContext(),TOP20 模板节点数与类型摘要
-
工具 schema 加载
toolRegistry.getToolsSchema(),6 个复合工具完整定义
-
Token 估算 + 压缩
estimateMessagesTokens(),≥90% 强制 compactHistoryInline()
-
发送 context_loaded 事件
所有上下文统计 + ragContext/nodeKbContext 原文
-
发送 debug_request 事件
完整 messages 数组 + toolsCount + toolsSchema 全量
-
SSE 调用 LLM
逐 token 推送,tool_calls 按 index 聚合 (TreeMap)
-
保存 assistant + 执行工具
检测 ::options 跳过工具;handleToolCalls() 查三级权限推送事件
🔁 toolResult() 回灌流程
-
批量保存 tool 消息
每个 tool 结果写入 agent_message (role=tool, toolCallId)
-
发送 debug_tool_result 事件
调试面板可查看每个工具实际执行结果
-
再次 streamLlm()
新一轮 LLM 推理,tool 结果作为对话历史继续
💾 compact() 上下文压缩流程
-
取 contextWindow 阈值
从模型配置读取,默认 32768
-
估算全部历史 token
estimateTokens(),中文场景按 /2.5 chars
-
低于阈值直接返回
消息 <6 条 或 占比 <50% 不压缩
-
对半切分
前半段送去 LLM 摘要,后半段原样保留
-
LLM 摘要
非流式调用,temperature=0.3,max_tokens=500
-
删除旧消息 + 插入摘要
role=system,内容前缀 "对话历史摘要:"
🧠 核心算法 · RAG 检索与 Embedding 降级
📐 余弦相似度公式
cos(θ) = Σ(Aᵢ × Bᵢ) / √(ΣAᵢ²) × √(ΣBᵢ²) 全量分块逐一计算, 降序排序取 TOP 3。
🔤 关键词分词规则
正则:[\s,,。.;;、??!!]+
过滤:长度 < 2 的词丢弃
策略:每词 LIKE LIMIT 5 → 去重
→ 满 3 条提前 break
🧩 Token 估算公式
messages 中 role + content 拼接后 chars.length / 2.5 (中英混合场景更准确) 占比:estimated / contextWindow ≥80% 预警 · ≥90% 强制压缩
🧩 关键机制 · 占位符解析 ($0/$1 + ref)
| 占位符类型 | 示例 | 解析规则与适用场景 |
|---|---|---|
| $N 节点索引 | $0 · $1 |
引用 createPlan 中第 N 个 canvas(addNode) 返回的 nodeId。适用字段:nodeId、from、to、afterNodeId。非标准 nodeId 自动替换为最近一次创建的 nodeId(兜底)。 |
| ref 显式格式 | {"type":"ref","content":["$0","result"]} |
end / variable / loop 节点 inputsValues 中引用上游节点输出字段。递归解析 $0 → 真实 nodeId。 |
| ref 简写格式 | {"ref":"start.text"} |
condition 节点 conditions[].left 简写,系统自动 normalize 为显式 ref 格式。同样支持 $N 占位符。 |
| 模板内联 | "分析 {{ start.text }}" |
llm 节点 prompt / systemPrompt 的 Vue 模板语法引用上游输出。直接嵌入字符串,无需 JSON 结构。 |
| SpEL 表达式 | "'结果:' + #start_0.result" |
string-format 节点 script.content,Spring Expression Language,引用节点名为变量名。 |
🛡️ 容错机制 · tool_calls JSON 补全
场景
小模型(qwen3-4b、deepseek 等)在深层嵌套的 createPlan steps 参数中,常输出缺失右花括号的 JSON,导致 parseObj 抛异常。
正常:{"steps":[{"a":1},{"b":2}]}
异常:{"steps":[{"a":1},{"b":2} ← 少 2 个 }
tryFixAndParse() 策略
模型无关的通用补全算法:
1. 遍历字符串,跳过字符串内的花括号
(处理 \" 和 \\ 转义)
2. 统计 { 与 } 的差值 diff = open - close
3. diff > 0 时尾部追加 diff 个 }
4. 仍失败 → 包装为 {"raw": argsStr} 返回
🗄️ 数据库 · Agent 系列 12 张表
| 表名 | 关键字段 | 用途说明 |
|---|---|---|
agent_session |
session_key, title, debug_data | 会话记录,title 自动生成/可编辑,debug_data 存储调试条目 JSON 数组持久化 |
agent_message |
role, content, tool_calls, tool_call_id, images, page_context | 对话消息表 (user/assistant/tool/system),tool_calls 存完整 JSON,支持多模态 |
agent_config |
config_type, config_key, content, config_data | KV 配置表:llm_config / embedding_config (config_data JSON) + system_prompt / node_knowledge (content 文本) |
agent_tool_definition |
tool_name, tool_group, description, parameters, default_policy, page_contexts, enabled, sort_order | 工具注册定义,6 条记录对应 6 个复合工具,DB-first 热更新 |
agent_knowledge_chunk |
title, content, language, embedding, keywords | RAG 知识库分块,embedding 存向量 JSON (可为空即走关键词降级),language 区分 zh/en |
agent_graph_node |
node_key, title, node_type, properties | 知识图谱节点 (概念/实体),properties JSON 存 description 等扩展属性 |
agent_graph_edge |
source_key, edge_type, target_key | 知识图谱有向边,构成节点间的语义关系 (如 "包含" "属于" "实现") |
agent_permission |
session_key, action, policy | 会话级工具权限,单会话内对某个 action 的个性化策略 |
agent_global_permission |
action, policy | 全局工具权限,跨会话对 action 的默认策略(优先级高于工具内 defaultPolicy) |
agent_config_history |
config_key, content, config_data, version, operator | 配置变更历史版本,支持提示词/模型配置的版本回滚 |
gaia_workflow_template |
template_code, template_name, template_desc, template_data | 工作流模板表,createWorkflow 可引用,对话中作为模板参考注入系统提示词 |
gaia_workflow |
workflow_code, name, description, workflow_data, status | 实际工作流实例表,canvas 操作 saveWorkflow 持久化到该表 |
⚛️ 前端 · 核心组件与数据流
🎯 核心文件一览
- AgentContext.tsx — 全局 Provider,状态管理核心
- AgentDockPanel.tsx — 浮动面板 UI (含输入框/顶栏/侧栏)
- AgentDock.tsx — Dock 外层容器,宽度动画 + FAB 按钮
- MessageList.tsx — 消息列表 (MessageItem/GroupedToolCard/OptionsCard)
- SessionList.tsx — 会话侧栏列表 (双击重命名)
- DebugPanel.tsx — 调试抽屉 + Raw 全屏面板
- PlanCard.tsx — createPlan 步骤卡片 (进度状态切换)
- sse-client.ts — SSE 流式封装 (ReadableStream 解析)
- tools.ts — 前端工具执行器 (6 工具分发改路由)
- api.ts — REST API 封装 (会话/配置/调试数据)
- types.ts — 完整类型定义 (DisplayMessage/ToolCallEvent/PlanStep)
📊 AgentContext 状态字段
sessions: AgentSession[]会话列表currentSessionKey: string当前会话messages: DisplayMessage[]消息展示数组permissions: Record<action, policy>三级权限缓存streaming / queueLength流式状态 + 排队数pendingConfirm: ToolCallEvent待确认工具弹窗tokenUsage.{estimated, limit}Token 用量条debugEntries[] / debugPanelOpen调试条目与面板开关focusDebugEntryId点击消息跳转聚焦activePlan: ActivePlan | null当前 createPlan 计划toolExecutor画布工具执行器回调注入
💾 调试信息持久化 · localStorage + DB 双层
📡 SSE 事件类型清单 (后端 → 前端)
| 事件名 event: | 触发时机 | data 主要字段 |
|---|---|---|
token |
LLM 每个 chunk | {content} 单个 token 文本,前端拼接展示流式打字效果 |
context_loaded |
调用 LLM 前 | model, apiHost, temperature, maxTokens, contextWindow, historyMessages, systemPromptChars, ragContext, nodeKbContext, graphContext, ragDegraded, toolsCount, estimatedTokens, tokenPercentage |
debug_request |
请求 LLM 前 | messages[] (全量), model, temperature, maxTokens, toolsCount, tools[] (完整schema), timestamp |
debug_response |
LLM 响应完成 | content, toolCalls[] (完整), toolCallsCount, durationMs |
debug_tool_result |
toolResult 入库后 | results[{toolCallId, rejected, result}], count — 每个工具实际执行结果 |
tool_call |
assistant 请求工具时 | id, action, args{}, policy — 前端据此弹窗 confirm 或 always 自动执行 |
token_warning |
80% ≤ 用量 < 90% | percentage, estimated, limit, message — 前端显示用量条黄色预警 |
error |
捕获异常时 | message — 前端 Toast 显示错误 |
done |
全部处理完成 | {} 或压缩结果 — 前端关闭 streaming 状态 |
初始化与配置部署
启动即用的 DB-first 自动建种机制,无需手动导入数据。修改配置通过管理后台在线编辑, 无需重启服务。
🚀 启动初始化流程
-
Spring Boot 启动
schema.sql 建表 (agent_ 系列 12 张)
-
AgentToolRegistry @PostConstruct
读取 classpath prompt-zh/en.md → loadFromDatabase(true)
-
检测旧工具迁移
如果存在 21 个独立旧工具名 → 全部删除
-
DB 空表建种
agent_tool_definition 插入 6 条复合工具硬编码 schema
-
AgentDataSeeder 再次 ensureSeeded
SQL 初始化后二次保障建种成功 (PostConstruct 时机可能过早)
-
系统提示词 DB 覆盖
若 agent_config 有 system_prompt.default → 覆盖 classpath 默认
🔧 配置层级与热更新
| 配置项 | 层级 | 热更新 |
|---|---|---|
| LLM 参数 | DB agent_config → application.yml | ✅ 每次 getLlmConfig() 查 DB |
| Embedding 参数 | DB → LLM 复用 → yml | ✅ 每次 embed() 查配置 |
| 系统提示词 | DB → classpath md | ✅ 每次 getSystemPrompt() 读 DB |
| 工具定义 | DB → 硬编码兜底 | ⚠️ 需调用 refresh() 接口 |
| 全局权限 | DB global → 工具默认 | ✅ 每次 getPolicy() 查 |
| 会话级权限 | 会话 DB (最高) | ✅ 每次查 |
📄 关键代码文件引用
后端核心:
· AgentChatService.java — 对话编排主流程
· AgentToolRegistry.java — 工具注册与建种
· AgentModelConfigService.java — 三级配置兜底
· EmbeddingService.java — 向量化 + 降级触发
· AgentDataSeeder.java — 启动建种保障
前端核心:
· agent/AgentContext.tsx — 全局状态与会话切换
· agent/AgentDockPanel.tsx — 对话面板 UI
· agent/DebugPanel.tsx — 调试面板
· agent/tools.ts — 前端工具执行器
· pages/admin/AgentConfigManagement.tsx — 配置中心