作业7 | 豆包MarsCode AI刷题

122 阅读6分钟
def solution(n, b, sequence):
    count = 0
    for i in range(n):
        sub_sum = 0
        for j in range(i, n):
            sub_sum += sequence[j]
            if sub_sum % b == 0:
                count += 1
    return count
```1.  **函数功能**

    -   这个函数的目的是计算给定序列`sequence`中,有多少个连续子序列的和能被`b`整除。

1.  **具体实现**

    -   首先初始化一个变量`count`为 0,用于记录满足条件的子序列的数量。

    -   外层循环`for i in range(n)`        -   这个循环用于确定子序列的起始位置。`i`从 0 开始,每次增加 1,直到`n - 1`    -   内层循环`for j in range(i, n)`        -   这个循环用于确定子序列的结束位置。`j``i`开始,每次增加 1,直到`n - 1`        -   在这个循环中,计算从`sequence[i]``sequence[j]`的子序列的和`sub_sum`        -   然后检查`sub_sum`是否能被`b`整除,如果能,则将`count`加 1。

    -   最后,函数返回`count`的值,即满足条件的子序列的数量。

  


在`if __name__ == "__main__"`部分:

  


-   定义了一个测试用例`sequence = [1, 2, 3]`,并调用`solution`函数,检查函数返回值是否等于 3。这是为了验证函数的正确性。

给我解释一下这段代码中count变量的作用

如何在Python中测试这段代码的正确性?

还有其他方法可以解决这个问题吗?每当你遇到这种需要模型做自主判断、自行调用工具、自行决定下一步行动的时候,Agent(也就是代理)就出场了。

![](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/5b4417960739485ba2d128091454a70c~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgcmF5YnVyc3Q=:q75.awebp?rk3s=f64ab15b&x-expires=1772032165&x-signature=sRVowJM%2FHw%2FWmuAiOT0zfNLGFM4%3D)

代理就像一个多功能的接口,它能够接触并使用一套工具。根据用户的输入,代理会决定调用哪些工具。它不仅可以同时使用多种工具,而且可以将一个工具的输出数据作为另一个工具的输入数据。

在LangChain中使用代理,我们只需要理解下面三个元素。

-   **大模型**:提供逻辑的引擎,负责生成预测和处理输入。
-   与之交互的**外部工具**:可能包括数据清洗工具、搜索引擎、应用程序等。
-   控制交互的**代理**:调用适当的外部工具,并管理整个交互过程的流程。

![](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/17a0156f67d24d5e9406e13a28f986e7~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgcmF5YnVyc3Q=:q75.awebp?rk3s=f64ab15b&x-expires=1772032165&x-signature=bU2lotdLdIQM%2FVPqAbX7g7hUEOQ%3D "代理接收任务后,会自动调用工具,给出答案")

上面的思路看似简单,其实很值得我们仔细琢磨。

这个过程有很多地方需要大模型自主判断下一步行为(也就是操作)要做什么,如果不加引导,那大模型本身是不具备这个能力的。比如下面这一系列的操作:

-   什么时候开始在本地知识库中搜索(这个比较简单,毕竟是第一个步骤,可以预设)?
-   怎么确定本地知识库的检索已经完成,可以开始下一步?
-   调用哪一种外部搜索工具(比如Google引擎)?
-   如何确定外部搜索工具返回了想要找的内容?
-   如何确定信息真实性的检索已经全部完成,可以开始下一步?

那么,LangChain中的代理是怎样自主计划、自行判断,并执行行动的呢?

## ReAct框架

这里我要请你思考一下:如果你接到一个新任务,你将如何做出决策并完成下一步的行动?

比如说,你在运营花店的过程中,经常会经历天气变化而导致的鲜花售价变化,那么,每天早上你会如何为你的鲜花定价?

也许你会告诉我,我会去Google上面查一查今天的鲜花成本价啊(**行动**),也就是我预计的进货的价格,然后我会根据这个价格的高低(**观察**),来确定我要加价多少(**思考**),最后计算出一个售价(**行动**)!

![](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/a6815cef2b7b4c4592a2d73a9cb64329~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgcmF5YnVyc3Q=:q75.awebp?rk3s=f64ab15b&x-expires=1772032165&x-signature=pdK%2FtH%2FJQ7utTlcZUGeAWSSqf%2Bs%3D "定价过程")

你看,在这个简单的例子中,你有观察、有思考,然后才会具体行动。这里的观察和思考,我们统称为推理(Reasoning)过程,推理指导着你的行动(Acting)。

我们今天要讲的 **ReAct 框架的灵感正是来自“行动”和“推理”之间的协同作用,这种协同作用使得咱们人类能够学习新任务并做出决策或推理**。这个框架,也是大模型能够作为“智能代理”,自主、连续、交错地生成推理轨迹和任务特定操作的理论基础。

先和你说明一点,此 ReAct 并非指代流行的前端开发框架React,它在这里专指如何指导大语言模型推理和行动的一种思维框架。这个思维框架是Shunyu Yao等人在ICLR 2023会议论文《[ReAct: Synergizing Reasoning and Acting in Language Models](https://link.juejin.cn/?target=https%3A%2F%2Farxiv.org%2Fpdf%2F2210.03629.pdf "https://arxiv.org/pdf/2210.03629.pdf")》(ReAct:在语言模型中协同推理和行动)中提出的。

这篇文章的一个关键启发在于:**大语言模型可以通过生成推理痕迹和任务特定行动来实现更大的协同作用**。

具体来说,就是引导模型生成一个任务解决轨迹:观察环境-进行思考-采取行动,也就是观察-思考-行动。那么,再进一步进行简化,就变成了推理-行动,也就是Reasoning-Acting框架。

其中,Reasoning包括了对当前环境和状态的观察,并生成推理轨迹。这使模型能够诱导、跟踪和更新操作计划,甚至处理异常情况。Acting在于指导大模型采取下一步的行动,比如与外部源(如知识库或环境)进行交互并且收集信息,或者给出最终答案。

ReAct的每一个推理过程都会被详细记录在案,这也改善大模型解决问题时的可解释性和可信度,而且这个框架在各种语言和决策任务中都得到了很好的效果。

下面让我们用一个具体的示例来说明这一点。比如我给出大模型这样一个任务:在一个虚拟环境中找到一个胡椒瓶并将其放在一个抽屉里。

在这个任务中,没有推理能力的模型不能够在房间的各个角落中进行寻找,或者在找到胡椒瓶之后不能够判断下一步的行动,因而无法完成任务。如果使用ReAct,这一系列子目标将被具体地捕获在每一个思考过程中。

![](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/49f7e5e64ddc46ed91f012e308fae001~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgcmF5YnVyc3Q=:q75.awebp?rk3s=f64ab15b&x-expires=1772032165&x-signature=UV2oJgb0vN2kVtmFc3QErGj9R2U%3D "通过 ReAct 思维框架,大模型成功找到胡椒瓶")

现在,让我们回到开始的时候我们所面临的问题。仅仅使用思维链(CoT)提示,LLMs能够执行推理轨迹,以完成算术和常识推理等问题,但这样的模型因为缺乏和外部世界的接触或无法更新自己的知识,会导致幻觉的出现。