Skip to content

Commit

Permalink
Merge pull request #2 from wj-Mcat/add-self-play-with-execution-paper…
Browse files Browse the repository at this point in the history
…-reading

update structure
  • Loading branch information
wj-Mcat authored Jul 16, 2024
2 parents 4515b5a + 94eb3d5 commit dc8ab95
Show file tree
Hide file tree
Showing 33 changed files with 292 additions and 88 deletions.
46 changes: 46 additions & 0 deletions agent-toolkit/uis/prompt-tester.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from jinja2 import Environment
from jinja2.parser import Parser
from jinja2.nodes import Name


def get_variable_names(content):
env = Environment()
parser = Parser(env, source=content)
stream = parser.parse()

variables = []
for node in stream.iter_child_nodes():
for sub_node in node.iter_child_nodes():
if isinstance(sub_node, Name):
variables.append(sub_node)
names = [item.name for item in variables]
return names

import gradio as gr

def greet(name):
return f"Hello, {name}!"

def survey(language):
if language == "Python":
return gr.components.Textbox(value="What do you like most about Python?")
elif language == "JavaScript":
return gr.components.Textbox(value="What do you like most about JavaScript?")
else:
return gr.components.Textbox(value="What do you like about programming?")

def submit(answer):
return f"Thanks for sharing! You said: {answer}"

with gr.Blocks() as demo:
with gr.Row():
language_choice = gr.components.Dropdown(["Python", "JavaScript", "Other"], label="What's your favorite programming language?")
survey_question = survey(language_choice)
with gr.Row():
answer = gr.components.Textbox(label="Answer")
submit_button = gr.components.Button("Submit")
submit_button.click(fn=submit, inputs=answer, outputs="output")

language_choice.change(fn=survey, outputs=survey_question)

demo.launch(debug=True)
84 changes: 49 additions & 35 deletions docs/00-agent-intro/00-what-is-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,70 +22,84 @@ slug: what-is-agent

老师首先需要给出所有学生的试卷得分细节,


## Memory

说的高级一点,就是智能体拥有长期记忆;说的Low 一点,就是把历史对话和开发者觉得重要的相关信息以一定格式塞入到 Prompt 当中,这样大模型就能够看到历史信息,此时便拥有了记忆
Agent中的记忆是智能体在处理任务、与用户交互以及从环境中获取信息时,能够存储和回忆这些信息的能力。这种记忆机制对于Agent理解环境、做出决策和从经验中学习至关重要。Agent中的记忆可以分为短期记忆和长期记忆两种类型,每种类型都有其特定的功能和实现方式

当然,这里`说的Low一点`仅仅是为了方便大家理解,并没有任何贬低的意思。
### 短期记忆(Short-Term Memory, STM)

当然,就好比如人类,记忆也分为长期记忆和短期记忆,并不是所有的内容都需要存放到记忆当中,毕竟记忆存储的空间是有限的。就好比如人类其实只能记忆一部分重要的内容,随着时间的流逝,很多曾经的美好都已忘却,甚至是曾经那个最重要人的生日。这些都不重要了,重要的是眼前这个人才是你接下来的人生路途中最重要的。
短期记忆主要负责处理当前任务相关的信息,包括会话上下文信息、临时变量、任务状态等。这些信息在Agent执行当前任务时非常关键,用于理解用户意图、跟踪任务进度和生成准确的回答。短期记忆的实现方式通常包括以下几种:
* 提示工程(Prompt Engineering):通过设计合适的提示,引导Agent在对话中记住关键信息,如用户提问和之前的响应,从而实现上下文理解。
* 内部状态管理:Agent在内部维护一个状态表示,用于存储当前任务的状态信息,如已选择的选项、处理中的变量等。

所以,记忆的内容是需要有选择性的,你可以让Agent 选择性的记忆不同的内容,根据记忆类型区分,可以将其分为两类:短期记忆、长期记忆。而这两类有点类似于思考快与慢当中的System1和System2。
### 长期记忆(Long-Term Memory, LTM)
长期记忆则用于存储历史数据和经验,为Agent提供知识基础。长期记忆可以包括事实、知识库、用户偏好、历史交互记录等,这些信息对于实现个性化服务和智能推荐至关重要。长期记忆的实现方式主要包括以下几种:

### 短期记忆
* 向量数据库:通过向量数据库进行外部向量存储和快速检索,实现长期记忆的保留和回忆。这种方式可以高效地存储和检索大量信息,支持Agent进行复杂的推理和决策。
* 知识库:构建结构化的知识库,包含各种领域的知识和规则,用于回答用户问题和提供推荐。知识库的内容可以抽象总结沉淀作为长期记忆的内容,提升模型的智能与个性化服务能力。
* 机器学习模型参数:通过训练机器学习模型(如推荐算法),将用户的历史行为和偏好作为长期记忆存储在模型的参数中。这种方式可以使Agent更加精准地理解用户需求,提供更加个性化的服务。

