Hello-Agents
Hello-Agents
ps:本文是我个人Java后端+agent方向的笔记,本篇笔记旨在基本了解agent相关概念和流程,为后续学习打地基,只是根据我个人来的,有些章节就没有出现,不全,有需要的可以去看原文档
附文档链接(不含代码):https://datawhalechina.github.io/hello-agents/#/README.md
智能体与语言模型基础
智能体(Agent)
在人工智能领域,智能体被定义为任何能够通过传感器(Sensors)感知其所处环境(Environment),并自主地通过**执行器(Actuators)采取行动(Action)**以达成特定目标的实体。
LLM(大语言模型)
超大参数 + Transformer 架构 + 海量文本预训练 + 通用语言理解与生成 + 涌现能力。
Agent 和普通 ChatBot 有什么区别
| 对比维度 | 普通 ChatBot | AI Agent(智能体) |
|---|---|---|
| 核心定位 | 对话应答工具 | 任务执行智能体 |
| 工作模式 | 被动接收提问,单次输出结果 | 主动理解目标,分步完成复杂流程 |
| 工具调用 | 不支持外接工具 | 原生支持调用搜索、API、软件等 |
| 思维能力 | 无任务规划、逻辑拆解 | 具备思维链,可拆分子任务、自查结果 |
| 适用场景 | 闲聊、简单问答、文本翻译 | 联网调研、自动化流程、复杂任务执行 |
Agent 的组成
- LLM + Tool + Memory + Planning
Agent的类型
-
基于内部决策架构的分类
-
基于时间与反应性的分类
- 反应式智能体
-
规划式智能体
-
混合式智能体(规划+反应)
-
基于知识表达的分类
- 符号主义AI
- 亚符号主义AI
- 神经符号主义AI
Agent的感知与行动
一套明确的交互协议 (Interaction Protocol) 来规范其与环境之间的信息交换。
- 这个结构包含两部分:Thought(思考) + Action(行动)
- 得到的输出Observation即观察
- 通过这个由 Thought、Action、Observation 构成的严谨循环,LLM 智能体得以将内部的语言推理能力,与外部环境的真实信息和工具操作能力有效地结合起来。
提示工程(Prompt Engineering)
- 驱动真实 LLM 的关键
Agent 常见应用场景
案例运行成功:

