Lagent:把 Agent 拆成层与消息传递的轻量框架
A lightweight framework for building LLM-based agents
秒懂
- 它是什么?
- Lagent 用 PyTorch 的类比组织 LLM Agent:Agent 相当于层,AgentMessage 相当于张量,memory 相当于状态。它适合想读源码、改流程的 Python 工程师,不适合只想调 API 拼一个客服机器人的人。
- 适合谁用?
- Lagent 适合已经写过 LLM 调用代码、并且需要把多轮消息、工具调用和输出解析拆开重组的 Python 团队,尤其是想复用 PyTorch 式抽象来组织多 Agent 流程的人。如果你只需要一个开箱即用的对话机器人,或者团队不接受自己写 aggregator 和 parser,它就不是合适的选择。
- 能商用吗?
- 可以。Apache-2.0 是宽松许可证:你可以使用、修改并销售基于它的软件,只需保留版权和许可证声明。
- 还在维护吗?
- 在维护。仓库最近一次提交在 2 天前。
- 用什么语言写的?
- 主要是 Python(依据 GitHub 的语言统计)。
以上回答依据项目的 GitHub 数据(最近同步于 2026年9月15日)和我们的分析,不构成法律意见。
开源项目深度解析
它解决的是哪一类重复劳动
自己写一个 LLM Agent,最容易失控的不是模型调用本身,而是围绕它的一圈胶水代码:多轮历史怎么拼成 OpenAI 格式、模型输出的工具调用怎么解析成结构化字段、流式返回的状态怎么标记、多轮会话之间怎么隔离。这些代码每个项目都要重写一遍,而且写完之后很难测试,因为逻辑散落在业务函数里。Lagent 把这些部分收进几个固定角色:Agent 负责一次前向,Memory 负责状态,Aggregator 负责把内存里的消息拼成模型输入,Parser 负责把模型输出解析回结构。README 里说这套设计受 PyTorch 启发,期望用户只关注创建层和定义层之间的消息传递。目标读者是有一定 Python 工程经验、愿意读源码的人,而不是只想配置一个 YAML 就跑起来的用户。
AgentMessage 是这套框架的基本单位
整个框架围绕 AgentMessage 这个数据结构展开。README 给出的字段包括 content、sender、formatted、extra_info、type、receiver 和 stream_state,其中 stream_state 的取值来自 AgentStatusCode 枚举,示例输出里是 AgentStatusCode.END。sender 决定了一条消息在聚合时被当成 user 还是 assistant,formatted 则专门留给 output_format 解析出来的结构化结果。这个划分值得注意:content 保留模型的原始文本,解析结果另存一处,出问题时可以对照原文排查,不必在字符串里做反向解析。代价是消息对象偏重,字段多,序列化后体积比裸 dict 大。如果你只是做单轮问答,这套结构显得多余。
memory 的读写发生在 __call__ 而不是 forward
README 明确给出了伪代码,说明输入和输出消息都是在 __call__ 里写入 memory,而不是在 forward 里。顺序是 pre_hooks、add_memory、forward、add_memory、post_hooks。这个安排的直接后果是:任何走 __call__ 的调用都会自动留痕,包括失败的调用,因为 forward 抛异常之前输入已经被写入。会话默认使用 session_id=0,README 里给出的清理方式是 agent.reset()。判断当前内存内容有两种途径,agent.memory.get_memory() 返回 AgentMessage 列表,agent.state_dict() 返回可序列化的 dict 列表,后者更适合直接落盘或传给日志系统。这套设计的限制也在这里:memory 是进程内的,README 没有描述跨进程或跨请求的持久化方案,多副本部署时你需要自己决定会话状态放在哪里。
Aggregator 与 Parser 是两个真正的扩展点
默认情况下 Agent 内部用 DefaultAggregator 把 AgentMessage 转成 OpenAI message 格式,README 展示了 forward 中的调用方式:aggregator.aggregate 接收 memory.get(session_id)、self.name、self.output_format 和 self.template 四个参数。要注入 few-shot 示例,可以继承 DefaultAggregator 并覆写 aggregate,在系统指令之后、历史消息之前插入固定的 user/assistant 对。README 给出的 FewshotAggregator 示例里还有一个细节:连续的 user 消息会被合并到上一条 user 消息的 content 上,而不是各占一条。这个合并策略对多 Agent 场景有实际影响,因为多个 sender 的消息可能被压成同一条 user 消息,sender 信息在聚合结果里就丢失了。如果你的流程依赖区分是谁说的话,需要自己改写这段逻辑。输出侧对应的是 output_format,README 提到可以用 lagent.prompts.parsers 下的 ToolParser 来解析工具调用,解析结果写入 AgentMessage.formatted。
装起来要几步,以及模型后端的选择
README 给出的安装方式是源码安装:git clone https://github.com/InternLM/lagent.git,cd lagent,然后 pip install -e .。没有提供 pip install lagent 的说明,尽管徽章指向 PyPI 上的 lagent 包,这一点文档和徽章之间存在不一致。模型侧,README 的示例用 VllmModel,参数包括 path、meta_template、tp、top_k、temperature、stop_words 和 max_new_tokens,meta_template 使用 INTERNLM2_META。也就是说这个例子走的是本地 vLLM 推理,需要你自己准备好权重和 GPU。仓库的 topics 里列了 transformers 和 gpt,说明还有别的后端,但 README 没有展开。对只想接一个云端 API 的人来说,第一步需要翻源码确认可用的 LLM 类,而不是照抄示例。
版本节奏与维护成本的现实
从发布记录看,v0.5.0rc2 在 2024 年 11 月,v0.5.0rc3 在 2025 年 3 月,之后是 2026 年 5 月的 agentrl_rc0,最近的推送时间在 2026 年 8 月。三个发布全部带 rc 或 rc 后缀,没有看到标记为稳定版的 0.5.0。这意味着 API 在可预见的范围内仍可能调整,尤其是 agents、memory、prompts 这几个模块。对采用者来说,升级成本主要落在自定义的 Aggregator 和 Parser 上,因为它们直接依赖 aggregate 和 parse_response 的签名。README 里的 forward 签名是 forward(self, *message, session_id=0, **kwargs),一旦这个约定变化,所有子类都要跟着改。许可证是 Apache-2.0,允许商用和修改,但如果你分发修改后的版本,需要按该许可证的要求保留声明和变更说明,具体条款请以仓库中的 LICENSE 文件为准,这里不构成法律意见。
什么时候它不合适
最明显的不合适场景是把它当成一个配置驱动的 Agent 平台。Lagent 没有提供可视化编排,README 展示的全部是 Python 代码,你要自己写类、自己接模型、自己管会话。第二个场景是团队希望开箱即用的工具生态:README 只演示了 ToolParser 的存在,没有列出内置工具清单,也没有说明工具注册和调用的完整链路,这部分需要读源码才能确认。第三个场景是长会话。memory 默认按 session_id 存在进程内,README 没有提到裁剪、摘要或窗口限制,多轮对话增长后如何控制上下文长度需要自行处理。相比之下,LangChain 走的是另一条路:把模型、工具、检索器都做成可组合的组件并配大量现成集成,代价是抽象层数多、调试时栈很深。Lagent 的选择是把抽象压到最少,换来可读性,但把集成工作交还给使用者。
编辑结论
Lagent 适合已经写过 LLM 调用代码、并且需要把多轮消息、工具调用和输出解析拆开重组的 Python 团队,尤其是想复用 PyTorch 式抽象来组织多 Agent 流程的人。如果你只需要一个开箱即用的对话机器人,或者团队不接受自己写 aggregator 和 parser,它就不是合适的选择。上手前先确认三件事:pip install -e . 之后 lagent.llms 里你能用的模型后端是哪一个;Agent.__call__ 会把输入输出都写进 memory,你的业务是否需要手动调用 agent.reset();以及 v0.5.0rc3 之后的 API 是否还在变动。
社区笔记