Agent

AI Agent的本质是能够感知环境、自主决策并执行行动的智能实体。与传统AI系统最大的区别在于Agent具有自主性、反应性、目标导向和学习能力,它不再是简单的工具,而是能够主动规划和完成复杂任务的智能体。从1997年击败国际象棋世界冠军的IBM“深蓝”,到2011年苹果推出的个人助理Siri,都展示了Agent在特定领域的强大能力,关键的转折点发生在2023年左右,大语言模型LLM的出现为Agent提供了强大的通用理解和推理能力,使其不再局限于单一任务。

Agent 架构模式

  1. 组成组件
    Agent:智能代理,它是一个能够感知环境、做出决策并执行动作的软件实体(比起LLM只能“回答问题”,Agent可以真正地“执行任务”)。在LLM语境中,Agent通常利用LLM作为大脑,来理解用户输入、决定需要执行的动作(比如调用工具)、处理工具返回的结果并生成响应。
    LLM(大语言模型):如GPT系列,是Agent的核心,负责理解自然语言、进行推理和生成文本。
    Tool:工具,是Agent可以调用的函数,用于执行特定任务,比如查询数据库、调用API。Tool扩展了Agent的能力,使其能够获取实时信息或执行具体操作。
    Function Calling:函数调用,是LLM的一种能力,允许模型根据用户输入决定何时以及如何调用哪个函数(Tool),并以结构化格式(如JSON)输出函数调用参数。然后由外部系统执行该函数。
    Prompt:提示词,是引导LLM生成期望输出的文本。在Agent中,Prompt通常包含系统指令(定义Agent的角色和能力)、用户输入、对话历史以及工具描述等。
    RAG(检索增强生成):通过从外部知识库检索相关信息,并将其作为上下文提供给LLM,从而生成更准确、更相关的回答。
    MCP(模型上下文协议):MCP可以包含本地tools和外部API,但通常 MCP更强调于将工具(无论是本地tools还是外部API)以标准化的上下文协议暴露给AI模型。MCP可以看作是一个中间层,它将工具抽象成标准的接口,使得AI Agent可以通过统一的协议来调用这些工具,从而实现模型与工具之间的解耦。
  2. 一个典型的工作流程如下:
    用户输入自然语言请求。
    Agent将用户输入、对话历史、可用的工具描述(通过Function Calling定义)以及系统提示词组合成一个Prompt,发送给LLM。
    LLM根据Prompt判断是否需要调用工具。如果需要,LLM会返回一个函数调用请求(包括函数名和参数)。
    Agent解析LLM返回的函数调用请求,并执行对应的工具(Tool)。
    工具执行后返回结果,Agent将工具执行结果作为上下文,再次调用LLM,生成最终的自然语言响应。
    Agent将响应返回给用户。
    在这个过程中,RAG可以在第一步之前或之中介入,通过检索外部知识库来增强Prompt的上下文。
  3. a demo
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    #### main.py
    from pydantic_ai.models.gemini import GeminiModel
    from pydantic_ai import Agent
    from dotenv import load_dotenv
    import tools

    # 模型API Key等可以写到.env文件 并加载到环境变量
    load_dotenv()
    model = GeminiModel("gemini-2.5-flash-preview-04-17")

    # 将llm模型、系统prompt、工具tools “注册” 到 Agent
    agent = Agent(model,
    system_prompt="You are an experienced programmer",
    tools=[tools.read_file, tools.list_files])

    def main():
    history = []
    while True:
    # eg. Input: list and read file. base on your konwledge tell me what lang each file use.
    user_input = input("Input: ")
    # 将用户输入、历史对话(上下文)发给 agent 并记录本次对话(短期记忆)
    resp = agent.run_sync(user_input,
    message_history=history)
    history = list(resp.all_messages())
    print(resp.output)

    if __name__ == "__main__":
    main()
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    #### tools.py
    from pathlib import Path
    import os

    base_dir = Path("./test")

    def read_file(name: str) -> str:
    # docstring 帮助模型理解 tools
    """Return file content. If not exist, return error message.
    """
    print(f"(read_file {name})")
    try:
    with open(base_dir / name, "r") as f:
    content = f.read()
    return content
    except Exception as e:
    return f"An error occurred: {e}"

    def list_files() -> list[str]:
    print("(list_file)")
    file_list = []
    for item in base_dir.rglob("*"):
    if item.is_file():
    file_list.append(str(item.relative_to(base_dir)))
    return file_list