> Short-Term Memory
### 记忆管理
除了短期记忆和长期记忆的实现方式外,Agent还需要进行记忆管理,包括记忆的生成、存储、检索和遗忘等过程。这些过程共同构成了Agent的记忆机制,使其能够在处理复杂任务时更加智能和高效。

短期记忆的作用仅限于在执行某个任务时存在的记忆,一旦任务完成之后相关的记忆即可被清除。
* 记忆生成:Agent在感知和处理外部环境信息时,会根据任务需求生成相应的记忆条目。这些条目可能包括原始信息的存储、信息摘要或更高层次的抽象表示。
* 记忆存储:生成的记忆条目需要被存储在适当的介质中,以便后续检索和使用。对于短期记忆,通常存储在内部状态中;对于长期记忆,则可能存储在向量数据库或知识库中。
* 记忆检索:当Agent需要回忆某个信息时,会从存储介质中检索相应的记忆条目。这个过程可能涉及复杂的计算和匹配算法,以确保检索的准确性和效率。
* 记忆遗忘:为了节省存储空间和避免冗余信息干扰决策过程,Agent需要遗忘一些不重要或不相关的信息。遗忘机制的设计需要考虑信息的时效性和重要性等因素。

假如,你去医院挂号看医生,在等待的那段时间,你对医生的名字记忆非常深刻,甚至会产生一种本能反应:一旦听到这个医生的相关声音,此时就会竖起耳朵听。可是当你走出医院刷会儿手机之后,你还记得刚才那个医生的全名叫什么吗?
综上所述,Agent中的记忆是智能体处理任务、与用户交互和从环境中获取信息时不可或缺的能力。通过合理设计和实现短期记忆和长期记忆机制以及进行有效的记忆管理,可以使Agent更加智能、高效地完成任务并提供优质的服务。

几乎记不得,因为这个名字对于看完病之后的我们而言,并不重要,他的作用仅仅只体现在看病那个时间段
详细内容请看 [记忆模块](./01-memory.md)

Agent 中的记忆也是一样的,如果要完成一个复杂的任务,通常会将其拆分成不同的小任务来执行,在不同的小任务当中的记忆内容很可能是不一样的,而当所有的任务都技术之后,只需要将任务的需求描述和执行结果给出来即可,不需要包含每个小任务中的细节。
## Planing

所以,短期记忆你明白了吗?
Agent中的任务规划是指Agent根据任务目标、环境和自身能力,对复杂任务进行分解、组织、设定实现步骤的过程。这一过程是Agent高效执行复杂任务的关键组成部分,它涉及对任务的全面分析、子任务的划分、执行路径的规划等多个方面。以下是Agent中任务规划的详细解释:

### 长期记忆
### 定义

> Long-Term Memroy
任务规划是Agent基于已知的知识和规则,以及从环境中收集的数据,对复杂任务进行拆解、组织、设定实现步骤的过程。它帮助Agent组织思维、设定目标,并确定实现这些目标的具体行动方案。

那长期记忆也非常重要,可能会一直印在脑子里面的信息,比如说:你爸妈是谁,你是谁,1+1 等于多少 等相关信息。
### 核心内容

人的一生会很长,可能会包含很多很杂的信息,可是你的记忆容量是有限的,只能包含部分信息,所以此时你可以将记忆内容进行精简,从而达到能够记忆的目的:
任务分析:Agent首先需要对任务进行全面的分析,理解任务的目标、约束条件和执行环境。
子任务划分:将复杂任务拆分为多个更小、更易于管理的子任务。这些子任务之间可能存在依赖关系,需要按照一定的顺序或并行执行。
路径规划:为每个子任务规划执行路径,确定实现子任务的具体步骤和方法。这包括选择合适的工具、调用外部API等。
资源分配:根据任务需求和Agent的能力,合理分配资源,如计算资源、存储资源等。

1. Memory Summary:将一段时间内的记忆进行总结,归纳成一段话。
2. Important Memory:记住一段时间内的非常重要的人、事或者物。
3. RAG:将每段时间的记忆存储到数据库当中,方便后续检索,提取重点信息。
### 方法与框架

通过 Memory Summary 可以将大大减少记忆的存储长度,也不确实记忆的完整度;Important Memory 则是将重要的人、事或者物进行记录,属于高频重要信息;RAG 则可以有选择性的检索重点信息,提供给自己使用。
ReAct框架:此方法强调在执行下一步行动时加入大模型的思考过程,并将思考过程、执行工具及参数、执行结果放入提示词中,以提升模型的反思能力和问题解决能力。
其他方法:如Zero-Shot(零样本提示)、Few-Shot(小样本提示)、COT(思维链提示)等,这些方法通过不同的提示策略引导模型进行逐步推理和任务拆解。

