背景
最近在探索新方向的时候,发现一个项目:Composio, 它是为AI Agent准备的生产完备的工具集,可以和一些主流的agent框架进行结合,让agent具备更加强大的能力。按之前的视角来划分,应该属于应用层的。看了下项目的介绍,感觉还是蛮有意思的,准备使用其skekit(SWE Development Kit,一个使用 Composio 的工具生态系统构建软件工程代理的强大框架。)构建一个应用体验下,但部署的过程中遇到一些问题,在网上没有找到相应的答案,因此在这里记录一下。
目标
运行起官方的skekit的demo, 通过Composio构建工具集来针对指定仓库指定issue提交一个解决方案。
环境
- windows11
- Docker
- conda
- WSL
问题定位
按官方文档流程操作,最后运行时会遇到一个问题:超时。
其实从错误信息看,http超时了,第一反应是拉一些库超时了,是不是要换源?但仔细点看,它拉的是localhost。拉本地超时?为什么会调用到本地?
查看源码及文档发现,官方给的默认代码的逻辑是会在本地起一个docker service, 然后Agent对外的实际调用是通过对docker service的调用完成的。关于为什么要用docker service 而不是直接在本地起一个服务,官方文档中的说法是:
很粗略(只有一个Unsafe),其实并不太明确部署在本地会有什么影响。但从部署docker后的日志来看,大致能明白为什么要这么做。
从这个角度看,如果我们本地用conda环境,那其实本地部署应该也是也是ok的。
回到问题上,查看源码,定位发现是在检测依赖的时候发起的请求超时了:
def check_for_missing_dependencies(
self,
apps: t.Optional[t.Sequence[AppType]] = None,
actions: t.Optional[t.Sequence[ActionType]] = None,
tags: t.Optional[t.Sequence[TagType]] = None,
) -> None:
request = self._request(
endpoint="/validate",
method="post",
json={
"apps": list(map(str, apps or [])),
"actions": list(
map(str, filter(lambda x: not hasattr(x, "enum"), actions or []))
),
"tags": list(map(str, tags or [])),
},
timeout=600 ,
)
if request.status_code != 200:
raise ComposioSDKError(f"Error installing dependencies: {request.text}")
//.... 其他代码
可以看到,这里写死了超时时间,10min。这就意味着,检查是否缺失依赖花了很长时间,为什么会花这么长时间呢?看看检查依赖的逻辑
self.logger.info("Following apps/actions have missing dependencies")
for enum, dependencies in missing.items():
self.logger.info(f"• {enum}: {dependencies}")
self.logger.info("Installing dependencies...")
for dependencies in missing.values():
for dependency in dependencies:
if dependency in installed:
continue
args = [
sys.executable,
"-m",
"pip",
"install",
"--disable-pip-version-check",
dependency,
]
if "git+https" in dependency:
args.append("--force-reinstall")
self.logger.info(f"Installing {dependency}")
output = subprocess.check_output(args=args).decode("utf-8")
if (
"Successfully installed" not in output
and "Requirement already satisfied" not in output
):
raise ComposioSDKError(message=f"Error installing {dependency}")
installed.add(dependency)
self.logger.info(f"Installed {dependency}")
add_package_to_installed_list(name=dependency)
这段逻辑大致意思是,检查环境是否缺失,如果缺失,使用pip install进行安装。那会不会有什么安装比较耗时的依赖呢?观察docker日志,可以发现,有个sentence-transformer的库,这个库手动拉起来是比较耗时的。手动在容器中拉一下可以看到:
即使是使用了阿里云的源,也要将近10min,这还只是这一个库,可能还有其他的依赖,10min还真不一定够。那么怎么解决呢?
解决思路
最简单的办法:修改超时时间,我们延长超时时间,从600s延长到1200s,保证有充足的时间拉好依赖。另外一个额外的方法是:修改拉取的镜像,使用国内可以快速使用的源。(后面这里的修改方式一直有点问题,可能是语法不对,后面暂时没有修改,感兴趣的可以继续尝试一下)
"--index-url https://pypi.tuna.tsinghua.edu.cn/simple" // 清华源,也可以替换成其他源
注意:这里有一个小坑的点:entrypoint.sh文件需要调整下结尾的格式,在windows下默认会保存成CRLF,需要改成LF,否则docker会启动失败。报错:exec /root/entrypoint.sh: no such file or directory
部署更新
问题发现了,也有了修改的思路,并且简单的修改了下源码,接下来就是要重新部署。项目拉到本地,进入python/dockerfiles目录下,可以看到一堆的dockerfile和一个makefile文件,对于docker和make不熟悉的同学可能就要头疼了。(官方给了一个更新的方式,但并不好找)。更新命令:
make dev && docker tag composio/composio:dev composio/composio:latest
如果window下没有配置过linux环境,那么这个命令运行不起来, make没法执行。需要在windows上安装linux环境才能用。下面推荐一种简单的做法:
WSL
其实装docker的时候就已经装过了WSL, 这是一个在windows上模拟linux的虚拟环境。可以在powershell中运行命令
wsl --list --verbose
查看WSL的环境:
一般来说你的电脑上可能只能看到docker-desktop这个环境,而这个环境下又不是传统的linux环境,没有各种常用工具,所以可能需要安装一个linux环境,比如我这里的Ubuntu。
wsl -d Ubuntu-20.04
安装好之后,由于linux和window的挂载路径是不一样的,在WSL中,本地电脑上的路径挂载在/mnt 路径下,比如上面的路径,对应在WSL中的路径就如下所示:
Docker desktop配置
只是配好上面环境还不足以支撑命令的执行,上面的命令还会报docker命令找不到的错误。这是因为在Ubuntu的WSL环境中没有安装过docker, 但我们本地其实有了docker desktop, 那么需要把他们联动起来。在docker desktop的配置中,把环境集成到一起。
打包镜像
此时再运行命令,就可以重新打包镜像了。
并且打包好的镜像在docker desktop中可以看到,服务启动直接就能使用。
至此,问题解决。
运行
处理完成之后,代码成功的运行起来,答案生成过程如下:
最终的的效果是,成功的在仓库中针对单个issue提交了一个解决方案。
总结
本文以部署实现SWE demo为目标,定位了遇到的超时问题,并通过修改源码重新部署的方式进行了解决。希望能对此项目感兴趣但部署时遇到此问题的同学提供帮助。
转载请注明出处~