Skip to content

Commit

Permalink
Add notebook executor as service function and add codeact agent. (#231)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: wenhao <wenhao@U-J0P61NH2-2025.local>
  • Loading branch information
garyzhang99 and wenhao authored Aug 2, 2024
1 parent 9f01064 commit 5fb1129
Show file tree
Hide file tree
Showing 14 changed files with 833 additions and 4 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ the following libraries.
- <img src="https://img.alicdn.com/imgextra/i3/O1CN01SFL0Gu26nrQBFKXFR_!!6000000007707-2-tps-500-500.png" alt="new" width="30" height="30"/>[Conversation with Customized Tools](https://github.com/modelscope/agentscope/blob/main/examples/conversation_with_customized_services/)
- <img src="https://img.alicdn.com/imgextra/i3/O1CN01SFL0Gu26nrQBFKXFR_!!6000000007707-2-tps-500-500.png" alt="new" width="30" height="30"/>[Mixture of Agents Algorithm](https://github.com/modelscope/agentscope/blob/main/examples/conversation_mixture_of_agents/)
- <img src="https://img.alicdn.com/imgextra/i3/O1CN01SFL0Gu26nrQBFKXFR_!!6000000007707-2-tps-500-500.png" alt="new" width="30" height="30"/>[Conversation in Stream Mode](https://github.com/modelscope/agentscope/blob/main/examples/conversation_in_stream_mode/)
- <img src="https://img.alicdn.com/imgextra/i3/O1CN01SFL0Gu26nrQBFKXFR_!!6000000007707-2-tps-500-500.png" alt="new" width="30" height="30"/>[Conversation with CodeAct Agent](https://github.com/modelscope/agentscope/blob/main/examples/conversation_with_codeact_agent/)


- Game
- [Gomoku](https://github.com/modelscope/agentscope/blob/main/examples/game_gomoku)
Expand Down
4 changes: 4 additions & 0 deletions README_ZH.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,14 @@ AgentScope支持使用以下库快速部署本地模型服务。
- [通过对话查询SQL信息](./examples/conversation_nl2sql/)
- [与RAG智能体对话](./examples/conversation_with_RAG_agents)
- <img src="https://img.alicdn.com/imgextra/i3/O1CN01SFL0Gu26nrQBFKXFR_!!6000000007707-2-tps-500-500.png" alt="new" width="30" height="30"/>[与gpt-4o模型对话](./examples/conversation_with_gpt-4o)
- <img src="https://img.alicdn.com/imgextra/i3/O1CN01SFL0Gu26nrQBFKXFR_!!6000000007707-2-tps-500-500.png" alt="new" width="30" height="30"/>[与自定义服务对话](./examples/conversation_with_customized_services/)

- <img src="https://img.alicdn.com/imgextra/i3/O1CN01SFL0Gu26nrQBFKXFR_!!6000000007707-2-tps-500-500.png" alt="new" width="30" height="30"/>[与SoftWare Engineering智能体对话](./examples/conversation_with_swe-agent/)
- <img src="https://img.alicdn.com/imgextra/i3/O1CN01SFL0Gu26nrQBFKXFR_!!6000000007707-2-tps-500-500.png" alt="new" width="30" height="30"/>[自定义工具函数](./examples/conversation_with_customized_services/)
- <img src="https://img.alicdn.com/imgextra/i3/O1CN01SFL0Gu26nrQBFKXFR_!!6000000007707-2-tps-500-500.png" alt="new" width="30" height="30"/>[Mixture of Agents算法](https://github.com/modelscope/agentscope/blob/main/examples/conversation_mixture_of_agents/)
- <img src="https://img.alicdn.com/imgextra/i3/O1CN01SFL0Gu26nrQBFKXFR_!!6000000007707-2-tps-500-500.png" alt="new" width="30" height="30"/>[流式对话](https://github.com/modelscope/agentscope/blob/main/examples/conversation_in_stream_mode/)
- <img src="https://img.alicdn.com/imgextra/i3/O1CN01SFL0Gu26nrQBFKXFR_!!6000000007707-2-tps-500-500.png" alt="new" width="30" height="30"/>[与CodeAct智能体对话](https://github.com/modelscope/agentscope/blob/main/examples/conversation_with_codeact_agent/)


- 游戏
- [五子棋](./examples/game_gomoku)
Expand Down
1 change: 1 addition & 0 deletions docs/sphinx_doc/en/source/tutorial/204-service.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ The following table outlines the various Service functions by type. These functi
| Service Scene | Service Function Name | Description |
|-----------------------------|----------------------------|----------------------------------------------------------------------------------------------------------------|
| Code | `execute_python_code` | Execute a piece of Python code, optionally inside a Docker container. |
| | `NoteBookExecutor.run_code_on_notebook` | Compute Execute a segment of Python code in the IPython environment of the NoteBookExecutor, adhering to the IPython interactive computing style. |
| Retrieval | `retrieve_from_list` | Retrieve a specific item from a list based on given criteria. |
| | `cos_sim` | Compute the cosine similarity between two different embeddings. |
| SQL Query | `query_mysql` | Execute SQL queries on a MySQL database and return results. |
Expand Down
1 change: 1 addition & 0 deletions docs/sphinx_doc/zh_CN/source/tutorial/204-service.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
| Service场景 | Service函数名称 | 描述 |
|------------|-----------------------|-----------------------------------------|
| 代码 | `execute_python_code` | 执行一段 Python 代码,可选择在 Docker <br/>容器内部执行。 |
| | `NoteBookExecutor.run_code_on_notebook` | 在 NoteBookExecutor 的 IPython 环境中执行一段 Python 代码,遵循 IPython 交互式计算风格。 |
| 检索 | `retrieve_from_list` | 根据给定的标准从列表中检索特定项目。 |
| | `cos_sim` | 计算2个embedding的余弦相似度。 |
| SQL查询 | `query_mysql` | 在 MySQL 数据库上执行 SQL 查询并返回结果。 |
Expand Down
166 changes: 166 additions & 0 deletions examples/conversation_with_codeact_agent/codeact_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
# -*- 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
"""
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

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


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
"""

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
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."""

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
Loading

0 comments on commit 5fb1129

Please sign in to comment.