这些方法能够让Agent在记忆管理方面像人一样工作,处理复杂的问题,进而为人类赋能。
### 重要性

## Planning
任务规划是Agent高效执行复杂任务的关键。通过合理的任务规划,Agent可以将复杂任务分解为多个简单子任务,降低执行难度;同时,通过路径规划和资源分配,确保任务能够按照预期目标顺利执行。此外,任务规划还有助于Agent在执行过程中进行自我反思和优化,提高任务执行的质量和效率。

任务规划是需要将一个复杂的问题拆分成多个简单的子问题,然后每个子问题也是可以继续规划进而让其对问题继续拆分,知道问题都被解决
总而言之,Agent中的任务规划是一个涉及任务分析、子任务划分、路径规划和资源分配等多个方面的复杂过程。通过合理的任务规划,Agent能够高效执行复杂任务,并在执行过程中不断优化自身表现

任务规划通常包含以下两个阶段:任务拆分和任务反思。
## Tool Use

### 任务拆分
Agent中的工具调用是指智能代理(AI Agent)在执行任务过程中,根据任务需求自动选择和执行适当的工具或服务的能力。在现代AI和机器学习领域,智能代理的概念已经广泛应用于多个场景,从自动化系统到智能家居,再到智能客服等。工具调用是智能代理核心能力之一,它使得代理能够处理更复杂、更具有适应性的任务。

任务拆分就是根据当前问题尝试将其拆分多个子问题,你可以认为输入是一个问题,输出是一些todo list,然后每个todo都需要下一个Agent 去完成。
### 定义

在任务拆分和任务执行的过程中,通常会使用 CoT 的相关技术来提升对于问题的的理解力,尽量将其模块化之后可以更好的生成 todo list。
* 工具定义:在AI Agent的上下文中,工具指的是模型可以调用的任何功能,它们允许Agent与外部数据源交互,通过拉取或推送信息到该源。这些工具可以是API、数据库、外部程序、第三方服务等。
* 调用过程:智能代理在执行任务时,会根据当前的状态和任务需求,从可用的工具集合中选择合适的工具进行调用。调用过程可能涉及参数配置、数据传递、执行监控和结果处理等多个环节。

当然,还有 Tree of Thought 可以对每个子问题进行递归拆分,直到问题被完全解决。
### 重要性

相关的方法介绍如下所示
工具调用目前是Agent中的基础能力之一,重要性无可厚非,于是从以下几个方面来展开描述工具调用的重要性

![agent planning](./imgs/agent-planning-methods.png)
* 扩展执行范围:通过调用外部工具,智能代理能够执行更多种类的任务,从而扩展其执行范围。
* 提高适应性:不同的任务可能需要不同的工具来处理,智能代理能够根据任务需求灵活选择工具,提高其在不同环境下的适应性。
* 增强性能:一些外部工具可能具有比智能代理本身更强大的处理能力,通过调用这些工具,智能代理能够完成更复杂、更高效的任务。

