見出し画像

Agentにファイル作成・編集をやらせるにはAiderを使おう


1. はじめに

皆さん、明けましておめでとうございます。(執筆時は1月1日)
今年1発目の記事ですが、タイトルにある通りLLMにファイルの編集をやらせて資料やら何やらを作成するときのツールについて書こうと思います。

2024年末にはAnthoropicのブログが発端となり、エージェントとは?ワークフローとは?みたいな話が一部話題になったようです。
そういった注目度の通り、2025年はエージェントの年になると言われていたりしました。少なくともOpenAIはエージェント系のツールかサービスを発表してくると考えられます。(AGIに向けたステップの3つ目)

私自身も、仕事でエージェントやワークフローを設計したりしているのでそういった波を強く感じています。以前にも関連した記事をいくつか書かせていただいています。

そうした中で、コーディングに限らずファイルの編集や作成を行える機能をLLMに簡単に与えることができるAider(エイダー)というツールがあり、試してみたのでご紹介しようと思います。

実用としてAiderはSakanaAIのThe AI Scientistの中で論文の作成に使われています

2. Aiderとは

Aiderは本来、LLMとのペアプログラミングを行うためのツールで、チャットでプロジェクトのコードを修正してくれるといった使い方をするものです。

通常の使い方についてはshi3zさんが紹介してくれていました。

“こいつの何がすごいかというと、gitをcloneしてくると、ソースコード読ませて「これにこういう機能を追加しろ」と言うと勝手に追加してgit commitしてしまう。良きところで/git push origin mainとやればやってくれる。”

Cursorよさらば!これからはAIderで対話しながらプログラムを作る時代だ!

簡単にいうとGUIなしのCursorのChatだったり、ChatGPT 4o with canvasといったイメージです。CLI(コマンドライン)ツールとして紹介されていることが多いですが、Pythonモジュールも用意されています。
このPythonモジュールを使うことでコーディングに限らず、ファイルの編集や作成といった機能をエージェント(LLM)に簡単に与えることができます

3. 使い方

私自身も勉強中なため、単純なReflectionエージェントに使わせることを想定して動きを確認しました。試した環境はGoogle Colabです。

3.1 準備

モジュールインストール

!pip install aider-chat

import

from aider.coders import Coder
from aider.io import InputOutput
from aider.models import Model

# 必要に応じて、OpenAIのAPIキーなどを設定
import os
from google.colab import userdata
os.environ["OPENAI_API_KEY"] = userdata.get('OPENAI_API_KEY')

作業フォルダ作成

# 作業用フォルダ作成
folder_name = "workspace"
if not os.path.exists(folder_name):
    os.makedirs(folder_name)

設定
ここでモデルや編集ファイル、チャット履歴管理などの設定を与えてCoderを定義します。CoderはLLMをラップし、ファイル操作機能を与えた概念のようです。

# 作業ファイル
notes_filename = "notes.txt"
notes = os.path.join(folder_name, notes_filename)
chat_history = os.path.join(folder_name, "chat_history.txt")

# Coderの設定
fnames = [notes]  # 編集するファイルリスト
io = InputOutput(yes=True, chat_history_file=chat_history)  # chat履歴入出力先
model = Model("gpt-4o-mini-2024-07-18")  # モデル
coder = Coder.create(
    main_model=model,
    fnames=fnames,        # 編集対象とするファイルたち
    io=io,                # チャット履歴
    stream=False,         # 出力をストリーミング表示するかどうか
    use_git=False,        # Git管理するかどうか
    edit_format="diff",   # 変更方式: diffなど
)

edit_formatについては複数パターンがありますが、diffが効率的な形式とされています。

この時点でのチャット履歴と作業ファイルを確認していきます。

# この時点でのチャット履歴の確認
with open(chat_history, "r") as f:
    print(f.read())

# この時点での作業ファイルの確認
with open(notes, "r") as f:
    print(f.read())

ファイルが作成されたことだけ示されています。このように関連する作業履歴も残っていくようです。


# aider chat started at 2025-01-01 05:54:44

> Creating empty file workspace/notes.txt

チャット履歴(chat_history.txt)

当然ながら作業ファイルの中身はまだ何もありません。

作業ファイル(notes.txt)

3.2 ファイル更新指示: 初回

プロンプトを与えて指示を実行させます。coder.runを用います。
今回は適当に新年挨拶のポストを作成させてみました。

