工作流程
graph TD
Start[开始
接收任务指令] --> Perception[感知
Perception
获取信息与状态] Perception --> Thinking[思考与规划
Thinking
分析并制定策略] Thinking --> Action[行动
Action
调用工具执行] Action --> Memory[记忆
Memory
存储经验与状态] Memory --> Decision{任务完成?} Decision -- 否 --> Thinking Decision -- 是 --> End[结束
交付最终结果] style Start fill:#e1f5ff style End fill:#e8f5e9 style Thinking fill:#fff3e0 style Action fill:#f3e5f5
接收任务指令] --> Perception[感知
Perception
获取信息与状态] Perception --> Thinking[思考与规划
Thinking
分析并制定策略] Thinking --> Action[行动
Action
调用工具执行] Action --> Memory[记忆
Memory
存储经验与状态] Memory --> Decision{任务完成?} Decision -- 否 --> Thinking Decision -- 是 --> End[结束
交付最终结果] style Start fill:#e1f5ff style End fill:#e8f5e9 style Thinking fill:#fff3e0 style Action fill:#f3e5f5
流程说明:
这个图展示了AI Agent的循环工作模式:
- 感知:接收你的指令或观察环境
- 思考:分析情况,规划下一步行动
- 行动:使用工具(搜索、计算、控制设备等)执行具体操作
- 记忆:记录已执行的操作和结果,保持上下文连贯
- 判断:检查是否达到目标,如果没有则回到"思考"阶段继续循环,直到完成任务
简单案例
AI Agent收到指令后,会进行思考与规划,看看是否需要调用工具。
java
public static final String BASE_URL = "https://api.xiaomimimo.com/v1";
public static final String LLM_NAME = "mimo-v2-flash";
public static void main(String[] args) {
OpenAIClient apiClient = OpenAIOkHttpClient.builder()
.apiKey(API_KEY)
.baseUrl(BASE_URL)
.build();
String userMessage = """
##角色定义
你是一个强大的AI助手,通过思考和使用工具来解决用户的问题
## 任务
你的任务是尽可能回答以下问题。你可以使用以下工具。
## 工具
工具1:
名称:weatherTool
说明:通过传入城市名称返回天气
参数:json
参数含义:city(城市名称)
## 问题
南昌天气怎么样?
## 输出
如果需要使用工具,输出你应该调用的工具名称,及参数值;如果不需要,则正常回答
""";
ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
.addUserMessage(userMessage)
.model(LLM_NAME)
.build();
ChatCompletion chatCompletion = apiClient.chat().completions().create(params);
String output = chatCompletion.choices().get(0).message().content().get();
System.out.println(output);
Map outPutJson = JSON.parseObject(
output.replaceAll("```", "")
.replaceAll("json", "")
, Map.class);
System.out.println(outPutJson);
String weather = weatherTool((Map<String, String>) outPutJson.get("parameters"));
System.out.println(weather);
}
public static String weatherTool(Map<String, String> params) {
Map<String, String> weatherMap = Map.of("南昌", "晴天", "九江", "小雨");
return Optional.ofNullable(weatherMap.get(params.get("city"))).orElse("没有这个城市的天气信息");
}
执行上面代码后,AI会输出以下内容。说明AI可以理解自然语言,可以对指令进行理解并思考,知道调用什么工具。
json
{
"tool": "weatherTool",
"parameters": {
"city": "南昌"
}
}
{parameters={"city":"南昌"}, tool=weatherTool}
晴天
复杂案例
借用spring ai alibaba文档介绍,模拟实现
ReAct(Reasoning + Acting)是一种将推理和行动相结合的 Agent 范式。在这个范式中,Agent 会:
- 思考(Reasoning) :分析当前情况,决定下一步该做什么
- 行动(Acting) :执行工具调用或生成最终答案
- 观察(Observation) :接收工具执行的结果
- 迭代:基于观察结果继续思考和行动,直到完成任务
这个循环使 Agent 能够:
- 将复杂问题分解为多个步骤
- 动态调整策略基于中间结果
- 处理需要多次工具调用的任务
- 在不确定的环境中做出决策
java
public static void main(String[] args) {
OpenAIClient apiClient = OpenAIOkHttpClient.builder()
.apiKey(API_KEY)
.baseUrl(BASE_URL)
.build();
String userMessageTemplate = """
## 角色定义
你是一个强大的 AI 助手,通过思考和使用工具来解决用户的问题。
## 任务
你的任务是尽你所能回答以下问题。你可以使用以下工具:
{tools}
## 规则
- Action中只需要返回工具的名字,比如writeFile,不要返回以下格式toolName=writeFile
- 每次只做一次Reason/Action/ActionInput或者FinalAnswer的输出过程,不要一次性都做了
- 每次返回的过程中不要自己生成Observation的内容
- 返回Reason/Action/ActionInput的时候不要生成并返回Observation的内容
## 输出过程参考
第一轮
Reason: 你思考的过程
Action: 你的下一步动作,你想要执行的工具是哪个,必须是{tools}中的一个
ActionInput: 你要调用的工具的输入参数是什么
第二轮
Reason: 你思考的过程
Action: 你的下一步动作,你想要执行的工具是哪个,必须是{tools}中的一个
ActionInput: 你要调用的工具的输入参数是什么
第三轮
Reason: 你思考的过程
Action: 你的下一步动作,你想要执行的工具是哪个,必须是{tools}中的一个
ActionInput: 你要调用的工具的输入参数是什么
...
最后一轮
FinalAnswer: 表示最终的答案,只需要最后输出就可以了
## 用户需求
Question: {input}
## 历史聊天记录
{history}
""";
String tools = """
工具1:
名称:weaterTool
工具说明: 查询城市天气
参数类型:json
参数说明: city(城市名称)
工具2:
名称:travelTool
工具说明: 根据天气查询适合的旅途工具
参数类型:json
参数说明: weather(天气)
""";
String history = """
""";
String userMessage = userMessageTemplate
.replace("{tools}", tools)
.replace("{history}", history)
.replace("{input}", "南昌的天气如何?适合哪种旅途工具?");
ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
.addUserMessage(userMessage)
.model(LLM_NAME)
.build();
ChatCompletion chatCompletion = apiClient.chat().completions().create(params);
String output = chatCompletion.choices().get(0).message().content().get();
System.out.println(output);
//模拟从output解析出城市名称,工具名称,进行调用工具
String weather = weatherTool(Map.of("city", "南昌"));
history = """
Reason: 首先需要获取南昌的天气信息,才能进一步推荐适合的旅途工具。因此,我应使用weaterTool查询南昌的天气。
Action: weaterTool
ActionInput: {"city": "南昌"}
Observation:晴天
""";
userMessage = userMessageTemplate
.replace("{tools}", tools)
.replace("{history}", history)
.replace("{input}", "南昌的天气如何?适合哪种旅途工具?")
;
params = ChatCompletionCreateParams.builder()
.addUserMessage(userMessage)
.model(LLM_NAME)
.build();
chatCompletion = apiClient.chat().completions().create(params);
output = chatCompletion.choices().get(0).message().content().get();
System.out.println(output);
//模拟从output解析出天气情况,工具名称,进行调用工具
String travel = travelTool(Map.of("weather", "晴天"));
history = """
Reason: 需要先查询南昌的天气,才能根据天气情况推荐适合的旅途工具。因此首先使用weaterTool查询南昌的天气。
Action: weaterTool
ActionInput: {"city": "南昌"}
Observation:晴天
Reason: 已获取南昌的天气为晴天,接下来需要根据该天气情况推荐适合的旅途工具。因此,我应使用travleTool查询适合的旅途工具。
Action: travleTool
ActionInput: {"weather": "晴天"}
Observation:飞机
""";
userMessage = userMessageTemplate
.replace("{tools}", tools)
.replace("{history}", history)
.replace("{input}", "南昌的天气如何?适合哪种旅途工具?")
;
params = ChatCompletionCreateParams.builder()
.addUserMessage(userMessage)
.model(LLM_NAME)
.build();
chatCompletion = apiClient.chat().completions().create(params);
output = chatCompletion.choices().get(0).message().content().get();
System.out.println(output);
}
public static String weatherTool(Map<String, String> params) {
Map<String, String> weatherMap = Map.of("南昌", "晴天", "九江", "小雨");
return Optional.ofNullable(weatherMap.get(params.get("city"))).orElse("没有这个城市的天气信息");
}
public static String travelTool(Map<String, String> params) {
Map<String, String> weatherMap = Map.of("晴天", "飞机", "小雨", "动车");
return Optional.ofNullable(weatherMap.get(params.get("weather"))).orElse("没有适合这种天气的出行方式");
}
这是样例回答
text
第一轮
Reason: 用户询问南昌的天气以及适合的旅途工具。我需要先获取南昌的天气信息,才能根据天气推荐合适的旅途工具。因此,我首先应该调用天气查询工具。
Action: weaterTool
ActionInput: {"city": "南昌"}
Reason: 已经获取到南昌的天气是晴天。现在需要根据晴天这个天气情况,使用travelTool来查询适合的旅途工具。
Action: travelTool
ActionInput: {"weather": "晴天"}
Reason: 根据工具调用记录,南昌的天气为晴天,根据晴天天气推荐的旅途工具为飞机。
FinalAnswer: 南昌当前的天气是晴天,适合选择飞机作为旅途工具。