(自主协作)框架的架构范式归纳
- 单智能体自主循环
- 核心是一个通用智能体通过“思考-规划-执行-反思”的闭环,不断进行自我提示和迭代,以完成一个开放式的高层级目标
- 多智能体协作
- 当前最主流的探索方向,旨在通过模拟人类团队的协作模式来解决复杂问题
- 高级控制流架构
- 更侧重于为智能体提供更强大的底层工程基础
Workflow(工作流)和Agent的差异
- Workflow 是让 AI 按部就班地执行指令,而 Agent 则是赋予 AI 自由度去自主达成目标。
大语言模型基础
语言模型 (Language Model, LM) 是自然语言处理的核心,其根本任务是计算一个词序列(即一个句子)出现的概率
Transformer架构理解
核心定义
Transformer 是 2017 年谷歌提出、基于自注意力机制(Self-Attention) 的深度学习模型,彻底替代 RNN/LSTM,成为大语言模型、AI 大模型的基础架构。
核心创新:自注意力机制
传统序列模型(RNN)只能逐词串行处理,长文本会丢失信息;
自注意力可以并行计算,同时捕捉文本里长距离、全局语义关联(比如一句话首尾词语的关系)。
整体结构(两大模块)
Transformer 由 编码器 (Encoder) + 解码器 (Decoder) 组成:
- 编码器 Encoder
- 作用:理解、提取文本特征(阅读理解、分类、语义分析)
- 代表模型:BERT(纯 Encoder)
- 解码器 Decoder
- 作用:逐一生成文本(对话、写作、翻译)
- 代表模型:GPT 系列、各类对话大模型(仅用 Decoder)
- 完整 Encoder+Decoder
- 多用于机器翻译(理解原文 → 生成译文)
内部核心组件
- 词嵌入(Embedding):把文字转成模型能计算的向量
- 位置编码(Positional Encoding):给单词加顺序信息(Transformer 不天然识先后)
- 多头自注意力(Multi-Head Attention):从多个角度捕捉语义关系
- 前馈神经网络 FFN:对特征做非线性变换
- 层归一化、残差连接:保证深层网络稳定训练
特点总结
- 依靠自注意力,擅长长文本建模
- 支持并行计算,训练速度远快于 RNN
- 结构通用,是 LLM、CV、多模态模型 的底层基石
- 主流大语言模型(GPT、LLaMA、通义、文心等)均基于 Transformer Decoder
通俗解释
Transformer 就是靠 “全局注意力” 看懂全文、再逐字生成内容的神经网络架构,是现在所有大 AI 模型的 “地基”。
Decoder-Only 架构
来源
OpenAI 在开发 GPT (Generative Pre-trained Transformer) 时,提出了一个更简单的思想:语言的核心任务,不就是预测下一个最有可能出现的词吗?
GPT 做了一个大胆的简化:它完全抛弃了编码器,只保留了解码器部分。 这就是 Decoder-Only 架构的由来。
工作模式
Decoder-Only 架构的工作模式被称为自回归 (Autoregressive) 。
重要机制
解码器通过掩码自注意力 (Masked Self-Attention),避免预测第t个词时读取后续词的信息。
通过“预测下一个词”这一简单的范式,开启了我们今天所处的大语言模型时代。
提示Prompt
提示工程,就是研究如何设计出精准的提示,从而引导模型产生我们期望输出的回复。
- 零样本提示 (Zero-shot Prompting) 这指的是我们不给模型任何示例,直接让它根据指令完成任务。这得益于模型在海量数据上预训练后获得的强大泛化能力。
- 单样本提示 (One-shot Prompting) 我们给模型提供一个完整的示例,向它展示任务的格式和期望的输出风格。
- 少样本提示 (Few-shot Prompting) 我们提供多个示例,这能让模型更准确地理解任务的细节、边界和细微差别,从而获得更好的性能。
基础提示技巧
-
角色扮演 (Role-playing) 通过赋予模型一个特定的角色,我们可以引导它的回答风格、语气和知识范围,使其输出更符合特定场景的需求。
# 案例 你现在是一位资深的Python编程专家。请解释一下Python中的GIL(全局解释器锁)是什么,要让一个初学者也能听懂。 -
上下文示例 (In-context Example) 这与少样本提示的思想一致,通过在提示中提供清晰的输入输出示例,来“教会”模型如何处理我们的请求,尤其是在处理复杂格式或特定风格的任务时非常有效。
# 案例 我需要你从产品评论中提取产品名称和用户情感。请严格按照下面的JSON格式输出。 评论:这款“星尘”笔记本电脑的屏幕显示效果惊人,但我不太喜欢它的键盘手感。 输出:{"product_name": "星尘笔记本电脑", "sentiment": "混合"} 评论:我刚买的“声动”耳机音质很棒,续航也超出了我的预期! 输出:
文本分词
将文本序列转换为数字序列的过程,就叫做分词 (Tokenization) 。
分词器 (Tokenizer) 的作用,就是定义一套规则,将原始文本切分成一个个最小的单元,我们称之为词元 (Token) 。
- 现代大语言模型普遍采用子词分词 (Subword Tokenization) 算法
上下文窗口
模型的上下文窗口(如 8K, 128K)是以 Token 数量计算的,而不是字符数或单词数。同样一段话,在不同语言(如中英文)或不同分词器下,Token 数量可能相差巨大。精确管理输入长度、避免超出上下文限制是构建长时记忆智能体的基础。
缩放法则(Scaling Laws)
是近年来大语言模型领域最重要的发现之一。它揭示了模型性能与模型参数量、训练数据量以及计算资源之间存在着可预测的幂律关系。
模型幻觉(Hallucination)
通常指的是大语言模型生成的内容与客观事实、用户输入或上下文信息相矛盾,或者生成了不存在的事实、实体或事件。
幻觉的本质是模型在生成过程中,过度自信地“编造”了信息,而非准确地检索或推理。
根据其表现形式分类:
- 事实性幻觉 (Factual Hallucinations) : 模型生成与现实世界事实不符的信息。
- 忠实性幻觉 (Faithfulness Hallucinations) : 在文本摘要、翻译等任务中,生成的内容未能忠实地反映源文本的含义。
- 内在幻觉 (Intrinsic Hallucinations) : 模型生成的内容与输入信息直接矛盾。
模型为什么会幻觉
多方面因素共同作用的结果
- 训练数据 中可能包含错误或矛盾的信息
- 模型的自回归生成机制决定了它只是在预测下一个最可能的词元,而没有内置的事实核查模块
- 在面对需要复杂推理的任务时,模型可能会在逻辑链条中出错,从而“编造”出错误的结论
大语言模型还面临着知识时效性不足和训练数据中存在的偏见等挑战
模型为什么需要 RAG
检测和缓解幻觉的方法
- 数据层面: 通过高质量数据清洗、引入事实性知识以及强化学习与人类反馈 (RLHF) 等方式,从源头减少幻觉。
- 模型层面: 探索新的模型架构,或让模型能够表达其对生成内容的不确定性。
- 推理与生成层面:
- 检索增强生成 (Retrieval-Augmented Generation, RAG): 这是目前缓解幻觉的有效方法之一。RAG 系统通过在生成之前从外部知识库(如文档数据库、网页)中检索相关信息,然后将检索到的信息作为上下文,引导模型生成基于事实的回答。
- 多步推理与验证: 引导模型进行多步推理,并在每一步进行自我检查或外部验证。
- 引入外部工具: 允许模型调用外部工具(如搜索引擎、计算器、代码解释器)来获取实时信息或进行精确计算。
构建 LLM Agent
Hello-Agents 里 Part 2 主要是开始动手构建 Agent,包括 ReAct、低代码平台、主流框架、自研 Agent 框架等内容。官方说明里也说 Part 2 是实践起点,会实现 ReAct、体验 Coze、接触 LangGraph,并从零构建自己的 Agent 框架。
重点看:
ReAct 思想
Tool Calling 工具调用
Agent 执行流程
简单 Agent 框架怎么组织代码
用户输入
↓
大模型思考
↓
判断是否需要调用工具
↓
调用工具
↓
拿到工具结果
↓
继续推理
↓
输出最终答案
经典的架构范式:
- ReAct (Reasoning and Acting): 一种将“思考”和“行动”紧密结合的范式,让智能体边想边做,动态调整。
- Plan-and-Solve: 一种“三思而后行”的范式,智能体首先生成一个完整的行动计划,然后严格执行。
- Reflection: 一种赋予智能体“反思”能力的范式,通过自我批判和修正来优化结果。
环境配置