MCP

MCP 可以看作是一个中间层,它将工具抽象成标准的接口,使得AI Agent可以通过统一的协议来调用这些工具,从而实现模型与工具之间的解耦。MCP 可以包含本地tools和外部API,但通常 MCP更强调于将工具(无论是本地tools还是外部API)以标准化的上下文协议暴露给AI模型。

  1. Agent通过集成的MCP Client向MCP Server发送请求,调用工具。因此,Agent不再直接调用具体的工具函数,而是可以使用任何符合MCP协议的工具,无论工具是本地还是远程。MCP模式下,我们不再直接注册这些Tools到Agent(如传统框架LangChain),而是注册MCP Client(可以看作是Tools的抽象层),然后Agent通过MCP Client来动态获取MCP Server提供的Tools列表,并在需要时调用它们。
    示例流程:
    步骤1:启动一个MCP Server,它提供了一些工具(例如,天气查询、计算器等)。
    步骤2:在Agent框架中,配置MCP Client,并连接到该MCP Server。
    步骤3:Agent在需要时,通过MCP Client查询MCP Server提供了哪些工具。
    步骤4:当用户提问时,Agent决定调用哪个工具,然后通过MCP Client发送调用请求给MCP Server。
    步骤5:MCP Server执行工具,并将结果返回给MCP Client,然后Agent接收结果并生成最终回答。?
  2. MCP代表了AI应用架构的演进方向,从紧耦合的工具注册转向松耦合的工具治理,特别适合企业级AI应用的复杂集成场景。

RAG

RAG​ 的核心思想是:在让大模型回答问题之前,先从一个外部的、可随时更新的知识库中检索相关信息,然后将这些“新鲜”信息作为上下文和问题一起交给模型,从而引导模型生成更准确、及时且可追溯的答案。它能有效减少模型“幻觉”(即胡编乱造),让AI应用在知识密集型任务中变得真正可靠。以及,它能帮助构建专业领域专家对话机器人。

一个典型的RAG系统工作流程包含三个关键阶段:

  1. 知识库索引构建(Indexing)
    这是准备阶段,目的是将您的私有知识库“灌输”进向量数据库。
    文档解析与分块:首先,系统会解析各种格式的文档(如PDF、Word、HTML),将其转换为纯文本。然后,根据语义或结构将长文本切分成大小适宜的“文本块”(Chunks),以适应模型上下文长度限制。
    向量化(Embedding):使用嵌入模型将每个文本块转换为一个高维向量(一组数字)。这个向量就像是文本在数学空间中的“坐标”,语义相近的文本,其向量在空间中的距离也更近。
    向量存储:将这些向量及其对应的原始文本块、元数据(如来源、标题)一并存入向量数据库。
  2. 实时检索(Retrieval)
    当用户提出问题时,系统执行以下操作:
    使用相同的嵌入模型将用户问题也转换为一个向量。
    将这个“问题向量”送入向量数据库,进行相似性搜索。数据库会快速找出与问题向量最相似的K个“文档向量”。
    为了提高检索质量,常采用混合检索策略,结合语义向量搜索和传统关键词搜索,并利用重排序模型对初步结果进行精细排序,以提升准确性。
  3. 增强生成(Generation)
    提示词增强:将检索到的最相关的文本块作为上下文,与用户的原始问题一起组合成一个结构化的提示词(Prompt)。
    智能生成:将这个富含信息的提示词发送给LLM,基于您提供的权威上下文,而非仅凭其内部可能过时的知识,来生成最终答案

