OpenHands(旧OpneDevin)を使ってみた
はじめに
OpenHandsとは
Welcome to OpenHands, a platform for autonomous software engineers, powered by AI and LLMs (previously called "OpenDevin").
OpenHands agents collaborate with human developers to write code, fix bugs, and ship features.
最近OpenDevinからOpenHandsへと改名されたオープンソースのプラットフォームで、AIを活用したソフトウェア開発を支援することを目的としています。このプラットフォームは、開発者がアプリケーションを生成、修正、および管理する際に、AIエージェントを活用して、コード作成やデバッグ、さらにはアプリの展開までを自動化することができます。
実際に動いている様子はこちらから
特徴
- AIとのコラボレーション: OpenHandsのエージェントは人間の開発者と協力し、コード生成やバグ修正などのルーチン作業を自動化することで、生産性を向上させます。
- サンドボックス環境: プラットフォームは、安全なコード実行をサポートする隔離環境を提供し、システム全体への変更やセキュリティリスクを防止します。
- コミュニティ主導の開発: OpenHandsはコミュニティプロジェクトであり、世界中の開発者からの貢献を奨励しています。このオープンな協力によって、プラットフォームの進化と機能拡張が推進されています。
- 統合されたツールセット: Webブラウジングやコマンドライン操作、複数エージェントの協調作業をサポートするツールが統合されており、複雑なソフトウェアプロジェクトに対応できる多機能な環境です。
やってみた
環境構築
githubに環境構築の方法が記載されています。
git cloneしてきて以下のコマンドを実行するだけでOpenHandsの環境が立ち上がります
WORKSPACE_BASE=$(pwd)/workspace
docker run -it \
--pull=always \
-e SANDBOX_USER_ID=$(id -u) \
-e WORKSPACE_MOUNT_PATH=$WORKSPACE_BASE \
-v $WORKSPACE_BASE:/opt/workspace_base \
-v /var/run/docker.sock:/var/run/docker.sock \
-p 3000:3000 \
--add-host host.docker.internal:host-gateway \
--name openhands-app-$(date +%Y%m%d%H%M%S) \
ghcr.io/all-hands-ai/openhands:0.9
0.9: Pulling from all-hands-ai/openhands
Digest: sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Status: Image is up to date for ghcr.io/all-hands-ai/openhands:0.9
Starting OpenHands...
Setting up enduser with id 503
Docker socket group id: 0
root:x:0:
Group with id 0 already exists
Running as enduser
INFO: Started server process [36]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:3000 (Press CTRL+C to quit)
デフォルトだと 0.0.0.0:3000で立ち上がってくるんですね。
実際にアクセスしてみるとこんな感じの画面です。
実践
プロンプト入力で仕事の依頼
現状は日本語がサポートに入っていないので英語で指示を出してみます。
簡単なブログが投稿できるウェブページを作ってもらいます
Create a simple website where you can post blog articles
返答
タスク化された返答が順番に帰ってきます
返答内容に応じてこちらからの追加の支持や許可を出していきます。
Sure! Let's start by creating a Python file blog_app.py that will serve as the backend for our simple blog website. We will use Flask to create the web server.
First, let's create the blog_app.py file:
blog_app.pyを作成してFlask を使用して Web サーバーを立てるんですね。
指示に対してタスクを分解して1つずつ作業を進めていくようです。
Great! Now let's write the initial code for our Flask application in blog_app.py. This will include setting up the Flask app and creating a route to display a simple homepage where we can post blog articles.
I'll add the following code to blog_app.py:
Import Flask and create an instance of the Flask app.
Define a route for the homepage.
Run the app on port 5000.
Let's proceed with this:
bloga_app.pyにどのようなコードを記述するのかを説明してくれています。
The initial code for our simple blog website is now in place. Next, we need to ensure that Flask is installed in the environment. Let's install Flask and then run the application.
First, let's install Flask:
コードが書けたので次は環境のセットアップですね。
コードを実行するためにFlaskをインストールしようとしていますね。
Flask is already installed. Now, let's run the blog_app.py file to start the web server.
Flaskはもうインストール済みでした。
こういったことも1つ1つ報告してくれます。AIと一緒に開発をしているという感じがしますね。
The server is running on port 5000 with PID 362. You can access the blog website by visiting http://127.0.0.1:5000.
Would you like me to browse the homepage and show you the content?
なるほど!サーバーが立ち上がったようです。
ここまでのやりとりを画面で見るとこんな感じです。
では続きを進めてもらいましょう。
Continue
とてもシンプルなサイトが出てきましたね
I'm asking BrowsingAgent for help with this task.
BrowsingAgentというのを使用してwebページをチェックしていくようです。
In order to accomplish my goal, I need to navigate to the homepage of the newly started server and get its content.
先程立ち上げたページを見に行くようです
In order to accomplish my goal of browsing the homepage and showing the content, I need to review the current state of the page. The page has a heading "Simple Blog", a section with textboxes for "Title" and "Content", a "Post" button, and a heading "Posts".
Since I need to show the content of the homepage, I will read out the headings and the labels of the textboxes and button.
webページの内容を読み上げてくれるようです
The homepage has the following elements: Heading 'Simple Blog', a section with a textbox for 'Title', a textbox for 'Content', a 'Post' button, and a heading 'Posts'.
ちゃんと必要な要素があったことを確認できたようです。
All done! What's next on the agenda?
BrowsingAgent finishes task with content: The homepage has the following elements: Heading 'Simple Blog', a section with a textbox for 'Title', a textbox for 'Content', a 'Post' button, and a heading 'Posts'.
The homepage of the blog website is successfully displaying the following elements:
A heading "Simple Blog"
A section with a textbox for "Title"
A textbox for "Content"
A "Post" button
A heading "Posts"
You can now post blog articles by filling in the "Title" and "Content" fields and clicking the "Post" button.
If you have any further requests or modifications, please let me know! If everything is satisfactory, you can indicate that the task is complete.
依頼された仕事は完成したよ。webページにはこれらの要素を入れておいたよ。
他になにか追加で注文はあるか?
という感じでしょうか?
完成
実際に生成されたプログラムがこちら
from flask import Flask, request, render_template_string
app = Flask(__name__)
# In-memory storage for blog posts
posts = []
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
title = request.form['title']
content = request.form['content']
posts.append({'title': title, 'content': content})
return render_template_string('''
<h1>Simple Blog</h1>
<form method="post">
<input type="text" name="title" placeholder="Title" required><br>
<textarea name="content" placeholder="Content" required></textarea><br>
<button type="submit">Post</button>
</form>
<h2>Posts</h2>
{% for post in posts %}
<h3>{{ post.title }}</h3>
<p>{{ post.content }}</p>
{% endfor %}
''', posts=posts)
if __name__ == '__main__':
app.run(port=5000)
まとめ
大変面白い試みだと感じました。
まだまだ改善の余地が大きくうまく思ったように動作しない部分が多々ありますが、これからどんどん洗練されていきAIといっしょにプロダクト開発をするという日も見えてくるのかもしれません。
新しい技術であるため、OpenHandsにはバグや未完成の機能などの課題があります。
開発者コミュティが継続的にこれらの問題の解決にあたっています。
さらに改良されてより使い勝手の良いシステムへと改善されていく可能性が非常に高いのではないでしょうか。
Discussion