003_AI Agent(模拟实现)

工作流程

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

流程说明:

这个图展示了AI Agent的循环工作模式

  1. 感知:接收你的指令或观察环境
  2. 思考:分析情况,规划下一步行动
  3. 行动:使用工具(搜索、计算、控制设备等)执行具体操作
  4. 记忆:记录已执行的操作和结果,保持上下文连贯
  5. 判断:检查是否达到目标,如果没有则回到"思考"阶段继续循环,直到完成任务

简单案例

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 会:

  1. 思考(Reasoning) :分析当前情况,决定下一步该做什么
  2. 行动(Acting) :执行工具调用或生成最终答案
  3. 观察(Observation) :接收工具执行的结果
  4. 迭代:基于观察结果继续思考和行动,直到完成任务

这个循环使 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: 南昌当前的天气是晴天,适合选择飞机作为旅途工具。
相关推荐
uzong22 分钟前
软件架构指南 Software Architecture Guide
后端
又是忙碌的一天22 分钟前
SpringBoot 创建及登录、拦截器
java·spring boot·后端
勇哥java实战分享1 小时前
短信平台 Pro 版本 ,比开源版本更强大
后端
学历真的很重要1 小时前
LangChain V1.0 Context Engineering(上下文工程)详细指南
人工智能·后端·学习·语言模型·面试·职场和发展·langchain
计算机毕设VX:Fegn08951 小时前
计算机毕业设计|基于springboot + vue二手家电管理系统(源码+数据库+文档)
vue.js·spring boot·后端·课程设计
上进小菜猪2 小时前
基于 YOLOv8 的智能杂草检测识别实战 [目标检测完整源码]
后端
Miku162 小时前
使用 Claude Code 的 pptx-skills 技能生成精美 EVA 主题 PPT 完整指南
aigc·agent·claude
韩师傅3 小时前
前端开发消亡史:AI也无法掩盖没有设计创造力的真相
前端·人工智能·后端
栈与堆3 小时前
LeetCode-1-两数之和
java·数据结构·后端·python·算法·leetcode·rust
superman超哥3 小时前
双端迭代器(DoubleEndedIterator):Rust双向遍历的优雅实现
开发语言·后端·rust·双端迭代器·rust双向遍历