Agent基础
1.Agent定义
什么是LLM Agent?LLM Agent的核心在于,用LLM代替传统的工程流程控制,由大模型进行思考,确定解决用户Query的方式,例如直接返回、Search Database、Invoke Tools API、或者使用其他的LLM。相较于传统的工程AI,Agent具有比较大的自主权,在解决问题的时候基本不需要人为干预。
2.LLM Agent工作流程
Agent的工作流程可以简化为以下的步骤:
- 用户输入Prompt提示词,LLM接收用户收到的Prompt
- LLM对Prompt的内容进行理解和思考,并指定解决方案,期间会基于不同思维模式进行Planing,例如链式思维(CoT)、ReAct、树形思维、图形思维GoT等等
- LLM在思考的时候,会基于LTM和STM对结果做出修正;
- Act:制定好解决方案之后,LLM会按照解决方案调用外部工具或API执行任务
- Observation and Optimization: 基于Observor观测任务执行结果,对执行结果学习和优化
flowchart TB
subgraph Input ["输入阶段"]
U([👤 用户输入]) --> P(["📝 Prompt 提示词"])
end
subgraph Thinking ["思考阶段"]
P --> R(["🧠 LLM 接收与理解"])
R --> PL["💭 思考与规划<br/>CoT / ReAct / ToT / GoT"]
PL --> M["🔀 基于记忆修正"]
M -->|LTM| LTM["长期记忆 LTM"]
M -->|STM| STM["短期记忆 STM"]
LTM --> M
STM --> M
end
subgraph Execution ["执行阶段"]
M --> A(["⚡ Act 执行动作"])
A --> T["🔧 调用外部工具/API"]
end
subgraph Optimization ["优化阶段"]
T --> O(["👁️ Observation 观测结果"])
O --> OPT["📈 学习与优化"]
OPT -.->|反馈| PL
OPT --> RESULT(["✅ 最终输出"])
end
classDef inputStyle fill:#e1f5fe,stroke:#01579b,stroke-width:2px,color:#000
classDef thinkingStyle fill:#f3e5f5,stroke:#4a148c,stroke-width:2px,color:#000
classDef executionStyle fill:#fff3e0,stroke:#e65100,stroke-width:2px,color:#000
classDef optimizationStyle fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px,color:#000
classDef memoryStyle fill:#fff9c4,stroke:#f57f17,stroke-width:2px,color:#000
class U,P inputStyle
class R,PL,M thinkingStyle
class A,T executionStyle
class O,OPT,RESULT optimizationStyle
class LTM,STM memoryStyle
3.Agent组织架构
flowchart LR
User[User / Request]
subgraph Agent
Planner[Planner / Reasoning]
Executor[Executor]
Memory[Memory]
end
LLM[LLM]
Tools[Tools / Skills]
Memo[STM / LTM / Sense]
User --> Planner
Planner --> LLM
LLM --> Planner
Planner --> Executor
Executor --> Tools
Tools --> Executor
Planner --> Memory
Memory --> Planner
Memory --> Memo
classDef agent fill:#e1f5fe,stroke:#01579b,stroke-width:2px,color:#000
class Planner,Executor,Memory,LLM agent
各个组件的功能
- Agent:Agent实际上并不算得上是一个组件,更像是一个容器。它不实现具体的功能,而是负责所有组件的生命周期,协调各个组件。
- Planner:Planner是整个系统的中枢大脑,主要进行决策,负责将模糊的、抽象的Prompt拆解为具体的、可以执行的子任务。Planner的原理是结构化Prompt + LLM推理,具体的思维模式有Chain of Thought, Reflection and Act, Tree of Thought, Graph of Thought
- Executor:执行器的作用是将 Planner 规划的Action转换为真实的行为,Executor会根据action调用tools,收集调用结果后feeback给Planner,用于学习和矫正;
- Tools:主要用于链接真实的世界,扩展Agent能力,例如搜索、查询、请求、文件操作等等。Tool是具体的,可以执行的函数;
- Memory:分为短期记忆、长期记忆等等,短期记忆指的是用户上下文的内容,长期记忆存储在数据库用,以知识库的形式为Planner提供参考
4.ChatBot和Agent
4.1 什么是Chatbot?
一句话定义,聊天机器人是一种旨在模拟人类对话的数字系统。
早起的聊天机器人通常需要人为定义对话规则或者内容,如果用户给出了规则之外的输入,chatbot可能会拒绝服务或者抛出异常。
2022年底,OpenAI发布的ChatGPT3.5一经发布就在世界范围内引起了一场人工智能热潮。用户争相体验和机器人对话,相较于传统的Chatbot,由LLM驱动的Chatbot具有更高的对话自由度,并且能够有效应对用户刁钻的问题。
不过,和传统的Chatbot一样,AI Chatbot的主要作用是对用户的输入进行思考,生成响应,返回给用户。Chatbot不会替用户完成任何任务。
4.2.Chatbot VS AI Agent
| 维度 | Chatbot | Agent |
|---|---|---|
| 决策模式 | 基于既定规则被动,遵循脚本 | 智能、主动,能够进行推理、任务拆解等,并采取独立的行动 |
| 行为模式 | 回复简单问题、引导用户完成流程步骤 | 深入了解用户意图,完成复杂的多步骤的流程 |
| 决策权 | 完全由用户掌握 | 用户/Agent(Agent会请求赋予相关权限) |
| 反馈能力 | 不会回顾执行结果,由用户判断执行结果的正确性 | 主动观察执行结果,若失败则会调整策略重新尝试 |
| 上下文能力 | 比较弱,不会存储上下文或者存储少量的上下文信息 | 强,会存储中间结果和用户的上下文 |
| 可控性 | 强,行为可控,出现幻觉的风险较小 | 弱,拥有较高的自由度,比较大的幻觉风险 |
| 典型场景 | 客服问答、知识查询、内容生成、教学答疑 | 自动化运维、数据分析任务、代码修复、多步骤业务处理 |
5.Agent内部实现
5.1.Agent工作流程
首先我们思考一下这个问题:为什么要进行Loop?不能执行完毕之后直接返回给用户吗?
一句话总结:Agent需要通过Loop,通过执行结果修正执行策略,从而达到满意的执行结果。
所有的Agent执行流程可以抽象为以下流程:
flowchart LR
Perception --> Reasoning
Reasoning --> Action
Action --> Feedback
Feedback --> Memory[Memory Updat]
- **Step1:**初始化,设置目标,初始化记忆、上下文、最大步数以及超时时间;
- **Step2:**Observe,观察当前状态。主要是收集用户的上下文信息、Prompt信息,已经执行的步骤、上一步返回的结果以及当前环境状态等;
- Step3:Think / Plan。根据当前状态进行推理,当前状态是什么?目标?下一步调用什么工具?然后输出结构化决策;
- Step4:Act。执行,根据LLM输出的决策信息,调用对应的API或者Tools,并捕获执行结果或者异常;
- Step5:Observe FeedBack。观察执行结果。
- Step6:Update Memory。将本轮信息写入到STM和LTM中。
- Step7:Stop Decision。终止判断,目标是否完成,是否达到终止条件?是否出现了不可恢复的错误?
- Step8:Continue Loop。如果没有终止循环,则进入下一轮循环。
5.2.伪代码
// 1.初始化
init(context);
// 2.主循环逻辑
while (AgentContext.state == RUNNING) {
// 2.1.观测当前状态
Observation curEnv = observeEnv(context);
// 2.2.调用LLM进行分析决策
LLMReasonResult decisions = LLMService.reason(
context.goal, context.memory, curEnv);
// 2.3.根据决策类型准备执行
if (decisions.type == FINISH) {
// a.直接返回结果
context.state = DONE;
context.result = decisions.result;
break;
} else if (decision.type == ACTION) {
Action act = decisions.getAction();
ActionContext ac = decisions.getInput();
// 调用执行器执行动作
Executor exc = Executors.builder().action(act).context(ac).build();
ActionResult ar = buildDefaultResult();
try {
ar = exc.excute();
} catch (RuntimeException e) {
// print log
}
// 更新记忆
context.updateMemory(act, ac, ar);
}
// 步数自增
context.increaseStep();
// 判断循环结束条件
if (context.getStep() >= context.maxStep) {
context.status = FAILED;
break;
}
}
5.3.Java实现Agent
5.3.1.模型
classDiagram
class AgentContext {
+ String goal
+ int stepCounts
+ AgentState state
+ getState() AgentState
+ incrementStep() void
}
5.3.2.接口设计
1.Agent抽象类
public abstract class Agent{ AgentResult run(AgentInput input); }
2.AgentLooper 循环编排器
主要负责while循环的流程编排以及context的状态推进。
public interface AgentLoop{
AgentResult execute(AgentContext cxt);
}
3.AgentObserver 观察者
主要负责构建上下文,分析当前执行环境。
public interface AgentObserver {
Observation observe(AgentContext ctx);
}
4.AgentPlanner 决策器
调用LLM对输入进行思考和规划,得出具体的执行策略。
public interface AgentPlanner {
AgentDecision decideAfterReasoning(Observation obs, AgentContext ctx);
}
5.Executor 执行器
获取执行计划,按照执行计划执行对应的Action。
public interface AgentExecutor {
ActionResult execute(Action ac, AgentState ctx);
}
6.Tool 外部能力
public interface Tool {
ToolResult run(Map params);
}
7.Agent Memory 记忆组件
public interface AgentMemory {
// 保存记忆
void store(MemoryRecord record);
// 获取记忆记录
List<MemoryRecord> recall(RecallRequest req);
}
5.3.3.落地实现
| 功能点 | 实现 | 备注 |
|---|---|---|
| LLM接入 | GLM API | 便宜,稳定 |
| 非阻塞调用 | Spring webClient | 一定要非阻塞调用,用户体感好 |
| 结构化输出 | Jackson | |
| 生命周期管理 | SpringBoot | Bean管理、配置管理 |
| Agent运行状态流转 | 有限状态机 | 防止出现非法状态的流转,更加安全 |
| 提示词模板动态配置 | Nacos | 配置中心,支持配置热更新和配置的版本管理 |
| Tool执行 | 策略模式 | 通过策略模式获取Tool的执行器 |
| Tool注册、发现 | SPI/Registry | |
| STM | Redis / Caffeine | 使用缓存来保存上下文 |
| LTM | DB | 长时记忆应当持久化数据库中 |