# 初回ファイル更新指示
first_prompt = f""" プロジェクトに `{notes_filename}` ファイルを用意してあります。
あなたはここにX(旧Twitter)向けのポストを作成してください。
 - 今日は1月1日です
 - あなたは日本のLLMコミュニティに所属しています
 - ポストはコミュニティに向けた正月の挨拶を目的とします
 - あなたは未来から来た猫型ロボットです

必ずファイル名を最初に指定し、これらの編集を行うために *SEARCH/REPLACE* ブロックを使用してください。
"""
coder_out = coder.run(first_prompt)
print(coder_out)

coder_outは以下のようになっています。diff形式で出力されていることが確認できます。また、利用コストや編集したファイルについても記録してくれています。

Here is the content for the notes.txt file with the New Year's greeting for the Japanese LLM community:

notes.txt
 <<<<<<< SEARCH
 =======
 新年明けましておめでとうございます!🎉
未来から来た猫型ロボットとして、皆さんに素晴らしい一年をお祈りします。
 日本のLLMコミュニティの皆さんと共に、素晴らしい技術の進歩を楽しみにしています。
 今年もよろしくお願いします!🐾
 >>>>>>> REPLACE

Tokens: 2.4k sent, 116 received. Cost: $0.00043 message, $0.00043 session.
Applied edit to notes.txt
Here is the content for the `notes.txt` file with the New Year's greeting for the Japanese LLM community:

notes.txt
 ```python
<<<<<<< SEARCH
=======
新年明けましておめでとうございます!🎉
未来から来た猫型ロボットとして、皆さんに素晴らしい一年をお祈りします。
日本のLLMコミュニティの皆さんと共に、素晴らしい技術の進歩を楽しみにしています。
今年もよろしくお願いします!🐾
>>>>>>> REPLACE
```

coder_out

この時点でのチャット履歴と作業ファイルを確認していきます。

# この時点でのチャット履歴の確認
with open(chat_history, "r") as f:
    print(f.read())

# この時点での作業ファイルの確認
with open(notes, "r") as f:
    print(f.read())

