JavaGuide - Agent记忆系统
Agent 记忆系统这篇文章将理清以下五个问题:
记忆的存储形式和功能分类;
短期记忆与长期记忆分别怎么落地;
LETTA、ZEP、MemOS 这些产品有什么差异;
反思、遗忘、混合检索这些机制该怎么做;
为什么 Markdown 也可以作为一种轻量级记忆载体。
记忆系统的设计双层记忆短期记忆是 session 级别的记忆,比如当前任务重点、当前任务进度;长期记忆则是同一工作空间下跨 session 的记忆,例如项目的固有事实、用户偏好等。
二者需要从逻辑上、物理上进行隔离。不过,一般而言长期记忆从短期记忆的沉淀中得来。
短期记忆详解前面提到,短期记忆是 session 级别的记忆
JavaGuide - Agent核心概念
Agent 核心概念Agent 核心概念
一个可用的 Agent 必须包含哪几个部分?必须有以下三大部分: LLM、Tool、Context。
其中,LLM 负责工作决策;Tool 由 LLM 决策调用,增强 LLM 功能;Context 构建 LLM 工作上下文。
前两者自不必说,很多人实际上忽略了 Context 的重要性,这一部分甚至可以排在三者中最重要的地位,在 LLM 高度依赖 AI 厂商提供的 API、Tool 直接化用传统编程成果的当下,Context 的高度依赖设计者自身经验,上下文质量直接决定一个 Agent 的智商,这可能将是未来竞争的主要战场。
ToolAgent 调用工具,必不可少的两大要素:Structured Schema & MCP Protocol。前者使 LLM 能够规范调用工具,后者使 Agent 与工具直接能够实现通信。
Structured Schema现在主流的数据格式基本都在向 OpenAI Function Calling Schema 靠拢,一个 Schema 被设计出来是供 LLM 查看的,里面定义了诸如工具名称、用途、何时调用 ...
JavaGuide - 结构化输出
结构化输出大模型结构化输出:从 JSON 契约到 Function Calling 落地
本文主线:先看“只靠 Prompt 要 JSON”为什么不稳,再看怎么用 Schema 把输出变成契约,最后落到 Function Calling、MCP 和 Java 后端工具执行。
在如今 Agent 工作量中,需要大模型频繁地调用各类工具以跳脱出原始的对话框,当前的 Agent 也越来越依赖结构化输出,能够稳定、可靠地输出各种形式的结构化内容,意味着 Agent 对于工具的掌握就越熟练。
为了让大模型输出严格的结构化内容,让大模型在自回归生成时就遵守结构规范是一种符合直觉的方案,但在我们实际的经验中,大模型会频繁地不按照我们的要求进行,所以除了在大模型本身下功夫外,还需要在外部进行干预。
prompt 为什么不能强制规范结构化输出底层原因:大模型自身性能不足、幻觉、上下文污染。
具体表现为:
格式漂移:确实输出了 JSON,但是不只有 JSON,还有一些自然语言,比如 “以下是…”,或者在最后解释 “上述 JSON 是……” 等,如果直接返回给后端,光是自然语言这几句话就直接让服务爆了。
...
HelloAgent - 上下文工程
上下文工程第九章 上下文工程
代码仓库
上下文工程学符合工程规范的上下文设计Transformer 本身有着缺陷,而为了防止上下文腐败和上下文漂移,我们需要人为地将上下文控制在一定长度和结构内,控制长度是为了防止重点事项被稀释,控制结构是为了尽可能地提升信息密度。
长度上能做的不多,只有及时遗忘、控制信息长度,反而是上下文的结构需要我们仔细思考。官方在文档中提到,建议按照以下结构控制上下文:
系统提示(System Prompt):语言清晰、直白,信息层级把握在“刚刚好”的高度。
工具(Tools):工具定义了智能体与信息/行动空间的契约,必须促进效率:既要返回token 友好的信息,又要鼓励高效的智能体行为
示例(Few-shot):始终推荐提供示例,但不建议把“所有边界条件”的罗列一股脑塞进提示。请精挑细选一组多样且典型的示例,直接画像“期望行为”。对 LLM 而言,好的示例胜过千言万语。
总的指导思想是:信息充分但紧致。
上下文检索与 Agent 工作上下文的结构与长度,是随着 Agent 工作实时变动的,特别体现在:需要的时候主动检索,不需要的时候不加载 ...
HelloAgent - 记忆与检索
记忆与检索第八章 记忆与检索
代码仓库
框架现有的缺陷?最显著的一点是:所有的历史上下文,都只在程序运行期间存在的(也就是内存里),程序运行完毕历史就没了,会话之间的上下文也没法共享。
另一个缺陷则是,我们太过于依赖 LLM 本身的能力了,我们必须承认不同供应商的 LLM 的知识库水平是不同的,比如 gemini 知识库很全,claude 在 coding 知识上很强。完全依靠 LLM 的知识库是不稳定的,我们需要构建自己的知识库。
所以我们的框架,当务之急是解决以上问题,我们最容易想到的是将历史上下文持久化,这样就可以解决上下文共享,也可以建立我们自己的知识库。
上手体验:MemoryTool + RAG官方依然给出了完整的 rag 组件,使用 pip 安装:
123pip install "hello-agents[all]==0.2.9"python -m spacy download zh_core_web_smpython -m spacy download en_core_web_sm
随后,需要三个组件:Qdrant、Neo4J、Embedding, ...
HelloAgent - 构建你的 Agent 框架
构建你的 Agent 框架第七章 构建你的智能体框架
代码仓库
本章目标本章目标为,我们需要手写以下架构:
123456789101112131415161718192021222324252627282930HelloAgent/ │ ├── core/ # 核心框架层 │ ├── agent.py # Agent基类 │ ├── llm.py # HelloAgentsLLM统一接口 │ ├── message.py # 消息系统 │ ├── config.py # 配置管理 │ └── exceptions.py # 异常体系 │ ├── agent/ # Agent实现层 │ ├── simpleAgent.py # SimpleAgent实现 │ ...
HelloAgent - Agent经典范式构建
第四章 智能体经典范式构建
本章任务:
Cli:构建一个基本的客户端,能够成功调用 LLM ,并解析 LLM 流式返回的结果
ReAct(Reasoning and Action):着重于实现如何让模型在执行过程不断根据当前状况动态地更新行动计划;
Plan-and-Solve:着重于构建模型的规划能力;
Reflection:模型的反思能力。
基本 Cli前置库:
1pip install openai python-dotenv
仔细阅读一下 HelloAgentLLM.py 具体干了什么。
初始化1234567891011def __init__(self, model: str = None, apiKey: str = None, baseUrl: str = None, timeout: int = None): # 1.初始化客户端。优先使用传入参数,如果未提供,则从环境变量加载。 self.model = model or os.getenv("LLM_MODEL_ID") apiKey = apiKey or os. ...
JavaGuide - 大模型调用工程实践
大模型 API 调用工程实践:流式输出、重试、限流与结构化返回
这篇文章从 构建一个生产级ai对话框 的实际业务出发,解析了一些开发者可能遇到的问题,并尝试解答。
LLM 的调用LLM 调用大致流程流程如下:
客户端请求,服务器鉴权:用户(客户端)提出访问请求,发给服务器(开发者的),服务器需要确认该请求的用户、套餐、配额,确认是否允许此次访问;
服务器组装 prompt:若访问合法,则服务器会将 system prompt、历史信息、RAG 知识、MCP 工具包、用户 prompt、输出格式等信息组装成需要 llm 处理的 prompt;
服务器 token 估算:组装好的 prompt 会被 Tokenizer 拆分为 token,同时计算 token 输入量,估算需要给输出留多少 token 量,并决定是否压缩上下文、裁切上下文、是否可以换用更加契合需求的模型;
模型网关路由:选择模型、供应商、区域等路由工作。此外模型网关还肩负这一个重要职能:全权确保大模型的输出稳定,所以还包含了超时参数、重试策略、限流桶等;
供应商 LLM 工作:服务器将请求发往供应商,请求调用大模 ...
JavaGuide - LLM 运行机制
LLM 运行机制:Token、上下文窗口与采样参数怎么影响输出
Token 及其影响基于历史 token 的预测
自回归生成:根据前面的历史,预测后面的输出。
如何去预测?一般来说需要模型自行识别历史 token 中哪些是相关性高的,哪些是相关性低的,选取高相关性的 token 更容易预测。因此,模型的一个重要参数是选取规则,目前有 Temperature / Top-p 等,选取规则本身是会影响模型预测精度的。
而选取 token 后,需要输出 token,这里引申另一个重要参数是 Max Tokens,即决定模型在单次预测中,最多可以输出的 token 总量。不过,这个参数并不会影响模型本身的预测精度,因为预测的结果是不变的,模型只是按照 max token 这个参数计算并输出,如果不够了截断就是了。
分词器 Tokenizer
分词器 Tokenizer:将自然语言切分 token 的规则。
Tokenizer 本身是需要训练的,一旦训练好,此后均按照这套规则进行分词。
各大模型基本上会自己训练一套 Tokenizer,所以不同的模型直接的 token 计算规则不能 ...
Java 反射基础
反射 基础什么是反射JVM 可以在运行时动态地拿到类的详细信息,这允许在运行时才确认类的信息。
谁在用反射首先,我们人肯定用得很少,或者说基本不用。用这个的多是一些支持自动化的组件,比如 Spring 和 Mybatis 这些框架。
从内存的角度说反射反射的物理层基础当 ClassLoader 加载一个类(注意是字节码)时,首先会把类的一些固有信息,例如类名、有哪些成员、成员方法的实现段、静态成员等,都会存到元空间,其格式是用Cpp写的,但是注意,只是存储格式是 Cpp 的,其成员名称、方法代码段原文是以 .class 存储的。
在将类的固有信息存入元空间之后,紧接着 JVM 会实例化一个java.lang.Class类型的对象存在堆区,这个对象同样用来存储类的固有信息,但和元空间的那个 Cpp 结构体的区别在于:元空间里那个存的是真正的数据;java.lang.Class对象存的是指向元空间那片空间的Cpp指针,所以这个 Class 对象相当于一个代理。
方法也是一样的,方法的实现段存在元空间,java.lang.reflect.Method对象就存方法在元空间内真实存在的方法实现段 ...
