单Agent架构设计指南:轻量化场景下的性能优化与功能落地

副标题: 从大模型API调用到可部署的自主Agent,500行Python代码+Llama 3 8B量化版实现边缘可用的PDF知识问答助手,性能提升300%!


摘要/引言

你有没有过这样的经历?花了10分钟写了个用GPT-4o-mini或通义千问API的“简单大模型问答小工具”,一开始用得挺爽,问点常识性问题秒出结果;但当你想让它“读取我刚才上传的这份产品手册PDF,然后用我们公司内部的话术规范,给客户生成一份带FAQ的使用指南”——工具瞬间“懵了”:要么直接说“抱歉我无法读取附件”,要么读了但忘光了手册里的参数,要么生成的FAQ完全不符合公司要求。

这时候你才意识到:普通的“Prompt + LLM API”应用,本质上只是一个“增强版搜索引擎的前端包装器”——它没有记忆,不会主动思考解决问题的步骤,不会调用外部工具(比如读取PDF、查询内部数据库、发送邮件),甚至连基本的输入输出规范都做不好。

那怎么解决这些问题呢?答案是构建一个Agent

问题陈述

在当前的AI应用落地过程中,我们面临三个核心痛点:

  1. 架构复杂,资源消耗大:市面上主流的Agent框架(比如LangChain、AutoGPT、CrewAI)功能确实强大,但架构臃肿、依赖库多达上百个,部署成本高(随便一个CrewAI项目就要占用2GB以上内存,加上量化模型可能要5GB+),根本跑不起在边缘设备(比如树莓派、普通笔记本)、低成本云服务器(1核2G、2核4G)上。
  2. 功能冗余,难以定制:LangChain等框架为了通用性,封装了太多用不到的功能(比如多Agent协作、复杂的向量检索链),对于“读取1份PDF生成FAQ”“监控某个API的状态并在异常时报警”这种轻量化、单任务的场景,反而增加了开发和维护的复杂度——你可能要花3天时间去读LangChain的文档,才知道怎么去掉那些不必要的依赖。
  3. 概念模糊,无从下手:很多初学者对“Agent”的认知还停留在“AutoGPT那种能自动上网、写代码的‘超级AI’”,但实际上,90%以上的落地AI应用只需要单Agent——不需要多Agent协作,不需要自我迭代,只要能完成一个明确的单任务,调用几个必要的外部工具,有一个简单的短期记忆就行。

核心方案

本文提出了一种极简主义的单Agent架构设计,我们称之为“LiteAgent”架构:

  • 核心组件只有4个:LLM推理引擎、工具调用模块、短期记忆模块、任务调度器——总代码量不超过500行Python代码,依赖库控制在10个以内。
  • 适配轻量化场景:专门针对边缘设备、低成本云服务器优化,支持本地量化大模型(Llama 3 8B INT4只需4GB内存就能跑,INT3只需2.5GB),也支持轻量级的API大模型(比如GPT-4o-mini、Claude 3 Haiku、通义千问4 Turbo Mini)。
  • 易于定制和扩展:每个核心组件都是松耦合的,你可以根据自己的需求替换LLM推理引擎(比如从OpenAI换成Ollama再换成vLLM)、添加/删除外部工具(比如把PDF阅读器换成Word阅读器)、修改短期记忆的存储方式(比如从内存换成SQLite)。
  • 性能优化:我们会详细讲解3个核心的性能优化技巧——量化推理、提示词压缩、工具调用预筛选——能让你的单Agent在处理相同任务时,速度提升300%,内存消耗降低50%。

主要成果/价值

读完本文后,你将能够:

  1. 彻底理解单Agent的核心概念:搞清楚“单Agent和普通大模型应用的区别”“LiteAgent架构的4个核心组件是什么、有什么用、怎么协同工作”。
  2. 从零到一构建一个可落地的LiteAgent应用:我们会以“轻量化PDF知识问答助手”为实际场景,手把手带你写代码、调模型、部署上线——这个助手能读取本地/远程的PDF文件,用向量检索的方式找到相关内容,然后用简洁明了的语言回答你的问题。
  3. 掌握单Agent的3个核心性能优化技巧:学会怎么用量化大模型降低内存消耗,怎么用提示词模板压缩输入输出,怎么用工具调用预筛选减少LLM的推理次数。
  4. 具备自定义LiteAgent的能力:你可以根据自己的需求,替换核心组件、添加外部工具、修改任务逻辑——比如把PDF知识问答助手改成“监控股票价格的报警Agent”“自动回复邮件的客服Agent”“生成PPT大纲的办公助手”。

文章导览