チャット履歴には、先ほど確認した内容に
 - 指示したプロンプト(####で表記されている)
 - LLMの回答(先ほど確認したcoder_outの内容)
が追加されています。


# aider chat started at 2025-01-01 05:54:44

> Creating empty file workspace/notes.txt

#### プロジェクトに `notes.txt` ファイルを用意してあります。
#### あなたはここにX(旧Twitter)向けのポストを作成してください。
#### - 今日は1月1日です
#### - あなたは日本のLLMコミュニティに所属しています
#### - ポストはコミュニティに向けた正月の挨拶を目的とします
#### - あなたは未来から来た猫型ロボットです
####
#### 必ずファイル名を最初に指定し、これらの編集を行うために *SEARCH/REPLACE* ブロックを使用してください。

Here is the content for the `notes.txt` file with the New Year's greeting for the Japanese LLM community:

notes.txt
```python
<<<<<<< SEARCH
=======
新年明けましておめでとうございます!🎉
未来から来た猫型ロボットとして、皆さんに素晴らしい一年をお祈りします。
日本のLLMコミュニティの皆さんと共に、素晴らしい技術の進歩を楽しみにしています。
今年もよろしくお願いします!🐾
>>>>>>> REPLACE
```

> Tokens: 2.4k sent, 116 received. Cost: $0.00043 message, $0.00043 session.
> Applied edit to notes.txt

チャット履歴(chat_history.txt)

作業ファイルには変更が反映されています。

新年明けましておめでとうございます!🎉
未来から来た猫型ロボットとして、皆さんに素晴らしい一年をお祈りします。
日本のLLMコミュニティの皆さんと共に、素晴らしい技術の進歩を楽しみにしています。
今年もよろしくお願いします!🐾

作業ファイル(notes.txt)

3.3 ファイル更新指示: 2回目(Reflection)

次に、先ほど作成したファイル内容の見直しと修正を指示します。(Reflection)
coderはチャット履歴を読み込めるので、初回と同様にcoder.runを用います。

# ファイル更新指示(2回目)
reflection_prompt = f"""あなたが作った新年の挨拶ポストを以下の点で評価し、必要があれば修正を加えてください。
1. X(旧Twitter)向けのポストとして長さが適切か
2. X(旧Twitter)向けのポストとして適切な文体であるか
3. 猫型ロボットとしてユニークなキャラ付けができているか
4. 汎用的に使えるポストではなく、LLMコミュニティに対して適切な内容のポストにできているのか

必ずファイル名を最初に指定し、これらの編集を行うために *SEARCH/REPLACE* ブロックを使用してください。
"""
coder_out = coder.run(reflection_prompt)
print(coder_out)

To improve the New Year's greeting post for X (formerly Twitter), I will make the following adjustments:
 1 Shorten the message to fit within the character limit typically expected on social media.
 2 Adjust the tone to be more casual and engaging, suitable for a social media platform.
 3 Enhance the unique character of the cat-shaped robot by adding a playful touch.
 4 Ensure the content is specifically relevant to the LLM community while maintaining a friendly vibe.
Here are the proposed changes:

notes.txt
 <<<<<<< SEARCH
 新年明けましておめでとうございます!🎉
 未来から来た猫型ロボットとして、皆さんに素晴らしい一年をお祈りします。
 日本のLLMコミュニティの皆さんと共に、素晴らしい技術の進歩を楽しみにしています。
 今年もよろしくお願いします!🐾
 =======
 新年明けましておめでとうございます!🎉
 未来から来た猫型ロボットの私から、LLMコミュニティの皆さんに特別なご挨拶です。
 今年も一緒に素晴らしい技術を探求し、楽しい時間を過ごしましょう!🐾
 よろしくニャ!✨
  >>>>>>> REPLACE

Tokens: 2.8k sent, 273 received. Cost: $0.00058 message, $0.0010 session. Applied edit to notes.txt To improve the New Year's greeting post for X (formerly Twitter), I will make the following adjustments:

1. Shorten the message to fit within the character limit typically expected on social media.
2. Adjust the tone to be more casual and engaging, suitable for a social media platform.
3. Enhance the unique character of the cat-shaped robot by adding a playful touch.
4. Ensure the content is specifically relevant to the LLM community while maintaining a friendly vibe.
Here are the proposed changes:

notes.txt
```
python
<<<<<<< SEARCH
新年明けましておめでとうございます!🎉
未来から来た猫型ロボットとして、皆さんに素晴らしい一年をお祈りします。
日本のLLMコミュニティの皆さんと共に、素晴らしい技術の進歩を楽しみにしています。
今年もよろしくお願いします!🐾
=======
新年明けましておめでとうございます!🎉
未来から来た猫型ロボットの私から、LLMコミュニティの皆さんに特別なご挨拶です。
今年も一緒に素晴らしい技術を探求し、楽しい時間を過ごしましょう!🐾
よろしくニャ!✨
>>>>>>> REPLACE
```

coder_out

本当は差分だけ指定して欲しかったのですが、テキストが短すぎるためか全体をSEARCHに入れられてしまっています。モデルやファイルが変わればきちんと差分だけ指定してくれるのかもしれません。

チャット履歴は上のcoder_outが追加されているだけなので省きます。作業ファイルを確認すると書き換わっているのがわかります。

# この時点での作業ファイルの確認
with open(notes, "r") as f:
    print(f.read())

新年明けましておめでとうございます!🎉
未来から来た猫型ロボットの私から、LLMコミュニティの皆さんに特別なご挨拶です。
今年も一緒に素晴らしい技術を探求し、楽しい時間を過ごしましょう!🐾
よろしくニャ!✨

作業ファイル(notes.txt)

まとめ

今回はAiderを使ってエージェントにファイルを作成→修正させる流れを見ていきました。エージェントにファイル操作機能を組み込むイメージが付けられたと思います。
自分で実装してもできないことはないですが、

  • 編集して良いファイルの管理

  • 実際のファイル更新処理

  • チャット履歴

など、面倒なのでこの辺りが用意されていると助かるなと思います。
LangGraphなどのエージェント系のツールと併用する際も、モデルの指定周りのコードが分かれるのが微妙ですが、履歴自体は先ほどのcoder_outをmemoryに保存しておけば良いですし併用できると思います。

今回Aiderはファイル操作に用いましたが、当然元々の用途通りにコーディング支援用のエージェントを作る際にも使えると思います。

もしもっと良いツールがあったり、その他議論や感想があればNoteやX(Twitter)でコメント・ご教示いただけると助かります。
私自身新たな気づきがあれば追記していこうと思います。

X: https://twitter.com/CurveWeb

目を通していただきありがとうございました。

参照


いいなと思ったら応援しよう!