在开始我们就直接抛出今天的主题,介绍通过使用 aZent 框架如何创建一个团队来协作进行编码开发应用,这里分享 aZent 这个 agent 在对编码支持。
这里说的 Agent 是智能体,而不仅仅是 LLM 的代理,LLM 虽然现在已经可以理解人类的语言。这种能力通过大量数据的训练,突破临界而产生涌现的现象,具有了这种能力。据说已经具有了逻辑能力,不过对于这一点,这个是存疑的。 LLM 能力是有边界的,缺乏在某些领域的专业性,这些都是源于他是利用互联网产生的海量数据来训练的。而且对于复杂的任务,现在根据个人经验来看,LLM 还是束手无策,这是为什么需要 Agent 的原因。
Agent 是利用 LLM 对于语言的理解能力,通过一些方式来弥补 LLM 的不足,最大程度地挖掘 LLM 潜在的能力。不过希望在将来,LLM 只是作为 Agent 语言能力的支持。
看到副标题就不难想到 aZent 是脱离不了大环境的,将来可能也会成为那些流行 Agent 框架的竞争对手。虽然已经动笔开始写 aZent 的代码了,初期大部分代码和思想还是借鉴当下流行的 Agent 框架,例如 MetaGPT、autoGen 和 CrewAI 。而且还是刚刚开始实现核心模块,方向还没有确定,一切都是待定。设计也在不断随着学习、研究不断地调整,所以项目暂时在 github 上可见性还是 private。随着时间,项目设计逐渐稳定了和确定方向了,可以用他来解决一些日常工作的问题时候,自然而然就会和大家见面了,到时候也希望看到大家的更多的建议,当然更是希望各位大佬也能贡献代码来推动这个项目,我自己能力是非常有限的。 返回内容
想要有自己东西,首先最好途径就是借鉴和学习,关于生产代码个模块个人比较看好 autoGen,所以先把微软的 autoGen 关于这部分功能弄清楚后,在一步一步修改形成自己东西。
Certainly! Below is a simple Python program that prints "Hello, World!" to the console:
```python
# This is a traditional first program for many beginning programmers.
print("Hello, World!")
```
To run this program:
1. You need to have Python installed on your computer.
2. You save the code in a file with a `.py` extension, for
example, `hello_world.py`.
3. Then you run it from the command line by navigating to the directory containing the file and typing:
```bash
python hello_world.py
```
可以从 LLM 的 response 提取到代码部分,然后将代码和代码对应语言封装为 Codeblock,这里是将 LLM 文本通过实现 CodeExtractor 类接口方法 extract_code_blocks 来提取到一个 CodeBlock 的集合,接下来我们去定义 DockerCommandLineCodeExecutor 这个实现了 CodeExecutor 接口来将代码运行在 docker 上,并且返回执行结果,包括输出和返回值。
在开始整理代码之前,首先开始写测试代码,测试代码比较简单,就是专注测试 DockerCommandLineCodeExecutor 类的execute_code_blocks
这个方法接受一个 List[CodeBlock]
作为参数,关于 CodeBlock
这个类也比较简单,包含 code
和 language
两个字段,code
是要执行的代码,而 language
是代码所采用的语言
ini
from azentcoder.coding.docker_commandline_code_executor import DockerCommandLineCodeExecutor
from azentcoder.coding.base import CodeBlock
code_block_1 = CodeBlock(code="print('hello world')",language="python")
code_block_2 = CodeBlock(code="print(1+2)",language="python")
code_blocks = [code_block_1,code_block_2]
docker_commandline_codeexecutor = DockerCommandLineCodeExecutor()
res = docker_commandline_codeexecutor.execute_code_blocks(code_blocks)
print(res)
python
image: str = "python:3-slim",
container_name: Optional[str] = None,
timeout: int = 60,
work_dir: Union[Path, str] = Path("."),
auto_remove: bool = True,
stop_container: bool = True,
搭建 Docker 容器的命令环境,也就是通过终端来运行 Docker,然后在容器中执行代码文件,将代码块保存到工作目录下文件后,然后执行容器里面的包含代码块的文件,现在 executor 支持对 python 和 bash、shell 或者 sh 脚本支持。
- container_name 容器的名字
- timeout: 设置超时,默认值为 60
- work_dir: 要执行 python 文件会放置这个目录下
- image 镜像是可选的,默认值为 python:3-slim
- auto_remove 如果为 True docker 停止后自动移除文件
- stop_container 也就是 python 进程退退出后停止容器,默认值为 True
python
self._container = client.containers.create(
image,
name=container_name,
entrypoint="/bin/sh",
tty=True,
auto_remove=auto_remove,
volumes={str(work_dir.resolve()): {"bind": "/workspace", "mode": "rw"}},
working_dir="/workspace",
)
python
def execute_code_blocks(self, code_blocks: List[CodeBlock]) -> CommandLineCodeResult:
if len(code_blocks) == 0:
raise ValueError("No code blocks to execute.")
outputs = []
files = []
last_exit_code = 0
for code_block in code_blocks:
lang = code_block.language
code = code_block.code
code_hash = md5(code.encode()).hexdigest()
# print(code_hash)
first_line = code.split("\n")[0]
if first_line.startswith("# filename:"):
filename = first_line.split(":")[1].strip()
path = Path(filename)
if not path.is_absolute():
path = Path("/workspace") / path
path = path.resolve()
try:
path.relative_to(Path("/workspace"))
except ValueError:
return CommandLineCodeResult(exit_code=1, output="Filename is not in the workspace")
else:
# create a file with a automatically generated name
filename = f"tmp_code_{code_hash}.{'py' if lang.startswith('python') else lang}"
code_path = self._work_dir / filename
with code_path.open("w", encoding="utf-8") as fout:
fout.write(code)
command = ["timeout", str(self._timeout), _cmd(lang), filename]
result = self._container.exec_run(command)
exit_code = result.exit_code
output = result.output.decode("utf-8")
if exit_code == 124:
output += "\n"
output += TIMEOUT_MSG
outputs.append(output)
files.append(code_path)
last_exit_code = exit_code
if exit_code != 0:
break
code_file = str(files[0]) if files else None
return CommandLineCodeResult(exit_code=last_exit_code, output="".join(outputs), code_file=code_file)
如果 exit_code = 124 因为执行代码超时代码退出进程返回的 exit_code
python
if first_line.startswith("# filename:"):
filename = first_line.split(":")[1].strip()
path = Path(filename)
if not path.is_absolute():
path = Path("/workspace") / path
path = path.resolve()
try:
path.relative_to(Path("/workspace"))
except ValueError:
return CommandLineCodeResult(exit_code=1, output="Filename is not in the workspace")
else:
# create a file with a automatically generated name
filename = f"tmp_code_{code_hash}.{'py' if lang.startswith('python') else lang}"
这里重点了解一下 paht.resolve()
和 path.relative_to
的用法。