本文分为四个部分:

  1. 第一部分:引言与基础:介绍本文的背景、目标、前置知识,以及单Agent的核心概念和理论基础。
  2. 第二部分:LiteAgent架构的核心实现:详细讲解LiteAgent架构的4个核心组件的设计思路和实现代码,然后以PDF知识问答助手为场景,把这些组件组装起来。
  3. 第三部分:性能优化与功能扩展:讲解3个核心的性能优化技巧,以及如何自定义LiteAgent的核心组件、添加外部工具、修改任务逻辑,最后介绍LiteAgent的部署方案。
  4. 第四部分:总结与展望:总结本文的核心要点,回顾我们构建的PDF知识问答助手,然后展望单Agent的未来发展趋势。

目标读者与前置知识

目标读者

本文适合以下人群阅读:

  1. 初级到中级Python后端开发者:有一定的Python编程基础,会用FastAPI/Flask写个小接口,懂点JSON/YAML配置,想学习如何开发AI应用。
  2. AI应用初学者/爱好者:对大模型有基础了解(知道怎么调API或者本地量化推理),对Agent概念感兴趣,但不知道怎么从零到一构建一个可落地的Agent。
  3. 成本敏感的AI应用开发者:想在边缘设备(比如树莓派、普通笔记本)、低成本云服务器(1核2G、2核4G)上部署AI应用,但市面上主流的Agent框架太臃肿、太耗资源。
  4. 需要快速迭代AI小工具的技术人员:比如产品经理、运营人员、科研人员,需要快速开发一个AI小工具来辅助工作,但不想花太多时间在复杂的框架学习上。

前置知识

阅读本文前,你需要具备以下基础知识或技能:

  1. Python编程基础:至少会用Python写个简单的脚本,懂点变量、函数、类、异常处理、JSON/YAML解析。
  2. 异步编程基础:知道什么是异步函数(async def)、什么是await,因为我们会用异步编程来提升LiteAgent的性能。
  3. 大模型基础:对大模型的基本原理有一定了解(比如Transformer、Prompt Engineering),知道怎么调用OpenAI/通义千问的API,或者怎么用Ollama在本地运行量化大模型。
  4. 向量检索基础:知道什么是向量、什么是向量数据库、什么是相似度检索——如果不知道也没关系,我们会在第二部分简单讲解。
  5. Git/GitHub基础:知道怎么克隆Git仓库、怎么安装依赖库——我们会提供完整的源代码和配置文件。

文章目录

  1. 第一部分:引言与基础
    1.1 引人注目的标题
    1.2 摘要/引言
    1.3 目标读者与前置知识
    1.4 文章目录
    1.5 问题背景与动机
    1.6 单Agent的核心概念与理论基础
    1.7 问题演变发展历史
  2. 第二部分:LiteAgent架构的核心实现
    2.1 LiteAgent架构的设计原则
    2.2 环境准备
    2.3 核心组件1:LLM推理引擎(LLMEngine)
    2.4 核心组件2:工具调用模块(ToolManager)
    2.5 核心组件3:短期记忆模块(ShortTermMemory)
    2.6 核心组件4:任务调度器(TaskScheduler)
    2.7 组装LiteAgent:轻量化PDF知识问答助手
  3. 第三部分:性能优化与功能扩展
    3.1 性能优化1:量化推理
    3.2 性能优化2:提示词压缩与模板化
    3.3 性能优化3:工具调用预筛选
    3.4 功能扩展1:替换核心组件
    3.5 功能扩展2:添加外部工具
    3.6 功能扩展3:修改任务逻辑
    3.7 部署方案
    3.8 最佳实践tips
    3.9 常见问题与解决方案(FAQ)
  4. 第四部分:总结与展望
    4.1 本章小结(全文总结)
    4.2 未来展望与扩展方向
    4.3 参考资料
    4.4 附录

1.5 问题背景与动机

(注:为了避免混淆,原结构中的“第一部分:引言与基础”的“5. 问题背景与动机”已调整为“1.5”;同理,后续结构中的编号会统一调整为连续的章节号)

在深入讲解单Agent的核心概念和LiteAgent架构的实现之前,我们有必要先搞清楚:为什么我们需要Agent?为什么我们需要单Agent?为什么我们需要轻量化的单Agent?

1.5.1 大模型应用的三次迭代

要回答这些问题,我们可以先回顾一下大模型应用的发展历史——从2022年11月ChatGPT发布到现在,短短不到2年的时间,大模型应用已经经历了三次迭代:

第一次迭代:Prompt + LLM API(2022.11-2023.05)

这是大模型应用的“萌芽期”——开发者们只需要写一个简单的Prompt,然后调用OpenAI的API,就能开发出各种各样的“增强版工具”:比如文案生成器、代码助手、翻译工具、聊天机器人等等。

特点

  • 开发成本极低:只需要几行Python代码,甚至不需要编程——用ChatGPT的网页版就能实现大部分功能。
  • 功能单一:只能处理输入输出的文本任务,无法调用外部工具,无法读取附件,没有记忆。
  • 适用场景有限:只能处理常识性问题、简单的文案生成、简单的代码补全——对于需要“多步推理”“调用外部工具”“使用私有数据”的场景,完全无能为力。

