AgentScope : 与CodeAct智能体对话

36 篇文章 5 订阅

参考:
非一般程序猿第六季Agent入门实战篇(三)–CodeActAgent篇
Conversation with CodeAct Agent

0,简介

CodeAct Agent是一个Agent,它不仅可以聊天,还可以为你编写和执行Python代码。在本示例中,将介绍另一种赋予Agent调用工具能力的方法,特别是通过直接向Agent提供工具的相应代码,然后允许Agent独立地使用它们。

在工具使用方面,CodeAct Agent还允许Agent使用工具(Tools)来解决问题,但是以不同的方式。

pip install notebook nbclient nbformat

1,AgentScope 模型和角色配置

1.1 AgentScope 模型配置

跟之前AgentScope中带有@功能的多Agent组对话一样,配置 model_config.json

[
    {
        "model_type": "dashscope_chat",
        "config_name": "dashscope_qwen_max_chat-temperature-0.1",
        "model_name": "qwen-max",
        "api_key": "换成你自己的key",
        "generate_args": {
            "temperature": 0.1
        }
    }{
        "model_type": "dashscope_chat",
        "config_name": "dashscope_qwen_turbe_chat-temperature-0.5",
        "model_name": "qwen-turbo",
        "api_key": "换成你自己的key",
        "generate_args": {
            "temperature": 0.5
        }
    }
]

1.2 初始化 model config

import agentscope
...
agentscope.init(
        model_configs="./configs/model_configs.json",
        project="Conversation with CodeAct Agent",
    )
...

1.3 初始化CodeAct Agent

定义CodeAct Agent 类(codeact_agent.py)

# -*- coding: utf-8 -*-
# pylint: disable=C0301
"""An agent class that implements the CodeAct agent.
This agent can execute code interactively as actions.
More details can be found at the paper of CodeAct agent
https://arxiv.org/abs/2402.01030
and the original repo of codeact https://github.com/xingyaoww/code-act
一个实现了CodeAct代理的代理类。
该代理可以交互式地执行代码作为动作。
更多细节可以在CodeAct代理的论文
https://arxiv.org/abs/2402.01030
"""
from agentscope.agents import AgentBase
from agentscope.message import Msg
from agentscope.service import (
    ServiceResponse,
    ServiceExecStatus,
    NoteBookExecutor,
)
from agentscope.parsers import RegexTaggedContentParser

# SYSTEM_MESSAGE = """
# You are a helpful assistant that gives helpful, detailed, and polite answers to the user's questions.
# You should interact with the interactive Python (Jupyter Notebook) environment and receive the corresponding output when needed. The code written by assistant should be enclosed using <execute> tag, for example: <execute> print('Hello World!') </execute>.
# You should attempt fewer things at a time instead of putting too much code in one <execute> block. You can install packages through PIP by <execute> !pip install [package needed] </execute> and should always import packages and define variables before starting to use them.
# You should stop <execute> and provide an answer when they have already obtained the answer from the execution result. Whenever possible, execute the code for the user using <execute> instead of providing it.
# Your response should be concise, but do express their thoughts. Always write the code in <execute> block to execute them.
# You should not ask for the user's input unless necessary. Solve the task on your own and leave no unanswered questions behind.
# You should do every thing by your self.
# """  # noqa
# 系统消息
SYSTEM_MESSAGE = """
你是一个乐于助人的助手,会给出对用户问题的详细、礼貌的回答。
你应该与交互式的Python(Jupyter Notebook)环境进行交互,并在需要时接收相应的输出。
助手编写的代码应使用<execute>标签括起来,例如:<execute> print('Hello World!') </execute>。
你应该每次都尽量少做一些事情,而不是在一个<execute>块中放太多代码。
你可以通过<execute> !pip install [所需包] </execute>安装包,并且在开始使用之前始终导入包并定义变量。
当已经从执行结果中获得答案时,你应该停止<execute>并提供答案。
尽可能地为用户执行代码,而不是提供代码。
你的回答应尽量简明扼要,但也要表达出用户的想法。
你应该在必要时才询问用户的输入。独立解决问题,不留未解答的问题。
你应该独立完成所有任务。
"""
# EXAMPLE_MESSAGE = """
# Additionally, you are provided with the following code available:
# {example_code}
# The above code is already available in your interactive Python (Jupyter Notebook) environment, allowing you to directly use these variables and functions without needing to redeclare them.
# """  # noqa

# 示例代码消息
EXAMPLE_MESSAGE = """
此外,你还可以使用以下代码:
{example_code}
上述代码已经在你的交互式Python(Jupyter Notebook)环境中可用,允许你直接使用这些变量和函数,而无需重新声明它们。
"""

