Agent Ⅱ 手搓一个Agent feat. Qwen-Agent

前言 上一篇文章介绍了关于Agent的一些相关内容,这篇文章来动手实现一个Agent。目前比较流行的Agent开发框架有很多,比如可视化的字节的扣子,还有代码实现的babyagi、AutoGPT,因为我用qwen用的比较多,正好我最近看到qwen也开源了一套框架,qwen-agents,封装了工具、助手和一些规划的方法,使用起来比较方便,那就用这套框架实现一个简单的Agent。 Agent设计开发 既然是Agent,那就让他做一个LLM不能直接实现的任务,我这边有一个北京的房价表格,我们可以让Agent帮我们分析一下房价,最后生成一个图标来展示每平米的价格。 因为这个任务需要多步骤才能实现,所以我们可以使用上篇文章中将的ReAct的思路,让模型自己规划任务,根据每一次的执行结果来调整任务,并且可以利用代码助手来帮助他实现目标。 先配置LLM,这里可以使用阿里的api,也可以使用第三方的api,只要与openAI库兼容就可以。我这里尝试了付费的qwen-max和免费的Qwen2-7B-Instruct。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 llm_cfg = { # 使用 DashScope 提供的模型服务: # 'model': 'qwen-max', # 'model_server': 'dashscope', # 'api_key': 'EMPTY', # 如果这里没有设置 'api_key',它将读取 `DASHSCOPE_API_KEY` 环境变量。 # 使用与 OpenAI API 兼容的模型服务,例如 vLLM 或 Ollama: 'model': 'alibaba/Qwen2-7B-Instruct', 'model_server': 'http://localhost:8000/v1', # base_url,也称为 api_base 'api_key': 'EMPTY', # (可选) LLM 的超参数: 'generate_cfg': { 'top_p': 0.8 } } 然后去定义我们的Agent,因为框架封装的很方便了,所以几行代码就可以实现。 ...

June 21, 2024

Agent Ⅰ Introduction

Overview 随着ChatGPT的流行,我们似乎觉得LLM能够帮我们解决任何问题,但是长时间使用下来,有一些问题LLM并不能很好的解决,比如我想让LLM基于一次考试后的全班试卷帮我统计某个班级的最高分、最低分、平均分,并且针对考试较差的学生提出针对性的建议。目前所有的LLM都无法直接做到,因为首先全班所有的试卷就已经够长了,LLM的上下文长度可能都不够,再就是LLM并不擅长做关于数字的内容,因为数字对于他来说就是token,他有可能并不清楚数字token之间的关系。 那这个问题怎么解决呢,那就是通过Agent来解决,我们让LLM作为大脑,让其拥有记忆功能来存储试卷内容,还可能让其调用工具,让其学会计算,对于他也不会的知识点,他还可以上网搜索学会了再来辅导学生。这是不是就有人工智能那味儿了。 Agent能够通过构建LLM与规划、记忆、工具和执行来完成复杂的任务,LLM在其中扮演的就是大脑的角色,通过将复杂任务进行拆解,并且通过调用工具和存储来逐一解决小任务,最终完成复杂的任务。Agent能够大大提升LLM的实用性,让其不仅仅是一个只会对话的模型,而是有了规划和思考的能力。 下图为Agent的构成的概要。 Memory 人类的大脑中有多种记忆模式,比如短期记忆,用于存储当下的一些信息,例如我们现在与人对话的上下文,还有长期记忆,用于存储我们的知识体系。Agent也是一样,短期记忆用于存储当前会话的上下文,一般通过模型的上下文窗口来解决,长期记忆用于存储知识库和历史行为,一般通过外部存储来解决。 短期记忆受模型上下文窗口限制,所以不会太长,随着上下文长度的增长,对于显存的占用也会同步增加,所以这部分我们尽量控制的短一些,如果是超长的上下文,我们也可以将其转换为长期记忆来存储。 长期记忆其实也就是RAG,我们通过外部向量存储知识库,可以快速检索和访问,因为向量库相对比较便宜,所以我们可以存储大量的知识以供Agent使用,并且向量库的内容我们还可以经常更新,让模型在不调整参数的同时就拥有了比较新的知识。 Planning 无反馈规划 对于复杂的任务将其进行拆解能够帮助Agent更好的进行执行。 对于LLM来说,他并不会主动将任务进行拆解,我们可以通过CoT(Chain of Though)让其进行拆解复杂任务,“let’s think step by step”就是一句魔法咒语,在prompt开头添加这句话,能够让模型分步骤解决问题,从而获得更高的准确率。 在CoT的基础上,还有ToT(Tree of Though)的方法,通过在每一步探索多个可能得路径,形成树状结构,再通过DFS或者BSF来评估每个步骤的有效性。 还有一种方法是LLM+P,也就是通过外部规划期来进行长期规划,这种方法先将问题转化为PDDL格式,然后利用规划期生成方案,最终将这一方案转换为自然语言。本质上,规划步骤被外包给外部工具,假设特定领域的 PDDL 和合适的规划器可用,这在某些机器人设置中很常见,但在许多其他领域并不常见。 有反馈规划 如果模型规划有问题也不能很好的解决复杂的问题,所以我们可以让Agent通过反馈来进行规划,以纠正以前的错误,这对于解决复杂的任务有着至关重要的作用,毕竟人类在解决复杂问题时也会通过复盘来迭代自己的方法。姚顺雨大佬的两篇论文就是解决这个问题。 ReAct通过结合特定任务的离散动作与语言描述,实现了LLM中融合推理和执行的能力。离散动作能够与现实环境进行交互,语言米哦啊哈苏则可能促进LLM产生基于自然语言的推理路径。这种策略不仅提高了LLM处理复杂问题的能力,还通过与外部环境直接交互,增强了模型在真实世界中的适应性和灵活性。 具体的就是通过一下prompt模板,让LLM思考其Though、Action、Observation。 1 2 3 4 Thought: ... Action: ... Observation: ... ... (Repeated many times) 下图可以看到使用ReAct后的效果,并且对比了只使用推理(reason)和只使用执行(act)的区别。在使用了推理+执行后,模型可以很好的规划这个任务,并且根据每一步的结果来规划下一步需要做什么,最终得到正确的答案。 传统的强化学习学习大量的训练样本和计算资源来让模型从错误中进行学习,Reflexion提出了一种新的框架,不通过更新模型的权重,而是通过自然语言的反馈来增强模型从错误中学习。 Reflexion有一个标准的RL设置,其中简历模型提供简单的二元奖励,动作空间遵守ReAct中的设置,其中特定于任务的动作空间通过语言进行增强,以实现复杂的推理步骤。每一次执行,执行者(Actor)都会基于观察状态生成文本和动作,执行后,评估者(Evaluator)会对执行者生成的内容计算奖励分数,自我反思模型(Self-reflection)会生成口头自我反思提示以协助执行者进行改进,对于效率低下的规划,因为会存储在长期记忆中,所以会被识别到一直没有完成,这时自我反思模型会考虑将其停止。 Tools 曾几何时,人们普遍认为“使用工具”是人和动物最大的区别,虽然现在人们不这么认为了,但是人类文明发展史很大程度上就是一部人类发明工具帮助人类做事情的历史。如果Agent也能像人类一样使用工具就能够大大提升LLM的能力范围。 比如LLM对数字不够敏感,可能很多加减法都会做错,但是如果他能够调用计算器,那多复杂的运算也能够准确的计算出来。还有很多工具,像是网页浏览、写代码、画图、调用API等等,都能够有效的提升LLM的能力。 以下是一些LLM使用工具的方法: MRKL(Modular Reasoning, Knowledge and Language)包含一组专家模块,LLM作为路由器将查询路由到最合适的专家模块。 TALM(Tool Augmented Language Models)和Toolformer都是对LLM进行微调,让其学会使用外部工具API。 ...

June 20, 2024