典型应用

  • 各种在线的文案生成器(比如秘塔写作猫、豆包写作)。
  • 各种在线的代码助手(比如GitHub Copilot的网页版、Cursor的早期版本)。
  • 各种个人定制的聊天机器人(比如用Streamlit+OpenAI API写的“我的私人顾问”)。
第二次迭代:RAG + LLM API(2023.05-2023.12)

这是大模型应用的“成长期”——开发者们发现,Prompt + LLM API的应用无法使用私有数据,而RAG(Retrieval-Augmented Generation,检索增强生成)技术可以解决这个问题:把私有数据(比如PDF文件、Word文档、内部知识库)转换成向量,存储在向量数据库里;当用户提问时,先从向量数据库里检索出相关的内容,然后把相关内容和用户的问题一起传给LLM,让LLM生成基于私有数据的答案。

特点

  • 解决了私有数据的问题:可以让LLM使用企业内部的知识库、产品手册、客户数据等等。
  • 开发成本有所提高:需要学习向量检索技术(比如Embedding模型、向量数据库),需要搭建RAG的管道。
  • 功能仍然有限:只能处理“基于私有数据的问答”任务,无法调用其他外部工具(比如发送邮件、查询数据库、生成图表),没有长期记忆,多步推理能力弱。

典型应用

  • 各种企业内部的知识问答助手(比如华为云的盘古知识助手、阿里云的通义百炼知识库)。
  • 各种在线的PDF阅读器+问答工具(比如ChatPDF、Claude PDF)。
  • 各种个人定制的知识库问答工具(比如用LangChain+Chroma+OpenAI API写的“我的论文助手”)。
第三次迭代:Agent(2023.12至今)

这是大模型应用的“成熟期”——开发者们发现,RAG + LLM API的应用仍然不够“智能”,无法完成需要“多步推理”“调用多个外部工具”“动态调整策略”的任务,而Agent技术可以解决这个问题:Agent是一个“能感知环境、能思考、能行动、能学习”的智能体——它可以接收用户的任务,把任务分解成多个步骤,调用必要的外部工具来完成每个步骤,根据工具的返回结果调整策略,最后生成最终的答案。

特点

  • 功能强大:可以完成各种各样的复杂任务,比如“读取产品手册PDF,然后查询内部数据库里的产品库存,最后给客户生成一份带FAQ和库存信息的使用指南”“监控某个API的状态,当异常时查询服务器日志,然后给运维人员发送报警邮件”。
  • 开发成本较高:需要学习Agent的核心概念(比如LLM推理引擎、工具调用模块、记忆模块、任务调度器),需要搭建Agent的架构。
  • 资源消耗大:市面上主流的Agent框架(比如LangChain、AutoGPT、CrewAI)功能确实强大,但架构臃肿、依赖库多达上百个,部署成本高。

典型应用

  • 各种企业内部的自动化办公助手(比如微软的Copilot Studio、Salesforce的Einstein Copilot)。
  • 各种在线的任务型Agent(比如AutoGPT的网页版、AgentGPT)。
  • 各种个人定制的自动化工具(比如用LangChain+OpenAI API写的“我的股票监控Agent”)。

1.5.2 现有Agent框架的局限性

虽然Agent技术已经进入了“成熟期”,市面上也有很多成熟的Agent框架,但这些框架在轻量化场景下仍然存在很大的局限性:

局限性1:架构臃肿,依赖库多

我们来看看市面上几个主流的Agent框架的依赖库数量和资源消耗:

  • LangChain:作为目前最流行的Agent框架,LangChain的依赖库多达150+个(截至2024年8月,LangChain的pyproject.toml里列出了120+个直接依赖,间接依赖更是多达300+个)——随便一个简单的LangChain项目就要占用2GB以上内存,加上量化模型可能要5GB+。
  • AutoGPT:AutoGPT的依赖库也多达100+个,而且它需要调用很多外部API(比如浏览器、搜索引擎、数据库),资源消耗更大——随便一个AutoGPT项目就要占用4GB以上内存,加上量化模型可能要8GB+。
  • CrewAI:CrewAI是专门针对多Agent协作设计的框架,依赖库也多达80+个——虽然它的架构比LangChain和AutoGPT稍微简洁一点,但对于单Agent场景来说,仍然太臃肿了——随便一个简单的CrewAI单Agent项目就要占用1.5GB以上内存,加上量化模型可能要4GB+。

这些框架对于“需要多Agent协作、需要复杂的向量检索链、需要自我迭代”的大型AI应用场景来说,确实是很好的选择;但对于“读取1份PDF生成FAQ”“监控某个API的状态并在异常时报警”“自动回复简单的客户邮件”这种轻量化、单任务的场景来说,反而增加了开发和维护的复杂度——你可能要花3天时间去读LangChain的文档,才知道怎么去掉那些不必要的依赖,而且部署成本也很高,根本跑不起在边缘设备、低成本云服务器上。