> 图片来源于:[A Survey on Large Language Model based Autonomous
Agents](https://arxiv.org/pdf/2308.11432)
### 应用场景

### 任务反思
现在绝大多数公司都在做商业落地,其中工具调用能够扩展 Agent 与外界进行交互的能力边界,具体场景如下所示:

一旦任务被拆分出来,此时需要判断:拆分之后的任务是否合理,能否解决问题。所以任务拆分是否正确此时至关重要,能进一步提升任务执行的准确度,这个阶段就称之为任务反思。
* 智能家居:智能代理可以根据用户的语音指令调用不同的家居设备(如灯光、空调、窗帘等),实现智能家居的自动化控制。
* 智能客服:智能代理可以调用知识库、对话管理模块和文本生成工具等,与用户进行自然语言交互,提供客服支持。
* 数据分析:在数据分析领域,智能代理可以调用数据库查询工具、数据可视化工具和机器学习模型等,自动完成数据分析任务并生成报告。

任务反思可以用LLM来进行反思,此时你可以写一套Prompt
Agent中的工具调用是智能代理在执行任务过程中自动选择和执行适当工具的能力,它对于扩展智能代理的执行范围、提高适应性和增强性能具有重要意义
46 changes: 46 additions & 0 deletions docs/00-agent-intro/01-memory.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
sidebar_position: 1
slug: memory-of-agent
---

# 记忆管理

说的高级一点,就是智能体拥有长期记忆;说的Low 一点,就是把历史对话和开发者觉得重要的相关信息以一定格式塞入到 Prompt 当中,这样大模型就能够看到历史信息,此时便拥有了记忆。

当然,这里`说的Low一点`仅仅是为了方便大家理解,并没有任何贬低的意思。

当然,就好比如人类,记忆也分为长期记忆和短期记忆,并不是所有的内容都需要存放到记忆当中,毕竟记忆存储的空间是有限的。就好比如人类其实只能记忆一部分重要的内容,随着时间的流逝,很多曾经的美好都已忘却,甚至是曾经那个最重要人的生日。这些都不重要了,重要的是眼前这个人才是你接下来的人生路途中最重要的。

所以,记忆的内容是需要有选择性的,你可以让Agent 选择性的记忆不同的内容,根据记忆类型区分,可以将其分为两类:短期记忆、长期记忆。而这两类有点类似于思考快与慢当中的System1和System2。

### 短期记忆

> Short-Term Memory
短期记忆的作用仅限于在执行某个任务时存在的记忆,一旦任务完成之后相关的记忆即可被清除。

假如,你去医院挂号看医生,在等待的那段时间,你对医生的名字记忆非常深刻,甚至会产生一种本能反应:一旦听到这个医生的相关声音,此时就会竖起耳朵听。可是当你走出医院刷会儿手机之后,你还记得刚才那个医生的全名叫什么吗?

几乎记不得,因为这个名字对于看完病之后的我们而言,并不重要,他的作用仅仅只体现在看病那个时间段。

Agent 中的记忆也是一样的,如果要完成一个复杂的任务,通常会将其拆分成不同的小任务来执行,在不同的小任务当中的记忆内容很可能是不一样的,而当所有的任务都技术之后,只需要将任务的需求描述和执行结果给出来即可,不需要包含每个小任务中的细节。

所以,短期记忆你明白了吗?

### 长期记忆

> Long-Term Memroy
那长期记忆也非常重要,可能会一直印在脑子里面的信息,比如说:你爸妈是谁,你是谁,1+1 等于多少 等相关信息。

人的一生会很长,可能会包含很多很杂的信息,可是你的记忆容量是有限的,只能包含部分信息,所以此时你可以将记忆内容进行精简,从而达到能够记忆的目的:

1. Memory Summary:将一段时间内的记忆进行总结,归纳成一段话。
2. Important Memory:记住一段时间内的非常重要的人、事或者物。
3. RAG:将每段时间的记忆存储到数据库当中,方便后续检索,提取重点信息。

通过 Memory Summary 可以将大大减少记忆的存储长度,也不确实记忆的完整度;Important Memory 则是将重要的人、事或者物进行记录,属于高频重要信息;RAG 则可以有选择性的检索重点信息,提供给自己使用。

这些方法能够让Agent在记忆管理方面像人一样工作,处理复杂的问题,进而为人类赋能。

如想了解更多更详细记忆相关的知识点,可查看 [记忆管理](./01-memory.md) 小节。
8 changes: 0 additions & 8 deletions docs/00-agent-intro/01-tool-usage.md

This file was deleted.

8 changes: 0 additions & 8 deletions docs/00-agent-intro/02-memory.md

This file was deleted.

38 changes: 38 additions & 0 deletions docs/00-agent-intro/02-tool-usage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
sidebar_position: 1
slug: tool-usage
---

# 工具使用

大多数的工具调用基于 [ReAct](https://arxiv.org/abs/2210.03629) 模板,可以让LLM 与外部工具进行交互,从而从一定程度上缓解幻觉问题、提升能力边界。

以下为ReAct 的示例:

```txt
query = Who is Olivia Wilde's boyfriend? What is his current age raised to the 0.23 power?
> Entering new AgentExecutor chain...
I need to find out who Olivia Wilde's boyfriend is and then calculate his age raised to the 0.23 power.
Action: Search
Action Input: "Olivia Wilde boyfriend"
Observation: Olivia Wilde started dating Harry Styles after ending her years-long engagement to Jason Sudeikis — see their relationship timeline.
Thought: I need to find out Harry Styles' age.
Action: Search
Action Input: "Harry Styles age"
Observation: 29 years
Thought: I need to calculate 29 raised to the 0.23 power.
Action: Calculator
Action Input: 29^0.23
Observation: Answer: 2.169459462491557
Thought: I now know the final answer.
Final Answer: Harry Styles, Olivia Wilde's boyfriend, is 29 years old and his age raised to the 0.23 power is 2.169459462491557.
> Finished chain.
```

工具调用目前属于LLM的基础能力,主流LLM和Agent框架都会集成此类能力。

Loading

0 comments on commit dc8ab95

Please sign in to comment.