ReAct(Reason+Act)
将推理 (Reasoning) 与行动 (Acting) 显式地结合起来,形成一个“思考-行动-观察”的循环。(2022年提出)
- 核心优势在于环境适应性和动态纠错能力
推理使得行动更具目的性,而行动则为推理提供了事实依据。
适用于以下场景:
- 需要外部知识的任务:如查询实时信息(天气、新闻、股价)、搜索专业领域的知识等。
- 需要精确计算的任务:将数学问题交给计算器工具,避免LLM的计算错误。
- 需要与API交互的任务:如操作数据库、调用某个服务的API来完成特定功能。
Tool Calling 工具调用
Tool Calling 是工程统称,Function Calling 是 LLM 标准协议(OpenAI / 通义 / 文心等通用接口规范),Agent 本质就是基于 Function Calling 实现工具调用。
为了让ReAct范式能够真正解决我们设定的问题,智能体需要具备调用外部工具的能力。
-
获取APIkey
-
实现搜索工具的核心逻辑
-
一个良好定义的工具应包含以下三个核心要素:
- 名称 (Name): 一个简洁、唯一的标识符,供智能体在
Action中调用,例如Search。 - 描述 (Description): 一段清晰的自然语言描述,说明这个工具的用途。这是整个机制中最关键的部分,因为大语言模型会依赖这段描述来判断何时使用哪个工具。
- 执行逻辑 (Execution Logic): 真正执行任务的函数或方法。
- 名称 (Name): 一个简洁、唯一的标识符,供智能体在
-
from serpapi import SerpApiClient def search(query: str) -> str: """ 一个基于SerpApi的实战网页搜索引擎工具。 它会智能地解析搜索结果,优先返回直接答案或知识图谱信息。 """ print(f"🔍 正在执行 [SerpApi] 网页搜索: {query}") try: api_key = os.getenv("SERPAPI_API_KEY") if not api_key: return "错误:SERPAPI_API_KEY 未在 .env 文件中配置。" params = { "engine": "google", "q": query, "api_key": api_key, "gl": "cn", # 国家代码 "hl": "zh-cn", # 语言代码 } client = SerpApiClient(params) results = client.get_dict() # 智能解析:优先寻找最直接的答案 if "answer_box_list" in results: return "\n".join(results["answer_box_list"]) if "answer_box" in results and "answer" in results["answer_box"]: return results["answer_box"]["answer"] if "knowledge_graph" in results and "description" in results["knowledge_graph"]: return results["knowledge_graph"]["description"] if "organic_results" in results and results["organic_results"]: # 如果没有直接答案,则返回前三个有机结果的摘要 snippets = [ f"[{i+1}] {res.get('title', '')}\n{res.get('snippet', '')}" for i, res in enumerate(results["organic_results"][:3]) ] return "\n\n".join(snippets) return f"对不起,没有找到关于 '{query}' 的信息。" except Exception as e: return f"搜索时发生错误: {e}"
-
-
构建通用的工具执行器
- 需要一个统一的管理器来注册和调度多种工具
-
测试
ReAct智能体的编码实现
将所有独立的组件,LLM客户端和工具执行器组装起来,构建一个完整的 ReAct 智能体:
-
系统提示词设计
提示词是整个 ReAct 机制的基石,它为大语言模型提供了行动的操作指令。我们需要精心设计一个模板,它将动态地插入可用工具、用户问题以及中间步骤的交互历史。
# ReAct 提示词模板 REACT_PROMPT_TEMPLATE = """ 请注意,你是一个有能力调用外部工具的智能助手。 可用工具如下: {tools} 请严格按照以下格式进行回应: Thought: 你的思考过程,用于分析问题、拆解任务和规划下一步行动。 Action: 你决定采取的行动,必须是以下格式之一: - `{{tool_name}}[{{tool_input}}]`:调用一个可用工具。 - `Finish[最终答案]`:当你认为已经获得最终答案时。 - 当你收集到足够的信息,能够回答用户的最终问题时,你必须在Action:字段后使用 Finish[最终答案] 来输出最终答案。 现在,请开始解决以下问题: Question: {question} History: {history} """这个模板定义了智能体与LLM之间交互的规范:
- 角色定义: “你是一个有能力调用外部工具的智能助手”,设定了LLM的角色。
- 工具清单 (
{tools}): 告知LLM它有哪些可用的“手脚”。 - 格式规约 (
Thought/Action): 这是最重要的部分,它强制LLM的输出具有结构性,使我们能通过代码精确解析其意图。 - 动态上下文 (
{question}/{history}): 将用户的原始问题和不断累积的交互历史注入,让LLM基于完整的上下文进行决策。
-
核心循环的实现
ReActAgent的核心是一个循环,它不断地“格式化提示词 -> 调用LLM -> 执行动作 -> 整合结果”,直到任务完成或达到最大步数限制。
-
输出解析器的实现
LLM 返回的是纯文本,我们需要从中精确地提取出
Thought和Action。这是通过几个辅助解析函数完成的,它们通常使用正则表达式来实现。 -
工具调用与执行
首先检查是否为
Finish指令,如果是,则流程结束。否则,它会通过tool_executor获取对应的工具函数并执行,得到observation。 -
观测结果的整合
最后一步,也是形成闭环的关键,是将
Action本身和工具执行后的Observation添加回历史记录中,为下一轮循环提供新的上下文。通过将
Observation追加到self.history,智能体在下一轮生成提示词时,就能“看到”上一步行动的结果,并据此进行新一轮的思考和规划。 -
运行实例与分析
将以上所有部分组合起来,我们就得到了完整的
ReActAgent类。
ReAct的特点、局限性与调试技巧
- ReAct 的主要特点
- 高可解释性:ReAct 最大的优点之一就是透明。
- 动态规划与纠错能力:与一次性生成完整计划的范式不同,ReAct 是“走一步,看一步”。
- 工具协同能力:ReAct 范式天然地将大语言模型的推理能力与外部工具的执行能力结合起来。
- ReAct 的固有局限性
- 对LLM自身能力的强依赖:ReAct 流程的成功与否,高度依赖于底层 LLM 的综合能力。
- 执行效率问题:由于其循序渐进的特性,完成一个任务通常需要多次调用 LLM。
- 可能陷入局部最优:步进式的决策模式意味着智能体缺乏一个全局的、长远的规划。
- 调试技巧
- 检查完整的提示词:在每次调用 LLM 之前,将最终格式化好的、包含所有历史记录的完整提示词打印出来。
- 分析原始输出:当输出解析失败时(例如,正则表达式没有匹配到
Action),务必将 LLM 返回的原始、未经处理的文本打印出来。 - 验证工具的输入与输出:检查智能体生成的
tool_input是否是工具函数所期望的格式,同时也要确保工具返回的observation格式是智能体可以理解和处理的。 - 调整提示词中的示例 (Few-shot Prompting):如果模型频繁出错,可以在提示词中加入一两个完整的“Thought-Action-Observation”成功案例,通过示例来引导模型更好地遵循你的指令。
- 尝试不同的模型或参数:更换一个能力更强的模型,或者调整
temperature参数(通常设为0以保证输出的确定性),有时能直接解决问题。
Plan-and-Solve
先规划(Planner)后执行(Executor)
- 核心优势在于结构性和稳定性
适用于那些结构性强、可以被清晰分解的复杂任务
执行器:状态管理
执行器的提示词与规划器不同。它的目标不是分解问题,而是在已有上下文的基础上,专注解决当前这一个步骤。
提示词需要包含以下关键信息:
- 原始问题: 确保模型始终了解最终目标。
- 完整计划: 让模型了解当前步骤在整个任务中的位置。
- 历史步骤与结果: 提供至今为止已经完成的工作,作为当前步骤的直接输入。
- 当前步骤: 明确指示模型现在需要解决哪一个具体任务。
Reflection
Reflection 机制的核心思想:
- 为智能体引入一种事后(post-hoc)的自我校正循环,使其能够像人类一样,审视自己的工作,发现不足,并进行迭代优化。
- 核心工作流程可以概括为一个简洁的三步循环:执行 -> 反思 -> 优化
适合那些对最终结果的质量、准确性和可靠性有极高要求,且对任务完成的实时性要求相对宽松的场景
总结
- ReAct:边想边做、动态迭代,适合不确定场景;
- Plan-and-Solve:先总规划再分步执行,适合结构化固定流程;
- Reflection:执行 + 复盘修正,适合高准确度要求场景。
低代码平台
- 低代码是一种简化软件开发的开发模式:
- 不用手写大量传统代码,依靠可视化拖拽、配置参数、模板、组件就能搭建应用,大幅降低编程门槛、缩短开发周期
- 低代码平台就是实现上面这套能力的工具 / 软件,是承载低代码开发的载体
- Coze
- Dify:融合了后端服务和模型运营的理念,支持 Agent 工作流、RAG Pipeline、数据标注与微调等多种能力
- FastGPT:最核心的优势在于其对知识库问答场景的极致优化
- n8n:强项在于“连接”
- 节点 (Node):节点是工作流中执行具体操作的最小单元。
- 触发节点 (Trigger Node):它是整个工作流的起点,负责启动流程。
- 常规节点 (Regular Node):负责处理具体的数据和逻辑。
- 工作流 (Workflow):工作流是由多个节点连接而成的自动化流程图。
- 节点 (Node):节点是工作流中执行具体操作的最小单元。
- 快速原型验证、非技术用户: 优先选择 Coze
- 企业级应用、复杂业务逻辑、多模态生成: 优先选择 Dify
- 基于私有知识库的问答系统、智能客服: 优先选择 FastGPT
- 深度业务集成、通用自动化流程: 优先选择 n8n
LangGraph
LangGraph 将智能体的执行流程建模为一种状态机(State Machine),并将其表示为有向图(Directed Graph)。
在这种范式中,图的**节点(Nodes)代表一个具体的计算步骤(如调用 LLM、执行工具),而边(Edges)**则定义了从一个节点到另一个节点的跳转逻辑。
LangGraph 是 LangChain 生态的核心组件,适合实现复杂 Agent 流程、多分支逻辑、多智能体协作,也是 Java 生态 LangChain4j 的重要参考。
Memory and Retrieval
以后做 Java AI 项目,最常见就是:
聊天记忆 + 知识库问答 + RAG
Hello-Agents 第 8 章讲 Memory 和 RAG,还把 Memory 和 RAG 设计成标准工具,而不是新建一堆 Agent 类。这个思想对后面做工程项目很有帮助。
重点看:
Memory 是什么
短期记忆和长期记忆区别
RAG 是什么
知识库怎么被检索
为什么要把 Memory / RAG 当成工具
看完要能理解:
RAG = 用户问题 → 向量检索相关文档 → 把文档塞进 Prompt → 让模型基于资料回答
基于LLM的智能体而言,通常面临两个根本性局限:对话状态的遗忘和内置知识的局限
记忆
- 工作记忆
- 情景记忆
- 语义记忆
- 感知记忆
工程中常简化为短期对话记忆(上下文历史)和长期知识库记忆(对接 RAG),二者搭配使用。
MemoryTool
RAG
检索增强生成(Retrieval-Augmented Generation,RAG)是一种结合了信息检索和文本生成的技术
- 核心思想是:在生成回答之前,先从外部知识库中检索相关信息,然后将检索到的信息作为上下文提供给大语言模型,从而生成更准确、更可靠的回答。
专注于外部知识的获取和利用
基本工作流程
- 数据准备阶段
- 数据提取、文本分割、向量化
- 应用阶段
- 响应用户的提问,从数据库中检索相关信息,将其注入Prompt,并最终驱动大语言模型生成答案
架构设计
用户层:RAGTool统一接口
↓
应用层:智能问答、搜索、管理
↓
处理层:文档解析、分块、向量化
↓
存储层:向量数据库、文档存储
↓
基础层:嵌入模型、LLM、数据库
流程:
任意格式文档 → MarkItDown转换 → Markdown文本 → 智能分块 → 向量化 → 存储检索
高级检索策略
- 多查询扩展(Multi-Query Expansion)是一种通过生成语义等价的多样化查询来提高检索召回率的技术。
- 假设文档嵌入(Hypothetical Document Embeddings,HyDE)是一种创新的检索技术,它的核心思想是"用答案找答案"。
- 扩展检索框架
上下文工程
上下文工程(Context Engineering)。它关注的是“在每一次模型调用前,如何以可复用、可度量、可演进的方式,拼装并优化输入上下文”,从而提升正确性、鲁棒性与效率。
核心是管理有限的注意力预算
- ContextBuilder (
hello_agents/context/builder.py):上下文构建器,实现 GSSC (Gather-Select-Structure-Compress) 流水线,提供统一的上下文管理接口 - NoteTool (
hello_agents/tools/builtin/note_tool.py):结构化笔记工具,支持智能体进行持久化记忆管理 - TerminalTool (
hello_agents/tools/builtin/terminal_tool.py):终端工具,支持智能体进行文件系统操作和即时上下文检索
区别
提示工程 关注如何编写与组织 LLM 的指令以获得更优结果(例如系统提示的写法与结构化策略);而上下文工程 则是在推理阶段,如何策划与维护“最优的信息集合(tokens)”,其中不仅包含提示本身,还包含其他会进入上下文窗口的一切信息。
问题
上下文腐蚀(context rot)——随着上下文窗口中的 tokens 增加,模型从上下文中准确回忆信息的能力反而下降。
原因:随着上下文长度增长,模型对这些两两关系的建模能力会被“拉薄”
面对长时程任务的上下文工程
约束的工程手段:压缩整合(Compaction)、结构化笔记(Structured note-taking)与子代理架构(Sub-agent architectures)
工程实践
- ContextBuilder:实现了 GSSC 流水线,提供统一的上下文管理接口
- NoteTool:Markdown+YAML 的混合格式,支持结构化的长期记忆
- TerminalTool:安全的命令行工具,支持即时的文件系统访问
- 长程智能体:整合三大工具,构建了跨会话的代码库维护助手
智能旅行助手案例
注意看它怎么把多个能力组合起来:
用户需求分析
工具调用
规划流程
多步骤执行
最终生成方案
看 Hello-Agents 时,只抓这 8 个关键词
Agent
Tool
Function Calling
ReAct
Planning
Memory
RAG
Multi-Agent
其中最重要的是:
Tool
ReAct
Memory
RAG
这四个以后在 Spring AI 和 LangChain4j 里都会反复出现。
更多推荐

所有评论(0)