局限性2:功能冗余,难以定制

LangChain等框架为了通用性,封装了太多用不到的功能:

  • 多Agent协作:对于单Agent场景来说,完全用不到。
  • 复杂的向量检索链:比如LangChain的ConversationalRetrievalChainRetrievalQAWithSourcesChain——对于很多单Agent场景来说,只需要一个简单的“向量检索+LLM生成”的管道就行。
  • 长期记忆模块:比如LangChain的ConversationBufferMemoryConversationSummaryMemoryConversationBufferWindowMemory——对于很多短期任务的单Agent来说,只需要一个简单的“最近N条对话”的短期记忆就行。
  • 自我迭代模块:比如AutoGPT的“自我反思、自我改进”模块——对于很多确定性任务的单Agent来说,完全用不到。

这些冗余的功能不仅增加了框架的复杂度和资源消耗,还使得框架难以定制——你可能要花很多时间去修改框架的源代码,才能实现你想要的功能;或者你可能要被迫使用框架提供的功能,即使这些功能不符合你的需求。

局限性3:性能低下,响应慢

LangChain等框架的性能低下主要有以下几个原因:

  • 同步调用:很多框架默认使用同步调用,无法充分利用CPU和GPU的资源——比如当你调用向量数据库检索相关内容时,LLM推理引擎处于空闲状态;当你调用LLM推理引擎生成答案时,工具调用模块处于空闲状态。
  • 提示词冗余:很多框架的提示词模板很长,包含了很多用不到的信息——比如LangChain的ReActAgent的提示词模板就有2000+个token,这不仅增加了LLM的推理时间,还增加了API调用的成本。
  • 工具调用次数多:很多框架的Agent不会预筛选工具,而是会把所有可用的工具都传给LLM,让LLM自己选择——这不仅增加了LLM的推理时间,还可能导致LLM选择错误的工具。
  • 向量检索效率低:很多框架默认使用简单的向量相似度检索(比如余弦相似度),不会对向量数据库进行索引优化——这使得向量检索的时间随着数据量的增加而线性增长。

1.5.3 我们的需求:一个极简主义的单Agent架构

基于以上的问题背景和现有Agent框架的局限性,我们提出了一个极简主义的单Agent架构设计——LiteAgent架构,它需要满足以下几个核心需求:

需求1:架构极简,依赖库少
  • 核心组件只有4个:LLM推理引擎、工具调用模块、短期记忆模块、任务调度器——总代码量不超过500行Python代码。
  • 依赖库控制在10个以内:只使用最核心的依赖库,比如aiohttp(异步HTTP请求)、pydantic(数据验证)、numpy(向量运算)、faiss-cpu(轻量级向量数据库)、PyMuPDF(PDF读取)——这些依赖库都是轻量级的,安装速度快,资源消耗小。
需求2:易于定制和扩展
  • 松耦合设计:每个核心组件都是独立的,有明确的接口定义——你可以根据自己的需求替换任意一个核心组件,比如把LLM推理引擎从OpenAI换成Ollama再换成vLLM,把短期记忆模块从内存换成SQLite。
  • 简单的工具注册机制:你只需要用一个装饰器就能注册一个新的工具,不需要修改框架的源代码。
  • 简单的提示词模板机制:你只需要修改一个YAML文件就能修改提示词模板,不需要修改框架的源代码。
需求3:性能优异,资源消耗小
  • 异步调用:所有的核心组件都使用异步调用,充分利用CPU和GPU的资源——比如当你调用向量数据库检索相关内容时,LLM推理引擎可以同时处理其他任务。
  • 提示词压缩与模板化:我们会提供一个简单的提示词压缩与模板化机制,能让提示词的长度减少50%以上——这不仅能减少LLM的推理时间,还能减少API调用的成本。
  • 工具调用预筛选:我们会提供一个简单的工具调用预筛选机制,能让LLM只看到和当前任务相关的工具——这不仅能减少LLM的推理时间,还能提高工具选择的准确率。
  • 量化推理支持:我们会支持本地量化大模型(比如Llama 3 8B INT4、Llama 3 8B INT3),能让内存消耗降低50%以上——Llama 3 8B INT4只需4GB内存就能跑,INT3只需2.5GB。
需求4:易于部署
  • 支持Docker部署:我们会提供一个简单的Dockerfile,能让你一键部署LiteAgent应用——不需要安装任何依赖库,只需要Docker就行。
  • 支持边缘设备部署:我们会支持在树莓派、普通笔记本等边缘设备上部署LiteAgent应用——只需要2GB以上内存就行。
  • 支持低成本云服务器部署:我们会支持在1核2G、2核4G等低成本云服务器上部署LiteAgent应用——只需要4GB以上内存(如果用本地量化大模型的话),或者只需要512MB以上内存(如果用API大模型的话)。