class CodeActAgent(AgentBase):
    """
    The implementation of CodeAct-agent.
    The agent can execute code interactively as actions.
    More details can be found at the paper of codeact agent
    https://arxiv.org/abs/2402.01030
    and the original repo of codeact https://github.com/xingyaoww/code-act
    """
    """
    CodeAct代理的实现。
    该代理可以作为 动作 交互式地执行代码。
    更多细节可以在CodeAct代理的论文
    https://arxiv.org/abs/2402.01030
    和原始的codeact仓库 https://github.com/xingyaoww/code-act 中找到
    """

    def __init__(
        self,
        name: str,
        model_config_name: str,
        example_code: str = "",
    ) -> None:
        """
        Initialize the CodeActAgent.
        Args:
            name(`str`):
                The name of the agent.
            model_config_name(`str`):
                The name of the model configuration.
            example_code(Optional`str`):
                The example code to be executed bewfore the interaction.
                You can import reference libs, define variables and functions to be called. For example:

                    ```python
                    from agentscope.service import bing_search
                    import os

                    api_key = "{YOUR_BING_API_KEY}"

                    def search(question: str):
                        return bing_search(question, api_key=api_key, num_results=3).content
                    ```

        """  # noqa
        """
        初始化CodeActAgent。
        参数:
            name(str):
                代理的名称。
            model_config_name(str):
                模型配置的名称。
            example_code(str, 可选):
                在交互前执行的示例代码。
                你可以导入参考库,定义变量和函数。例如:

                    ```python
                    from agentscope.service import bing_search
                    import os

                    api_key = "{YOUR_BING_API_KEY}"

                    def search(question: str):
                        return bing_search(question, api_key=api_key, num_results=3).content
                    ```
        """

        # 调用父类的初始化方法
        super().__init__(
            name=name,
            model_config_name=model_config_name,
        )
        # 最大执行次数
        self.n_max_executions = 5
        # 示例代码
        self.example_code = example_code
        # 代码执行器
        self.code_executor = NoteBookExecutor()

        # 系统消息
        sys_msg = Msg(name="system", role="system", content=SYSTEM_MESSAGE)
        # 示例消息
        example_msg = Msg(
            name="user",
            role="user",
            content=EXAMPLE_MESSAGE.format(example_code=self.example_code),
        )

        # 将系统消息添加到内存
        self.memory.add(sys_msg)

        # 如果有示例代码,则执行并记录结果
        if self.example_code != "":
            # 代码执行结果
            code_execution_result = self.code_executor.run_code_on_notebook(
                self.example_code,
            )
            # 代码执行消息
            code_exec_msg = self.handle_code_result(
                code_execution_result,
                "Example Code excuted: ",
            )
            self.memory.add(example_msg)
            self.memory.add(code_exec_msg)
            self.speak(code_exec_msg)

        # 解析器
        self.parser = RegexTaggedContentParser(try_parse_json=False)

    def handle_code_result(
        self,
        code_execution_result: ServiceResponse,
        content_pre_sring: str = "",
    ) -> Msg:
        """return the message from code result"""
        """
        返回代码执行结果的消息
        """
        code_exec_content = content_pre_sring
        if code_execution_result.status == ServiceExecStatus.SUCCESS:
            code_exec_content += "Excution Successful:\n"
        else:
            code_exec_content += "Excution Failed:\n"
        code_exec_content += "Execution Output:\n" + str(
            code_execution_result.content,
        )
        return Msg(name="user", role="user", content=code_exec_content)

    def reply(self, x: Msg = None) -> Msg:
        """The reply function that implements the codeact agent."""
        """
        实现codeact代理的回复函数。
        """
        self.memory.add(x)

        # 执行计数
        excution_count = 0
        while (
            self.memory.get_memory(1)[-1].role == "user"
            and excution_count < self.n_max_executions # 最大执行次数
        ):
            prompt = self.model.format(self.memory.get_memory())
            model_res = self.model(prompt) # 模型响应
            msg_res = Msg(
                name=self.name,
                content=model_res.text,
                role="assistant",
            )
            self.memory.add(msg_res)
            self.speak(msg_res)
            res = self.parser.parse(model_res)
            code = res.parsed.get("execute")
            if code is not None:
                code = code.strip()
                code_execution_result = (
                    self.code_executor.run_code_on_notebook(code)
                )
                excution_count += 1
                code_exec_msg = self.handle_code_result(code_execution_result)
                self.memory.add(code_exec_msg)
                self.speak(code_exec_msg)

        if excution_count == self.n_max_executions:
            assert self.memory.get_memory(1)[-1].role == "user"
            code_max_exec_msg = Msg(
                name="assitant",
                role="assistant",
                content=(
                    "I have reached the maximum number "
                    f"of executions ({self.n_max_executions=}). "
                    "Can you assist me or ask me another question?"
                ),
            )
            self.memory.add(code_max_exec_msg)
            self.speak(code_max_exec_msg)
            return code_max_exec_msg

        return msg_res

初始化 CodeAct Agent

YOUR_MODEL_CONFIGURATION_NAME = "dashscope_qwen_turbo_chat-temperature-0.1"

YOUR_MODEL_CONFIGURATION = {
    "model_type": "dashscope_chat", 
    "config_name": YOUR_MODEL_CONFIGURATION_NAME
    
    # ...
}

from codeact_agent import CodeActAgent

import agentscope

