Appearance
聊天机器人智能体工作流详解
本文档详细描述
AiChatbotAgent.createChatbotGraph()方法创建的标准聊天机器人工作流。
工作流概览
┌─────────────────────────────────────────────────────────────────────────┐
│ Chatbot Agent 工作流 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ START │
│ │ │
│ ▼ │
│ ┌──────────────────┐ │
│ │ load_config │ 加载Agent配置、LLM模型、子Agent、工具、知识库 │
│ └────────┬─────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────┐ │
│ │intent_recognition│ 分析用户意图,决定下一步动作 │
│ └────────┬─────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ routeByIntent│ │
│ └──────┬──────┘ │
│ │ │
│ ┌─────┼─────────────────┬──────────────────┐ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌───────┐┌─────────────┐┌─────────────┐ ┌────────┐ │
│ │ END ││sub_agent ││tool_ │ │response│ │
│ │ ││_execution ││execution │ │_gener- │ │
│ └───────┘└──────┬──────┘└──────┬──────┘ │ation │ │
│ │ │ └────┬───┘ │
│ └──────────────┴───────────────┤ │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ loop_check │ │
│ └───────┬───────┘ │
│ │ │
│ ┌─────┴─────┐ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────────┐ ┌────────┐ │
│ │intent_recognition│ │ END │ │
│ │ (继续循环) │ └────────┘ │
│ └──────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘节点详细说明
1. load_config - 加载配置节点
位置: AiChatbotAgent.loadAgentConfig()
功能: 从数据库加载Agent运行所需的所有配置信息。
┌─────────────────────────────────────────────────────────────────┐
│ 加载配置流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ State.agentId │
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ AiAgentMapper│ 加载 Agent 基础信息 │
│ │ .selectById │ (name, description, systemPrompt, etc.) │
│ └──────┬───────┘ │
│ │ │
│ ┌──────┴──────────────────┬──────────────────┬─────────────┐ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌─────────┐│
│ │ 加载LLM模型 │ │ 加载子Agent │ │ 加载工具 │ │加载知识库│
│ └──────────────┘ └──────────────┘ └──────────────┘ └─────────┘│
│ │
└─────────────────────────────────────────────────────────────────┘1.1 加载 LLM 模型配置
java
// 1. 查询 Agent-LLM 关联配置
AiAgentLlmModelEntity agentLlmModel = aiAgentLlmModelService.getByAgentId(agentId);
// 2. 查询 LLM 模型基本信息
AiLlmModelEntity llmModel = aiLlmModelManagementService.getById(agentLlmModel.getLlmModelId());
// 3. 构建模型配置 Map
Map<String, Object> llmModelConfig = buildLlmModelConfig(llmModel, agentLlmModel);LLM 模型配置结构:
| 字段 | 说明 | 来源优先级 |
|---|---|---|
modelId | 模型标识 | llmModel |
provider | 提供商 (openai, anthropic, etc.) | llmModel |
baseUrl | API 地址 | llmModel |
apiKey | API 密钥 | llmModel |
maxTokens | 最大 Token 数 | agentLlmModel > llmModel |
temperature | 温度参数 | agentLlmModel > llmModel |
topP | Top-P 参数 | agentLlmModel > llmModel |
supportsStreaming | 是否支持流式 | agentLlmModel > llmModel |
supportsFunctionCall | 是否支持函数调用 | agentLlmModel > llmModel |
1.2 加载子 Agent 列表
java
private List<Map<String, Object>> loadSubAgents(List<Long> subAgentIds) {
for (Long subAgentId : subAgentIds) {
AiAgentEntity subAgent = aiAgentMapper.selectById(subAgentId);
// 提取: id, name, description
}
}1.3 加载工具列表
java
private List<Map<String, Object>> loadTools(List<Long> toolIds) {
List<AiToolEntity> toolEntities = aiToolService.listByIds(toolIds);
// 提取: id, toolId, name, description, parameterSchema,
// responseSchema, serviceType, endpoint, timeoutMs
}1.4 加载知识库配置
java
private List<KnowledgeBaseDTO> loadDatasetsFromDatabase(Long agentId) {
// 1. 查询 Agent-Dataset 关联
List<AgentDatasetRelationDTO> relations =
agentDatasetRelationService.listEnabledByAgentId(agentId);
// 2. 加载每个知识库详情
for (AgentDatasetRelationDTO relation : relations) {
KbDatasetEntity dataset = kbDatasetService.getById(relation.getDatasetId());
// 3. 设置检索配置
if (relation.getUseCustomConfig() == 1) {
dto.setRetrievalSettings(relation.getCustomConfig());
} else {
RagConfig ragConfig = ragConfigService.getConfigByDatasetId(datasetId);
dto.setRetrievalSettings(ragConfigDTO);
}
}
}输出到 State:
agent_config: Agent 配置 MapllmModelConfig: LLM 模型配置datasetList: 知识库列表retrievalConfig: 检索配置摘要
2. intent_recognition - 意图识别节点
位置: IntentRecognitionNode.apply()
功能: 分析用户输入,识别意图,决定下一步动作。
┌─────────────────────────────────────────────────────────────────┐
│ 意图识别流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 用户输入 (userInput) │
│ │ │
│ ▼ │
│ ┌────────────────────┐ │
│ │ buildIntentPrompt │ 构建意图识别提示词 │
│ │ │ - 用户输入 │
│ │ │ - 可用子Agent列表 (含ID/名称/描述) │
│ │ │ - 可用工具列表 (含名称/描述/参数Schema) │
│ └──────────┬─────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────┐ │
│ │ 调用 LLM 分析 │ 使用配置的 LLM 模型 │
│ │ │ 支持流式/非流式两种模式 │
│ └──────────┬─────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────┐ │
│ │ parseIntentFromLlm │ 解析 JSON 响应 │
│ │ Response │ │
│ └──────────┬─────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────┐ │
│ │ IntentResult │ │
│ │ - intent: "用户意图描述" │ │
│ │ - confidence: 0.0-1.0 │ │
│ │ - nextAction: 下一步动作 │ │
│ │ - needRag: 是否需要RAG检索 │ │
│ │ - ragReason: RAG判断理由 │ │
│ │ - ragKeywords: 检索关键词 │ │
│ │ - selectedSubAgent: 选中的子Agent ID │ │
│ │ - selectedTool: 选中的工具名 │ │
│ │ - toolParams: 工具调用参数 │ │
│ └────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘LLM 返回的 JSON 格式:
json
{
"intent": "用户意图描述",
"confidence": 0.85,
"action": "continue_chat|call_sub_agent|call_tool|end",
"need_rag": true,
"rag_reason": "需要RAG的理由",
"rag_keywords": ["关键词1", "关键词2"],
"sub_agent_id": "如果需要调用子Agent,填写ID",
"tool_name": "如果需要调用工具,填写工具名",
"tool_params": {"参数名": "从用户输入中提取的参数值"}
}动作类型说明:
| Action | 说明 | 路由目标 |
|---|---|---|
continue_chat | 继续对话,使用 RAG 和 LLM 生成响应 | response_generation |
call_sub_agent | 需要调用子 Agent 处理 | sub_agent_execution |
call_tool | 需要调用工具执行任务 | tool_execution |
end | 结束对话 | END |
3. sub_agent_execution - 子 Agent 执行节点
位置: SubAgentExecutionNode.apply()
功能: 调用选中的子 Agent 执行任务。
java
Long subAgentId = state.selectedSubAgent();
String userInput = state.userInput();
// 使用 AgentExecutionService 执行子 Agent
String result = agentExecutionService.executeAgent(subAgentId, userInput);
// 结果存入 State
updates.put(ChatbotAgentState.SUB_AGENT_RESULT_KEY, result);4. tool_execution - 工具执行节点
位置: ToolExecutionNode.apply()
功能: 调用选中的工具执行任务。
┌─────────────────────────────────────────────────────────────────┐
│ 工具执行流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ selectedTool + toolParams │
│ │ │
│ ▼ │
│ ┌────────────────────┐ │
│ │ aiToolService │ 根据工具名获取工具配置 │
│ │ .getByToolName() │ │
│ └──────────┬─────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────┐ │
│ │ executorFactory │ 根据 serviceType 获取执行器 │
│ │ .getExecutor() │ (HTTP/MCP/Function 等) │
│ └──────────┬─────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────┐ │
│ │ executor.execute() │ 执行工具,返回结果 │
│ └──────────┬─────────┘ │
│ │ │
│ ▼ │
│ 存入 State: tool_result │
│ │
└─────────────────────────────────────────────────────────────────┘5. response_generation - 响应生成节点
位置: ResponseGenerationNode.apply()
功能: 基于所有上下文生成最终响应。
┌─────────────────────────────────────────────────────────────────┐
│ 响应生成流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ 输入: │ │
│ │ - userInput (用户问题) │ │
│ │ - agentConfig (系统提示等) │ │
│ │ - subAgentResult (子Agent结果) │ │
│ │ - toolResult (工具结果) │ │
│ │ - datasetList (知识库列表) │ │
│ │ - needRag (是否需要RAG) │ │
│ └──────────────────┬──────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ needRag == true?│ │
│ └────────┬────────┘ │
│ │ │
│ ┌────────────┴────────────┐ │
│ │ Yes │ No │
│ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ RAG 检索 │ │ 跳过 RAG │ │
│ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │
│ └──────────┬───────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────┐ │
│ │ buildFullPrompt() │ │
│ │ 组装完整 Prompt: │ │
│ │ 1. 系统提示 (systemPrompt) │ │
│ │ 2. 参考文档 (RAG 检索结果) │ │
│ │ 3. 子Agent执行结果 │ │
│ │ 4. 工具执行结果 │ │
│ │ 5. 用户问题 │ │
│ │ 6. 生成指令 │ │
│ └──────────────────┬──────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────┐ │
│ │ LLM 生成响应 │ │
│ │ - 流式模式: generateResponseWithStreaming│ │
│ │ - 非流式模式: chatModel.chat() │ │
│ └──────────────────┬──────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────┐ │
│ │ 添加引用来源元数据 │ │
│ │ formatSourcesMetadata() │ │
│ │ 格式: ```reference ... ``` │ │
│ └──────────────────┬──────────────────────┘ │
│ │ │
│ ▼ │
│ 存入 State: final_response │
│ │
└─────────────────────────────────────────────────────────────────┘RAG 检索流程
java
for (KnowledgeBaseDTO dataset : datasetList) {
// 1. 转换检索配置
RagConfig ragConfig = convertToRagConfig(retrievalSettings);
// 2. 使用 RagExecutor 执行 6 阶段 RAG
// 自动完成: 查询转换、多检索器并行、质量评估、自纠正、结果聚合
Query query = Query.from(userInput);
List<Content> contents = ragExecutor.executeRetrieval(query, ragConfig);
// 3. 贪心策略: 找到结果后停止
if (!contents.isEmpty()) {
retrievedContents.addAll(contents);
break;
}
}6. loop_check - 循环检查节点
位置: AiChatbotAgent.checkLoop()
功能: 检查是否继续循环对话。
java
int loopCount = state.loopCount();
int maxLoops = state.maxLoops();
// 判断条件: 未达最大次数 且 无错误
boolean shouldContinue = loopCount < maxLoops && state.error().isEmpty();
updates.put(ChatbotAgentState.SHOULD_CONTINUE_KEY, shouldContinue);循环控制:
shouldContinue = true→ 返回intent_recognition节点shouldContinue = false→ 进入END
状态数据流
关键 State Key
| Key | 类型 | 说明 |
|---|---|---|
agent_id | Long | Agent ID |
agent_config | Map | Agent 配置 |
llmModelConfig | Map | LLM 模型配置 |
datasetList | List | 知识库列表 |
user_input | String | 用户输入 |
user_intent | String | 识别的用户意图 |
next_action | String | 下一步动作 |
need_rag | Boolean | 是否需要 RAG |
selected_sub_agent | Long | 选中的子 Agent ID |
selected_tool | String | 选中的工具名 |
tool_params | Map | 工具调用参数 |
sub_agent_result | String | 子 Agent 执行结果 |
tool_result | String | 工具执行结果 |
final_response | String | 最终响应 |
loop_count | Integer | 当前循环次数 |
should_continue | Boolean | 是否继续循环 |
流式处理
StreamHandler 接口
工作流支持流式推送,通过 StreamContext.getHandler() 获取处理器。
java
// 节点开始
handler.onNodeStart("intent_recognition");
// 思维链阶段开始
handler.onThinkingStageStart("intent_recognition", "意图识别");
// 推送思考内容
handler.onThinkingContent("intent_recognition", "正在分析用户意图...");
// RAG 开始/完成
handler.onRagStart("知识库名称");
handler.onRagComplete("知识库名称", 5);
// 推送 Token (响应生成时)
handler.onToken("部分响应文本");
// 阶段结束
handler.onThinkingStageEnd("intent_recognition");
// 节点完成
handler.onNodeComplete("intent_recognition", state);
// 最终完成
handler.onComplete(finalResponse, sessionId);相关代码文件
| 文件 | 说明 |
|---|---|
AiChatbotAgent.java | 主工作流定义 |
ChatbotAgentState.java | State 定义 |
IntentRecognitionNode.java | 意图识别节点 |
SubAgentExecutionNode.java | 子 Agent 执行节点 |
ToolExecutionNode.java | 工具执行节点 |
ResponseGenerationNode.java | 响应生成节点 |
StreamHandler.java | 流式处理接口 |
StreamContext.java | 流式上下文管理 |