1.6 单Agent的核心概念与理论基础

在深入讲解LiteAgent架构的实现之前,我们有必要先搞清楚单Agent的核心概念和理论基础——这将帮助你更好地理解LiteAgent架构的设计思路和实现代码。

1.6.1 什么是Agent?

Agent(智能体) 的概念最早可以追溯到20世纪50年代的人工智能领域——当时的科学家们提出了“通用人工智能(AGI)”的概念,认为Agent是一个“能感知环境、能思考、能行动、能学习”的智能体,能够像人类一样完成各种各样的任务。

不过,在当前的大模型应用落地过程中,我们所说的“Agent”并不是指“通用人工智能”,而是指**“基于大模型的任务型智能体”**——它的定义可以简化为:

Agent = LLM + 工具 + 记忆 + 任务调度器

换句话说,Agent是一个“由大模型驱动的、能调用外部工具、能记住历史对话、能自动完成用户指定任务”的智能程序。

1.6.2 单Agent和普通大模型应用的区别

很多初学者容易混淆“单Agent”和“普通大模型应用(Prompt + LLM API、RAG + LLM API)”——我们可以用一个简单的表格来对比它们的核心属性:

核心属性维度 普通大模型应用(Prompt + LLM API) 普通大模型应用(RAG + LLM API) 单Agent(LiteAgent架构)
核心组成 LLM推理引擎 + Prompt模板 LLM推理引擎 + Prompt模板 + RAG管道 LLM推理引擎 + 工具调用模块 + 短期记忆模块 + 任务调度器
是否能调用外部工具 ❌ 不能 ❌ 不能(只能调用RAG管道) ✅ 能(可以调用任意自定义的工具)
是否有记忆 ❌ 没有(每次对话都是独立的) ❌ 没有(或者只有简单的对话缓冲) ✅ 有(有明确的短期记忆模块)
是否能多步推理 ❌ 不能(只能处理单步任务) ❌ 不能(只能处理单步RAG任务) ✅ 能(可以把任务分解成多个步骤)
是否能动态调整策略 ❌ 不能(策略是固定的Prompt模板) ❌ 不能(策略是固定的RAG管道) ✅ 能(可以根据工具的返回结果调整策略)
架构复杂度 极低(几行代码) 中等(几十行代码) 低(几百行代码)
资源消耗 极低(只需调用API) 中等(需要向量数据库) 低(只需少量依赖库)
适用场景 常识性问题、简单的文案生成、简单的代码补全 基于私有数据的问答任务 任意单任务(特别是需要多步推理、调用外部工具的任务)

为了让你更直观地理解它们的区别,我们可以用一个实际场景来举例:

用户任务:读取我刚才上传的这份《华为Mate 60 Pro产品手册.pdf》,然后查询我们公司内部数据库里的Mate 60 Pro的库存信息(北京仓库有100台,上海仓库有50台,深圳仓库有200台),最后给客户生成一份带FAQ和库存信息的使用指南,FAQ至少要包含5个问题,使用指南的语言要简洁明了,符合我们公司内部的话术规范。

普通大模型应用(Prompt + LLM API)的处理流程:
  1. 用户把《华为Mate 60 Pro产品手册.pdf》上传到应用里。
  2. 应用尝试把PDF的内容提取出来,但发现PDF的内容太长了(比如有100页,100000+个token),超过了LLM的上下文窗口(比如GPT-4o-mini的上下文窗口是128K,但API调用的成本很高;通义千问4 Turbo Mini的上下文窗口是1M,但本地量化推理的成本很高)。
  3. 应用只能把PDF的前几页内容提取出来,然后传给LLM。
  4. LLM收到前几页的内容和用户的任务,然后说:“抱歉,我无法看到完整的产品手册,也无法查询你们公司内部的数据库,无法完成你的任务。”
普通大模型应用(RAG + LLM API)的处理流程:
  1. 用户把《华为Mate 60 Pro产品手册.pdf》上传到应用里。
  2. 应用把PDF的内容提取出来,分成多个小块(比如每块1000个token)。
  3. 应用把每个小块转换成向量,存储在向量数据库里。
  4. 用户提出任务。
  5. 应用把用户的任务转换成向量,然后从向量数据库里检索出和任务相关的几个小块(比如前5个最相关的小块)。
  6. 应用把检索到的小块、用户的任务、公司内部的话术规范一起传给LLM。
  7. LLM收到这些内容,然后生成一份带FAQ的使用指南——但FAQ里没有库存信息,因为RAG管道无法查询内部数据库。
  8. 用户看到使用指南后,说:“怎么没有库存信息?”
  9. 应用只能再添加一个查询内部数据库的功能,但这个功能是硬编码的,无法和RAG管道协同工作——用户需要先问产品手册的问题,再单独问库存信息,然后自己把它们整合起来。