Agent流程编排

业务逻辑

LangChain

LangChain 是一个功能强大的大语言模型应用开发框架。与Spring在Java后端开发中的定位类似。
https://python.langchain.com/docs/concepts/
https://arxiv.org/abs/2302.07842

LangChain 包:通过 pip 命令(类似于Java的Maven或Gradle)安装到项目中,避免重复造轮子。

LangGraph

LangGraph 核心认知:用“有向图”构建智能体的新一代框架,是 用于构建有状态、多步骤、多分支智能体(Agent) 的框架,核心是将 Agent 的行为拆解为节点(Nodes)边(Edges),用有向图(Directed Graph) 替代老版本的“线性循环” 以支持更复杂的流程编排。
LangGraph 可以理解为:给 Agent 设计“流程图”的工具,而老版本 ReAct Agent 只是这个流程图中最基础的“单循环分支”。
https://docs.langchain.com/oss/python/langgraph/overview

  • LangGraph 核心概念解析(多节点、边是关键)
    1. 核心基础:状态(State)
      • 作用:整个图的“共享内存”,所有节点都能读写这个状态(比如用户问题、LLM 思考结果、工具调用结果、最终回答等)。
      • 举例:在你之前的 CMDB Agent 中,状态里会包含:
        1
        2
        3
        4
        5
        {
        "messages": [{"role": "user", "content": "显示运行中的Linux服务器"},
        {"role": "ai", "content": "思考过程+工具调用指令"},
        {"role": "tool", "content": "工具调用结果"}]
        }
      • 特点:状态是持久化的(通过 Checkpoint 如 InMemorySaver),支持中断、恢复、回溯(比如多轮对话的上下文保留)。
    2. 最小执行单元:节点(Node)
      • 定义:图的最小操作单元,对应一个具体的功能(比如调用 LLM、调用工具、格式化回答、清洗用户问题)。
      • 类型(实际开发中常见):
      • LLM 节点:调用大模型生成思考结果或工具调用指令(比如你之前看到的“分析问题+工具选择”)。
      • 工具调用节点:执行具体的工具函数(比如 cmdb_searchcmdb_query)。
      • 预处理/后处理节点:清洗用户问题、格式化最终回答。
      • 判断节点:根据状态判断流程走向(比如“是否需要继续调用工具?”)。
      • 多节点的价值:你可以把 Agent 的复杂行为拆分成多个独立节点,比如:
        用户输入清洗节点LLM 思考节点CMDB 工具节点日志工具节点回答格式化节点
    3. 流程的灵魂:边(Edge)
      • 定义:节点之间的连接关系,定义流程的走向。LangGraph 支持三种边,这也是“多分支”的核心:
      • 普通边(Direct Edge):直接从 A 节点跳转到 B 节点(比如“清洗节点”执行完,直接到“LLM 思考节点”)。
      • 条件边(Conditional Edge):根据状态的内容判断跳转方向(最核心的“多分支”能力)。
        • 举例:LLM 输出“需要调用 CMDB 工具”,则跳转到 cmdb_search 节点;如果输出“需要调用日志工具”,则跳转到 log_search 节点;如果输出“无需调用工具”,则跳转到“回答节点”。
      • 入口/出口边:定义图的开始节点(比如用户输入节点)和结束节点(比如回答节点)。
      • 多边的价值:打破了老版本“单一循环”的限制,支持分支、并行、循环等复杂流程。
    4. 关键能力:检查点(Checkpoint)
      • 作用:记录图的执行状态,支持中断、恢复、回溯(比如你之前用的 InMemorySaver 就是内存级的检查点,还可以用 Redis、SQL 实现持久化)。
      • 场景:多轮对话中,用户可以“回退”到上一步,或 Agent 崩溃后恢复执行。
  • LangGraph 中 Agent 与 Tools 的工作机制(结合你的 CMDB 例子)
    以你之前的“显示运行中的 Linux 服务器”为例,LangGraph 的执行流程可以拆解为一个极简的有向图
    1
    2
    3
    4
    5
    6
    7
    8
    9
    [入口节点:用户输入] 
    ↓(普通边)
    [LLM 思考节点]:分析问题,生成工具调用指令(cmdb_search + 入参)
    ↓(条件边:判断需要调用工具)
    [工具调用节点]:执行 cmdb_search,将结果写回状态
    ↓(条件边:判断无需继续调用工具)
    [LLM 回答节点]:基于工具结果生成最终回答
    ↓(普通边)
    [出口节点:输出回答]
    核心细节:
    1. 状态驱动:所有节点都通过状态交互,没有直接的函数调用——LLM 节点从状态中读用户问题,工具节点从状态中读工具调用指令,执行后写回结果。
    2. 工具的解耦:工具本身是独立的函数(如 cmdb_search),LangGraph 只通过工具调用节点统一管理,支持多工具的动态选择和调用。
    3. 循环执行:通过条件边实现“思考→工具→再思考→再工具”的循环(比如用户问“查生产主机并统计数量”,可能需要先调用 cmdb_search,再调用 cmdb_query 统计)。
  • LangGraph vs 老版本 ReAct Agent(核心区别)
    老版本 ReAct Agent(LangChain v0.x 的 AgentExecutor)是 LangGraph 的简化版,两者的核心差异在于流程的编排能力
    维度 老版本 ReAct Agent(AgentExecutor) LangGraph
    架构基础 线性循环(Single Loop) 有向图(Directed Graph)
    节点/边 无物理节点拆分,只有“思考→工具”的逻辑两步;无多分支边,只有单一循环。 支持多节点、多类型边(条件边、普通边),可编排复杂流程。
    状态管理 临时状态(每次循环重新生成,无持久化) 统一的状态对象,支持持久化、回溯(Checkpoint)。
    流程灵活性 只能“思考→工具→思考”的单一循环,多工具需按顺序调用(一次一个)。 支持多分支(比如不同工具的并行调用)、条件跳转、中断恢复。
    扩展性 扩展复杂流程(如多工具并行)需要大量自定义代码。 通过图的编排即可实现,无需修改核心逻辑。
    老版本 ReAct Agent 的核心是 AgentExecutor单一循环
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    while True:
    # 1. 调用 LLM 生成思考结果和工具调用指令
    llm_output = llm.invoke(状态)
    # 2. 判断是否需要调用工具
    if 需要调用工具:
    tool_result = tool.invoke(llm_output 中的指令)
    # 将工具结果加入状态,继续循环
    else:
    # 生成最终回答,退出循环
    break
    它的“节点”只是逻辑上的两步(思考、工具),没有物理上的节点拆分,也没有多分支的边——即使有多个工具,也只能按顺序单次调用(一次调一个),无法实现并行或多分支跳转。
    比如:
    老版本要实现“查生产主机+查今日告警”,只能先调用 cmdb_search,再调用 alert_search,通过多次循环实现。
    LangGraph 可以通过多节点和条件边,甚至并行执行这两个工具(比如同时调用 CMDB 和告警工具,提升效率)。
  • 五、总结:为什么需要 LangGraph?
    1. 从“单一循环”到“复杂图”:老版本 Agent 适合简单的单工具循环场景,而 LangGraph 适合需要复杂流程编排的场景(比如多工具、多分支、有状态的智能体)。
    2. 可视化与可维护性:将 Agent 的行为拆解为节点和边,流程更清晰,便于调试和维护(比如你之前看到的“两轮 LLM 调用”,在 LangGraph 中就是两个节点的执行)。
    3. 生产级能力:Checkpoint、状态持久化、中断恢复等能力,让 LangGraph 更适合生产环境的部署。

Spring AI

集成到Java