|
@@ -10,12 +10,15 @@ import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.ai.chat.memory.ChatMemory;
|
|
|
import org.springframework.ai.chat.messages.AssistantMessage;
|
|
|
import org.springframework.ai.chat.messages.Message;
|
|
|
+import org.springframework.ai.chat.messages.ToolResponseMessage;
|
|
|
import org.springframework.ai.chat.model.ChatResponse;
|
|
|
import org.springframework.ai.chat.prompt.ChatOptions;
|
|
|
import org.springframework.ai.chat.prompt.Prompt;
|
|
|
import org.springframework.ai.chat.prompt.PromptTemplate;
|
|
|
import org.springframework.ai.chat.prompt.SystemPromptTemplate;
|
|
|
import org.springframework.ai.model.tool.ToolCallingChatOptions;
|
|
|
+import org.springframework.ai.model.tool.ToolCallingManager;
|
|
|
+import org.springframework.ai.model.tool.ToolExecutionResult;
|
|
|
import org.springframework.ai.tool.ToolCallback;
|
|
|
import org.springframework.ai.tool.metadata.ToolMetadata;
|
|
|
|
|
@@ -62,18 +65,20 @@ public class PavisAgent extends ReActAgent {
|
|
|
* 用于获取所有工具集
|
|
|
*/
|
|
|
private ToolService toolService;
|
|
|
- ;
|
|
|
+
|
|
|
+ private final ToolCallingManager toolCallingManager;
|
|
|
|
|
|
/**
|
|
|
* 构造函数
|
|
|
*
|
|
|
* @param llmService LLM服务实例,用于处理自然语言交互
|
|
|
*/
|
|
|
- public PavisAgent(LlmService llmService, Long planId, AgentResp agent, ToolService toolService) {
|
|
|
+ public PavisAgent(LlmService llmService, Long planId, AgentResp agent, ToolService toolService, ToolCallingManager toolCallingManager) {
|
|
|
super(llmService);
|
|
|
this.planId = planId;
|
|
|
this.agent = agent;
|
|
|
this.toolService = toolService;
|
|
|
+ this.toolCallingManager = toolCallingManager;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -82,24 +87,32 @@ public class PavisAgent extends ReActAgent {
|
|
|
try {
|
|
|
List<Message> messages = new ArrayList<>();
|
|
|
addThinkPrompt(messages);
|
|
|
- log.info("start thinking....");
|
|
|
- ChatOptions chatOptions = ToolCallingChatOptions.builder().internalToolExecutionEnabled(false).build();
|
|
|
+
|
|
|
Message nextStepMessage = getNextStepWithEnvMessage();
|
|
|
messages.add(nextStepMessage);
|
|
|
reActRecord.startThinking(messages.toString());
|
|
|
|
|
|
log.debug("Messages prepared for the prompt: {}", messages);
|
|
|
|
|
|
+ ChatOptions chatOptions = ToolCallingChatOptions
|
|
|
+ .builder()
|
|
|
+ .toolCallbacks(getToolCallList())
|
|
|
+ .internalToolExecutionEnabled(false)
|
|
|
+ .build();
|
|
|
+
|
|
|
userPrompt = new Prompt(messages, chatOptions);
|
|
|
|
|
|
+ log.info("prompt:{}", userPrompt.getContents());
|
|
|
+
|
|
|
response = llmService.getAgentChatClient(String.valueOf(planId))
|
|
|
.getChatClient()
|
|
|
.prompt(userPrompt)
|
|
|
.advisors(memoryAdvisor -> memoryAdvisor.param(ChatMemory.CONVERSATION_ID, String.valueOf(planId)))
|
|
|
- .toolCallbacks(getToolCallList())
|
|
|
.call()
|
|
|
.chatResponse();
|
|
|
|
|
|
+ log.info("end calling...");
|
|
|
+
|
|
|
String responseByLLm = response.getResult().getOutput().getText();
|
|
|
if (responseByLLm != null && !responseByLLm.isEmpty()) {
|
|
|
log.info(String.format("💬 %s's response: %s", getName(), responseByLLm));
|
|
@@ -110,19 +123,38 @@ public class PavisAgent extends ReActAgent {
|
|
|
log.info(String.format("✨ %s's thoughts: %s", getName(), responseByLLm));
|
|
|
log.info(String.format("🛠️ %s selected %d tools to use", getName(), toolCalls.size()));
|
|
|
|
|
|
+ // 新增逻辑:如果有 tool calls,构造 tool responses 并添加到 messages 中
|
|
|
if (!toolCalls.isEmpty()) {
|
|
|
- log.info(String.format("🧰 Tools being prepared: %s",
|
|
|
- toolCalls.stream().map(AssistantMessage.ToolCall::name).collect(Collectors.toList())));
|
|
|
- reActRecord.setExecutionNeeded(true);
|
|
|
-
|
|
|
- // 修复点:处理所有工具调用,不只是第一个
|
|
|
- List<ReActToolExecute> toolExecutes = new ArrayList<>();
|
|
|
- for (AssistantMessage.ToolCall toolCall : toolCalls) {
|
|
|
- toolExecutes.add(new ReActToolExecute(toolCall.name(), toolCall.arguments()));
|
|
|
+
|
|
|
+ ToolExecutionResult toolExecutionResult = toolCallingManager.executeToolCalls(userPrompt, response);
|
|
|
+
|
|
|
+ ToolResponseMessage toolResponseMessage = (ToolResponseMessage) toolExecutionResult.conversationHistory()
|
|
|
+ .get(toolExecutionResult.conversationHistory().size() - 1);
|
|
|
+
|
|
|
+ log.info("re-prompt:{}", userPrompt.getContents());
|
|
|
+
|
|
|
+ llmService.getAgentChatClient(String.valueOf(planId)).getMemory().add(String.valueOf(planId), toolResponseMessage);
|
|
|
+ String llmCallResponse = toolResponseMessage.getResponses().get(0).responseData();
|
|
|
+
|
|
|
+ log.info("end re-calling...");
|
|
|
+
|
|
|
+ if (!llmCallResponse.isEmpty()) {
|
|
|
+ log.info(String.format("💬 %s's response after tool responses: %s", getName(), llmCallResponse));
|
|
|
+ log.info(String.format("🧰 Tools being prepared: %s",
|
|
|
+ toolCalls.stream().map(AssistantMessage.ToolCall::name).collect(Collectors.toList())));
|
|
|
+
|
|
|
+ reActRecord.setExecutionNeeded(true);
|
|
|
+
|
|
|
+ // 修复点:处理所有工具调用,不只是第一个
|
|
|
+ List<ReActToolExecute> toolExecutes = new ArrayList<>();
|
|
|
+ for (AssistantMessage.ToolCall toolCall : toolCalls) {
|
|
|
+ toolExecutes.add(new ReActToolExecute(toolCall.name(), toolCall.arguments()));
|
|
|
+ }
|
|
|
+ reActRecord.setToolExecutes(toolExecutes);
|
|
|
+
|
|
|
+ responseByLLm = String.format("Preparing to execute %d tools", toolCalls.size());
|
|
|
}
|
|
|
- reActRecord.setToolExecutes(toolExecutes);
|
|
|
|
|
|
- responseByLLm = String.format("Preparing to execute %d tools", toolCalls.size());
|
|
|
}
|
|
|
reActRecord.setStatus("SUCCESS");
|
|
|
reActRecord.finishThinking(responseByLLm != null ? responseByLLm : "No response from LLM");
|