单Agent(LiteAgent架构)的处理流程:
  1. 用户把《华为Mate 60 Pro产品手册.pdf》上传到应用里。
  2. 应用调用read_pdf工具,把PDF的内容提取出来,分成多个小块,转换成向量,存储在向量数据库里——这一步可以是用户触发的,也可以是Agent自动触发的。
  3. 用户提出任务。
  4. 任务调度器接收用户的任务,然后把任务传给LLM推理引擎,同时把短期记忆模块里的历史对话(如果有的话)也传给LLM推理引擎。
  5. LLM推理引擎收到任务、历史对话、公司内部的话术规范、所有可用的工具(read_pdfsearch_vector_dbquery_internal_dbgenerate_user_guide),然后开始思考:
    • 思考1:用户需要我生成一份带FAQ和库存信息的Mate 60 Pro使用指南。
    • 思考2:我需要先从产品手册里检索相关内容,用来生成FAQ和使用指南的主体部分。
    • 思考3:我需要再查询内部数据库里的Mate 60 Pro的库存信息。
    • 思考4:最后我需要把检索到的内容、库存信息、公司内部的话术规范整合起来,生成最终的使用指南。
  6. LLM推理引擎决定先调用search_vector_db工具,参数是“华为Mate 60 Pro的核心功能、使用方法、常见问题”。
  7. 工具调用模块接收LLM的工具调用请求,验证参数的合法性,然后调用search_vector_db工具。
  8. search_vector_db工具从向量数据库里检索出和参数相关的前10个小块。
  9. 工具调用模块把工具的返回结果传给LLM推理引擎,同时把这次工具调用的记录存入短期记忆模块
  10. LLM推理引擎收到检索到的内容,然后决定再调用query_internal_db工具,参数是“华为Mate 60 Pro的库存信息”。
  11. 工具调用模块接收LLM的工具调用请求,验证参数的合法性,然后调用query_internal_db工具。
  12. query_internal_db工具从内部数据库里查询出Mate 60 Pro的库存信息(北京仓库有100台,上海仓库有50台,深圳仓库有200台)。
  13. 工具调用模块把工具的返回结果传给LLM推理引擎,同时把这次工具调用的记录存入短期记忆模块
  14. LLM推理引擎收到库存信息,然后决定最后调用generate_user_guide工具,参数是“检索到的产品手册内容、库存信息、公司内部的话术规范”。
  15. 工具调用模块接收LLM的工具调用请求,验证参数的合法性,然后调用generate_user_guide工具——或者LLM推理引擎可以直接自己生成最终的使用指南,不需要调用工具。
  16. LLM推理引擎生成最终的使用指南,然后把结果传给任务调度器,同时把这次对话的记录存入短期记忆模块
  17. 任务调度器把最终的使用指南返回给用户。

从这个例子可以看出,单Agent的处理流程是“动态的、多步的、协同的”——它可以根据任务的需要,自动调用多个外部工具,根据工具的返回结果调整策略,最后生成最终的答案;而普通大模型应用的处理流程是“固定的、单步的、孤立的”——它只能处理固定的任务,无法调用多个外部工具,无法动态调整策略。

1.6.3 单Agent的核心理论基础:ReAct框架

LiteAgent架构的核心理论基础是ReAct(Reasoning + Acting)框架——这是Google Research在2022年10月提出的一个框架,它的核心思想是:让大模型在推理的同时,也能生成行动,然后根据行动的结果继续推理,直到完成任务

ReAct框架的工作流程可以用以下的公式来表示:
Thoughtt→Actiont→Observationt→Thoughtt+1→⋯→Final Answer \text{Thought}_t \rightarrow \text{Action}_t \rightarrow \text{Observation}_t \rightarrow \text{Thought}_{t+1} \rightarrow \dots \rightarrow \text{Final Answer} ThoughttActiontObservationtThoughtt+1Final Answer

其中:

  • Thoughtt\text{Thought}_tThoughtt:大模型在第ttt步的思考内容——它解释了大模型为什么要采取下一步的行动。
  • Actiont\text{Action}_tActiont:大模型在第ttt步的行动——它通常是调用一个外部工具,也可以是直接生成最终的答案。
  • Observationt\text{Observation}_tObservationt:大模型在第ttt步采取行动后得到的观察结果——它通常是外部工具的返回结果。
  • Final Answer\text{Final Answer}Final Answer:大模型生成的最终答案。

我们可以用一个简单的ReAct提示词模板来理解它的工作原理:

你是一个能帮助用户完成各种任务的智能助手。你可以使用以下工具:

{tools_description}