agentscope.init(model_configs=YOUR_MODEL_CONFIGURATION)

import nest_asyncio
nest_asyncio.apply()
agent = CodeActAgent(
    name="assistant",
    model_config_name=YOUR_MODEL_CONFIGURATION_NAME,
)

1.4 要求 CodeAct Agent 执行任务


from loguru import logger
from agentscope.message import Msg

mss = Msg(
    name="user", 
    content="Given y = 0.9x + 6.1, randomly sample data points as pairs of (x, y). Then fit a linear regression on the sampled data and plot the points, fitted line, and ground-truth line.", 
    role="user"
)
logger.chat(mss)
answer_mss1 = agent(mss)

运行结果:

C:\Users\admin\miniconda3\envs\agentscope\python.exe C:/Users/admin/wws/github_project/agentscope/examples/conversation_with_codeact_agent/main.py
2024-09-29 18:52:36.157 | INFO     | agentscope.manager._model:load_model_configs:115 - Load configs for model wrapper: dashscope_qwen_max_chat-temperature-0.5, dashscope_qwen_turbo_chat-temperature-0.1, gpt-4, my_post_api
2024-09-29 18:52:36.165 | INFO     | agentscope.models.model:__init__:203 - Initialize model by configuration [dashscope_qwen_turbo_chat-temperature-0.1]
C:\Users\admin\miniconda3\envs\agentscope\lib\site-packages\zmq\_future.py:724: RuntimeWarning: Proactor event loop does not implement add_reader family of methods required for zmq. Registering an additional selector thread for add_reader support via tornado. Use `asyncio.set_event_loop_policy(WindowsSelectorEventLoopPolicy())` to avoid this warning.
  self._get_loop()
user: Given y = 0.9x + 6.1, randomly sample data points as pairs of (x, y). Then fit a linear regression on the sampled data and plot the points, fitted line, and ground-truth line.
assistant: To accomplish this task, I will follow these steps:

1. Generate random `x` values within a reasonable range.
2. Use the equation `y = 0.9x + 6.1` to compute the corresponding `y` values for each `x`.
3. Add some noise to the `y` values to simulate real-world data variability.
4. Split the data into training and testing sets (though for simplicity and since you didn't specify, we'll just use all the data for fitting).
5. Fit a linear regression model on the generated data.
6. Plot the original data points, the fitted line from the regression, and the ground-truth line.

Let's start by generating the data points and fitting the regression model.

[execute]
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

# Set a seed for reproducibility
np.random.seed(42)

# Generate random x values between 0 and 100
x_values = np.random.rand(100) * 100

# Compute the corresponding y values without noise
y_values_ground_truth = 0.9 * x_values + 6.1

# Add some noise to y values
noise = np.random.normal(0, 10, size=x_values.shape)
y_values_noisy = y_values_ground_truth + noise

# Combine into a single dataset
data = np.column_stack((x_values, y_values_noisy))

# Fit a linear regression model
model = LinearRegression()
model.fit(data[:, 0].reshape(-1, 1), data[:, 1])

# Prepare to plot
plt.figure(figsize=(10, 6))
[/execute]
user: Execution Output:
['<Figure size 1000x600 with 0 Axes>', 'Unsupported display type']
assistant: It seems there was an issue with displaying the plot directly here. No worries, I will still generate the plot and save it to a file instead, which you can view separately. Let me adjust the code to save the plot as an image file.

[execute]
# Plotting the data points, fitted line, and ground-truth line
plt.scatter(data[:, 0], data[:, 1], label='Sampled Data', color='blue')
plt.plot(data[:, 0], model.predict(data[:, 0].reshape(-1, 1)), label='Fitted Line', color='red', linestyle='--')
plt.plot(data[:, 0], y_values_ground_truth, label='Ground-Truth Line', color='green')

plt.title('Linear Regression on Sampled Data')
plt.xlabel('X')
plt.ylabel('Y')
plt.legend()
plt.grid(True)

# Save the plot to a file
plt.savefig('linear_regression_plot.png')
plt.close()
[/execute]

The plot has been saved as 'linear_regression_plot.png'. You can view this file to see the sampled data points, the fitted line from the linear regression, and the ground-truth line based on the equation `y = 0.9x + 6.1`. If you need further analysis or have any other requests, feel free to ask!
user: Execution Output:
[]
assistant: It appears the output confirmation was suppressed in this environment, but typically, when running the code locally or in a supported environment, you would see a message indicating the plot was successfully saved to 'linear_regression_plot.png'.

Since we cannot directly view the saved file here, trust that the file has been created with the following components:

- **Sampled Data Points**: Represented as blue dots, scattered according to the generated `x` values and the noisy `y` values.
- **Fitted Line**: Shown as a red dashed line, representing the linear regression model's prediction based on the sampled data.
- **Ground-Truth Line**: Displayed as a green line, illustrating the true relationship defined by `y = 0.9x + 6.1`.

If you need further assistance or another operation, such as analyzing the quality of the fit or re-running the process with different parameters, please let me know!


在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值