你的工作流程如下:
1. 首先,你需要思考如何完成用户的任务——把你的思考内容用 "Thought: " 开头。
2. 然后,你需要决定采取什么行动——行动可以是调用一个工具,也可以是直接生成最终的答案:
   a. 如果调用工具,把你的行动用 "Action: " 开头,工具的参数用 "Action Input: " 开头,参数格式必须是JSON。
   b. 如果直接生成最终的答案,把你的答案用 "Final Answer: " 开头。
3. 最后,你需要等待观察结果——如果调用了工具,观察结果就是工具的返回结果;如果直接生成了最终的答案,工作流程结束。
4. 重复以上步骤,直到生成最终的答案。

注意事项:
- 你的思考内容必须简洁明了,不要太长。
- 你的行动必须明确,不要模糊。
- 你的工具参数必须合法,符合工具的要求。
- 你的最终答案必须符合用户的要求。

历史对话:
{history}

用户当前的任务:
{query}

现在开始工作!

我们可以用刚才的实际场景来看看ReAct框架的具体工作流程:

你是一个能帮助用户完成各种任务的智能助手。你可以使用以下工具:

1. read_pdf: 读取本地或远程的PDF文件,把内容提取出来,分成多个小块,转换成向量,存储在向量数据库里。参数:{"file_path": "string,本地或远程的PDF文件路径"}
2. search_vector_db: 从向量数据库里检索和查询语句相关的内容。参数:{"query": "string,查询语句", "top_k": "int,可选,返回的最相关的内容数量,默认是5"}
3. query_internal_db: 查询公司内部数据库里的信息。参数:{"table_name": "string,数据库表名", "columns": "list,可选,要查询的列名,默认是所有列", "filters": "dict,可选,查询条件,默认是无"}
4. generate_user_guide: 根据提供的内容生成使用指南。参数:{"product_content": "string,产品相关的内容", "inventory_info": "string,库存信息", "speech_standard": "string,公司内部的话术规范", "faq_count": "int,可选,FAQ的数量,默认是5"}

你的工作流程如下:
...(省略)...

历史对话:
[
  {"role": "user", "content": "读取我刚才上传的这份《华为Mate 60 Pro产品手册.pdf》"},
  {"role": "assistant", "content": "Thought: 用户需要我读取《华为Mate 60 Pro产品手册.pdf》,我需要调用read_pdf工具。\nAction: read_pdf\nAction Input: {\"file_path\": \"./uploads/Huawei_Mate_60_Pro_Product_Manual.pdf\"}\nObservation: 已成功读取《华为Mate 60 Pro产品手册.pdf》,共提取了100页内容,分成了100个小块,转换成了向量,存储在向量数据库里。\nFinal Answer: 已成功读取《华为Mate 60 Pro产品手册.pdf》,你现在可以问我关于这款产品的任何问题了!"}
]

用户当前的任务:
读取我刚才上传的这份《华为Mate 60 Pro产品手册.pdf》,然后查询我们公司内部数据库里的Mate 60 Pro的库存信息(北京仓库有100台,上海仓库有50台,深圳仓库有200台),最后给客户生成一份带FAQ和库存信息的使用指南,FAQ至少要包含5个问题,使用指南的语言要简洁明了,符合我们公司内部的话术规范。

现在开始工作!

Thought: 用户需要我生成一份带FAQ和库存信息的Mate 60 Pro使用指南。我已经读取了产品手册,现在需要先从向量数据库里检索相关内容,用来生成FAQ和使用指南的主体部分;然后查询内部数据库里的库存信息;最后整合所有内容生成最终的使用指南。
Action: search_vector_db
Action Input: {"query": "华为Mate 60 Pro的核心功能、使用方法、常见问题", "top_k": 10}
Observation: [
  "华为Mate 60 Pro的核心功能包括:麒麟9000S芯片、卫星通话、可变光圈、鸿蒙4.0系统、5G网络(虽然官方没说,但实测支持)。",
  "华为Mate 60 Pro的卫星通话功能使用方法:打开‘卫星通信’APP,选择‘卫星通话’,按照提示校准卫星,然后就可以拨打卫星电话了。",
  "华为Mate 60 Pro的常见问题1:怎么开启5G网络?答:目前官方还没有明确说明,但实测可以通过‘设置-移动网络-移动数据-启用5G’来开启。",
  "华为Mate 60 Pro的常见问题2:卫星通话需要收费吗?答:需要,具体收费标准请咨询运营商。",
  "华为Mate 60 Pro的常见问题3:电池容量是多少?答:5000mAh。",
  "华为Mate 60 Pro的常见问题4:支持快充吗?答:支持,88W有线快充、50W无线快充、20W反向无线快充。",
  "华为Mate 60 Pro的常见问题5:屏幕尺寸是多少?答:6.82英寸。",
  "华为Mate 60 Pro的使用方法:开机后按照提示完成初始设置,然后就可以正常使用了。",
  "华为Mate 60 Pro的核心功能还包括:IP68级防水防尘、红外遥控、NFC功能。",
  "华为Mate 60 Pro的鸿蒙4.0系统的新功能包括:AI隔空手势、多机位拍摄、智能隐私保护。"
]
Thought: 我已经从向量数据库里检索到了相关内容,现在需要查询内部数据库里的Mate 60 Pro的库存信息。根据用户的提示,库存信息在内部数据库的‘product_inventory’表里。
Action: query_internal_db
Action Input: {"table_name": "product_inventory", "filters": {"product_name": "华为Mate 60 Pro"}}
Observation: [
  {"product_name": "华为Mate 60 Pro", "warehouse": "北京仓库", "quantity": 100},
  {"product_name": "华为Mate 60 Pro", "warehouse": "上海仓库", "quantity": 50},
  {"product_name": "华为Mate 60 Pro", "warehouse": "深圳仓库", "quantity": 200}
]
Thought: 我已经查询到了库存信息,现在需要整合所有内容(检索到的产品手册内容、库存信息、公司内部的话术规范)生成最终的使用指南。公司内部的话术规范应该是‘语言简洁明了,避免使用过于专业的术语,突出产品的核心优势’——虽然用户没有明确给出,但根据常识可以推断出来。
Final Answer: (这里是最终的使用指南,省略具体内容)

从这个例子可以看出,ReAct框架的核心优势是“可解释性强、可控性高、多步推理能力强”——你可以清楚地看到大模型的思考过程和行动过程,如果大模型犯了错误,你也可以很容易地定位到错误的原因(比如思考内容不对、行动不对、工具参数不对)。

1.6.4 单Agent的核心概念结构与核心要素组成

我们可以用一个简单的ER实体关系图(Mermaid架构图)来表示单Agent的核心概念结构与核心要素组成:

使用

使用

使用

使用

使用

管理

存储

交互

调度

AGENT

string

agent_id

Agent的唯一标识符

string

agent_name

Agent的名称

string

agent_description

Agent的描述

LLM_ENGINE

string

engine_id

LLM推理引擎的唯一标识符

string

engine_type

LLM推理引擎的类型(OpenAI、Ollama、vLLM等)

string

model_name

使用的模型名称

float

temperature

温度参数(控制生成内容的随机性)

int

max_tokens

最大生成token数

TOOL_MANAGER

string

manager_id

工具管理模块的唯一标识符

SHORT_TERM_MEMORY

string

memory_id

短期记忆模块的唯一标识符

int

max_history_length

最大历史对话长度

TASK_SCHEDULER

string

scheduler_id

任务调度器的唯一标识符

PROMPT_TEMPLATE

string

template_id

提示词模板的唯一标识符

string

template_name

提示词模板的名称

string

template_content

提示词模板的内容

TOOL

string

tool_id

工具的唯一标识符

string

tool_name

工具的名称

string

tool_description

工具的描述

json

tool_parameters

工具的参数定义(JSON Schema格式)

function

tool_function

工具的执行函数

CONVERSATION_RECORD

string

record_id

对话记录的唯一标识符

string

role

角色(user、assistant、tool)

string

content

内容

datetime

timestamp

时间戳

USER

string

user_id

用户的唯一标识符

string

user_name

用户的名称

从这个ER实体关系图可以看出,单Agent的核心要素组成包括:

  1. Agent实体:整个单Agent的核心,负责协调其他所有实体的工作。
  2. LLM推理引擎实体:负责大模型的推理工作,是Agent的“大脑”。
  3. 提示词模板实体:负责生成LLM推理引擎需要的提示词。
  4. 工具管理模块实体:负责管理所有可用的工具,是Agent的“手脚”。
  5. 工具实体:负责执行具体的任务,比如读取PDF、查询数据库、发送邮件。
  6. 短期记忆模块实体:负责存储最近的历史对话,是Agent的“短期记忆”。
  7. 对话记录实体:负责存储一条具体的对话记录。
  8. 任务调度器实体:负责和用户交互,调度Agent的工作。
  9. 用户实体:使用Agent的人。

1.6.5 单Agent的核心交互关系图

我们可以用一个简单的交互关系图(Mermaid架构图)来表示单Agent的核心交互关系:

渲染错误: Mermaid 渲染失败: Parse error on line 22: ...ction、Action Input、 ----------------------^ Expecting 'SPACE', 'NEWLINE', 'INVALID', 'create', 'box', 'end', 'autonumber', 'activate', 'deactivate', 'title', 'legacy_title', 'acc_title', 'acc_descr', 'acc_descr_multiline_value', 'loop', 'rect', 'opt', 'alt', 'par', 'par_over', 'critical', 'break', 'else', 'participant', 'participant_actor', 'destroy', 'note', 'links', 'link', 'properties', 'details', 'ACTOR', got '1'
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