* 目次 [#ae8b0b60]
#contents
* 概要 [#e38ebfde]
AIでPCを操作できるということだ

通常のClaudeのチャットからは、メニューが見当たらない。

aiに、Computer useを使ってみたいと質問したところ以下のURLを紹介してもらえた

https://docs.anthropic.com/en/docs/build-with-claude/computer-use

(英文)

まだ、beta版のようである。(この記事を書いているのは、2024/10/25)

* 推奨スペック [#j5cc746f]
dockerでPC内に仮想PC入れる感じになるので、

本格的に使うのであれば、

32GBぐらいのRAMと、コア数の多めのPCを別途用意したほうが良さそうに思えた。

そうしないと、スワップ処理で、もっさり動作になってしまい。ほぼ停止しているかのような錯覚を感じた。


** デモのソースコード [#b81c330d]

https://github.com/anthropics/anthropic-quickstarts/tree/main/computer-use-demo

*** ご意見はこちら、、、だそうだ [#k997ddc5]

https://docs.google.com/forms/d/e/1FAIpQLSeD3IqITWsuepB19SEv889HsBvN9WOi6HRblPrJNyA9G7q02w/viewform

* セットアップ [#fe20dbe8]
** APIキーを用意 [#i6cde43e]
https://console.anthropic.com/dashboard


** Dockerを呼ぶ [#ud24ce95]
Docker本体のインストール手順は割愛する。他を見てほしい。

dockerが使える状態前提。


*** シェルの場合 [#jdaa2f50]
 export ANTHROPIC_API_KEY=%your_api_key%
 docker run \
     -e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
     -v $HOME/.anthropic:/home/computeruse/.anthropic \
     -p 5900:5900 \
     -p 8501:8501 \
     -p 6080:6080 \
     -p 8080:8080 \
     -it ghcr.io/anthropics/anthropic-quickstarts:computer-use-demo-latest


*** 実行結果 [#v78154d4]
 Xvfb started successfully on display :1
 Xvfb PID: 9
 starting tint2 on display :1 ...
 starting mutter
 starting vnc
 PORT=5900
 starting noVNC
 noVNC started successfully
 ✨ Computer Use Demo is ready!
 ➡️  Open http://localhost:8080 in your browser to begin

noVNCはオープンソースで開発されている、ブラウザ上で動作するHTML5製のVNCクライアントです。 このnoVNCをサーバー側にインストールして、HTTPサーバーで公開しておけば、クライアント側はブラウザでアクセスするだけでリモートデスクトップ環境を使えるようになります

ブラウザで、http://localhost:8080 を開いてみると、おそらくdockerのイメージだと思うが、dockerで立ち上げたであろうPCが立ち上がる。

dockerの中身を操作するだけならば、セキュリティは大丈夫そうだ。

&ref(claude_use_computer.png);

** 会話してみる [#s3bbefb7]
ブラウザで表示した上記の画面の左側のChat欄に、どのようなことができるのか質問したら、教えてくれた。

アカウントの作成やログイン関連については、手伝えないといわれた。

OSは何ですか?と聞いたところ以下の回答だった。

 Ubuntu 22.04.5 LTS

gitは、すでにインストール済みのようだ。

*** 言語のインストール状況 [#wb563b4a]

インストール済み:

- Python 3.11.6

pyenvを使用して管理されています

多数のPythonパッケージがインストールされています(numpy, pandas, streamlit, requests など)

未インストール:

- Node.js
- Java
- Go
- Ruby
- PHP

** vi [#f19f6b45]
テキストエディタのVIはインストールされていないようだ。

「viをインストールしてみて」

とお願いしてみた。できた。

「viのカラースキームをmonokaiにして」

とお願いしてみた。できた。日本語に対応してなかったので、まだ設定が必要そうだ




** CPUのプロセスが100%に! [#ke6eae66]
PCのメモリが16GBだと、ブラウザを立ち上げようとすると、固まってしまった。

VmmemVSLというプロセスがめちゃめちゃ占有している。

dockerがフリーズしてしまった。メモリを食いすぎ

PCにメモリはたくさん積んでおいたほうがいいだろう。

*** VmmemVSLのメモリ対策の記事 [#o27c5f04]

暫定対応

https://zenn.dev/quantum/articles/b29722e8795335

power shell用のコマンド

 # WSLに入るコマンド。すでにWSLに入っている場合は不要
 wsl
 
 # メモリをフラッシュするコマンド
 sudo sh -c "/usr/bin/echo 3 > /proc/sys/vm/drop_caches"


* 懸念点 [#r6760159]
チャットが複数セッションに分かれていないので、上限に来た場合にどうするのか?
長文のチャットだと会話の継続はできなくなってくるが、dockerでたちあげた環境に紐づいてしまっていると、チャットだけクリアすることはできるのだろうか?

自主的にどんどんファイルを更新してくれたりするのは頼もしいが、複雑になってくると、やらかしてしまった場合、戻る方法はどうするのだろうか? ソースコードならば、gitがインストールされているので、都度コミットしましょうというルールでいけそうだが、設定ファイルなどを改変されると、バックアップしていないと戻せなくなってしまう。


処理が進むと重くなってくる、となると、これを使った開発は、課題を1つ解決したらまたリセットして使う仕組みならば行けそうだ。

* 自分だったらこう使う。を考えてみた [#f8326c01]

AIとコラボ用にGitLabサーバを立てる

AI用に最低32GBのPCを用意する。

並列で作業させたい場合もあるから、もしかしたら複数台用意したほうがいいかもしれない

問題解決に近い環境をdockerのイメージを作る

- 日本語
- 言語の実行環境
- Git系の環境へのアクセス権
- gitのリポジトリをpullしてもらう

関連するファイルは自分で見に行ってもらうように指示する

Issue経由などで課題を与える

課題を手伝ってもらう

gitにコミットする

githabなどに pushする

不本意ながら、AIの処理できるトークン数に限界がくるので、次の課題に向けリセットし、上記の手順を
再度行う

* ローカルファイルをマウントするようにしてみる [#xfa7a4e6]
dockerで作業するのではなく、ホストマシンでgit cloneしたファイルを対象にすれば、いろいろと便利なのでは?と思った。

サンプルとして、以下を持ってきた。これはanthropicの公式をforkして、自分が好き勝手にできるようにしたリポジトリです。

 git clone https://github.com/khayashi4337/courses.git

目標は、github上の英語の資料を、ローカルに用意して、Couputer useにdocker-compose経由で連携し、翻訳できるかどうかチャレンジしてみるのです。そのまま、git に commitやpushできたら楽なので、ローカルの情報をどこまで持たせることができるのかも確認していきます。


ローカルファイルを使えるようにするには、Dockerfile形式ではなくdocker-compose形式が一般的だ。

なので、上記のコードをローカルファイルに変換してみます。

** ローカルのgitの設定を環境変数に入れておくbash [#m9bb7c41]

 # Git設定を確認して環境変数に設定
 export GIT_USER_NAME=$(git config --global user.name)
 export GIT_USER_EMAIL=$(git config --global user.email)
 
 # 設定された値を確認
 echo "Git User Name: $GIT_USER_NAME"
 echo "Git User Email: $GIT_USER_EMAIL"

** docker-compose.yml [#jffcd092]
 version: '3'
 services:
   anthropic:
     image: ghcr.io/anthropics/anthropic-quickstarts:computer-use-demo-latest
     environment:
       - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
       - GIT_USER_NAME=${GIT_USER_NAME}
       - GIT_USER_EMAIL=${GIT_USER_EMAIL}
     volumes:
       - ${HOME}/.anthropic:/home/computeruse/.anthropic
       - /c/Users/kh/prj/courses:/home/computeruse/courses  # サンプルとして追加したディレクトリ
       - /c/Users/kh/.ssh:/home/computeruse/.ssh:ro  # 読み取り専用
     ports:
       - "5900:5900"
       - "8501:8501"
       - "6080:6080"
       - "8080:8080"
     tty: true  # -it フラグの代わり
     stdin_open: true  # -it フラグの代わり


はいdocker-composeでも起動できました。.sshフォルダ丸ごと共有はお行儀がよくない気がするが、とりあえず実験用ってことにしておく。

これができるということは、今までできなかった以下のことができるようになったのです。

- AIが修正したコードをGitで管理できるようになった。つまり、修正した差分がどこなのかわかるようになった。長文のコードを出力してきて、修正部分と、既存のところはそのままという表現の区別がいらなくなった。もしくは、わかりやすくなった。理由はgit diffコマンドで緑色と赤色で区別されるようになるからだ。まだ、確認していないがきっとそうだ。

*** start-demo.sh [#q172430a]
毎回ブラウザでlocalhost:8080を開くのが面倒になってきたので、起動スクリプトを用意しました。

 #!/bin/bash
 
 docker-compose down
 
 # コンテナを起動
 docker-compose up &
 
 # 20秒待機(コンテナの起動を待つ)
 sleep 20
 
 # OSタイプに応じてブラウザを起動
 case "$OSTYPE" in
     "msys"*|"cygwin"*|"win"*)
         # Windows
         if command -v start &> /dev/null; then
             start chrome http://localhost:8080
         else
             cmd.exe /c start http://localhost:8080
         fi
         ;;
     "darwin"*)
         # macOS
         open -a "Google Chrome" http://localhost:8080
         ;;
     "linux-gnu"*)
         # Linux or WSL
         if grep -q Microsoft /proc/version; then
             # WSL環境
             cmd.exe /c start http://localhost:8080
         else
             # 通常のLinux
             if command -v google-chrome &> /dev/null; then
                 google-chrome http://localhost:8080
             elif command -v chrome &> /dev/null; then
                 chrome http://localhost:8080
             elif command -v chromium &> /dev/null; then
                 chromium http://localhost:8080
             else
                 xdg-open http://localhost:8080
             fi
         fi
         ;;
 esac

** 仮想PCの環境を改善できるかチャレンジしてみる [#t20a85d9]
Dockerファイルに、よくやる手順を追記する。

*** Dockerfile [#r96f55db]
以下をDockerfileとして保存する。手順を追加してある。

注意: 下記コード中のyou@example.comと、Your Nameは、各自のアカウントなどの設定に合わせてください。
以下のコマンドで確認できます。
 echo $(git config --global user.name)
 echo $(git config --global user.email)



 FROM ghcr.io/anthropics/anthropic-quickstarts:computer-use-demo-latest
 
 # 最初にrootユーザーとして実行することを明示
 USER root
 
 # 日本語環境のセットアップ
 RUN apt-get update && \
     apt-get install -y \
     language-pack-ja-base \
     language-pack-ja \
     locales \
     xclip && \
     xclip \
     vim && \
     locale-gen ja_JP.UTF-8 && \
     rm -rf /var/lib/apt/lists/*
 # デフォルトユーザー(computeruse)の.bashrcに日本語設定を追加
 USER computeruse
 RUN echo "export LANG=ja_JP.UTF-8" >> ~/.bashrc && \
     git config --global --add safe.directory /home/computeruse/courses && \
     git config --global user.email "you@example.com" && \
     git config --global user.name "Your Name"  
     git config --global user.name "Your Name"
     echo '# Gitブランチ表示の設定' >> ~/.bashrc && \
     echo 'parse_git_branch() {' >> ~/.bashrc && \
     echo '    git branch 2> /dev/null | sed -e "/^[^*]/d" -e "s/* \(.*\)/ (\1)/"' >> ~/.bashrc && \
     echo '}' >> ~/.bashrc && \
     echo 'export PS1="\u@\h:\w\[\e[32m\]\$(parse_git_branch)\[\e[00m\]\$ "' >> ~/.bashrc

 
 # システム全体のロケール設定
 ENV LANG=ja_JP.UTF-8 \
     LANGUAGE=ja_JP:ja \
     LC_ALL=ja_JP.UTF-8

*** docker-compose.yml [#l92535b5]

以下の、volumes:の設定項目は、各自が連携させたいディレクトリ名に置き換えること

 version: '3'
 services:
   anthropic:
     build:
       context: .
       dockerfile: Dockerfile
     environment:
       - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
       - GIT_USER_NAME=${GIT_USER_NAME}
       - GIT_USER_EMAIL=${GIT_USER_EMAIL}
     volumes:
       - ${HOME}/.anthropic:/home/computeruse/.anthropic
       - /c/Users/kh/prj/courses:/home/computeruse/courses
       - /c/Users/kh/.ssh:/home/computeruse/.ssh:ro
 
     ports:
       - "5900:5900"
       - "8501:8501"
       - "6080:6080"
       - "8080:8080"
     tty: true
     stdin_open: true

** 使い方 [#me9dc882]
Dockerfileを修正後、初回のみ
 docker-compose up --build
2回目以降は
 docker-compose up

* gitでの管理を手伝ってもらう。 [#n27ad2e7]
最初のコミットぐらいは、手動でもいいかな。でもdockerで立ち上げた仮想PC上でコマンドを入れてみる。
 git add . --all
 git commit -m 'first commit'

できた、自分の認証情報を与えているのでできるようになっている。

コンソールの日本語も適切に表示できている。

準備は整った。

今回は、練習として、英文のドキュメントがjupyter形式だったので、それをmarkdown形式にしてもらうというのを練習課題としてやってみようと思う。

ただし以下の縛りを付ける。

修正前にgitでブランチを切ること

作業が終わったらコミットすること


** 見どころ [#p2466675]

- 長文のドキュメントの修正に対応しているのかどうか?
- gitの操作を行いながら作業ができるかどうか。
- AIの仕事っぷりをgitのdiffを使ってレビューできるのかどうか?(一番これがやりたかった)

** gitで管理しているブランチのドキュメントを翻訳してもらう [#s15317fe]

では、やってみよう。

以下のようにお願いしてみた。

 以下のディレクトリ配下の
 /home/computeruse/courses 
 拡張子
 .ipynb
 のファイルをmarkdown形式に変換しコミット、さらに日本語にしてコミットしてください。
 
 
 
 作成するにあたって、gitのブランチを作成し、作業をお願いします。
 作業が完了したら、コミットをお願いします。
 
 まずは作業指示の認識確認のため、1つのファイルのみで作業を行ってください。


すると、claude sonnetは、こともあろうか、自分がforkしたリポジトリからブランチを切らずに、本家のほうからブランチを気って来た。。。まあ、そこで学習してたのだから、そうしたがるのはわかるが。。。。いけない。

タスクが複雑になると、ポンコツになってくるようなので、gitのコミットはさせないようにしたほうがよさそうだ。大量のタスクもやらせると、ろくでもない対応を横展開するので、NGな使い方だと思った。


* AIの処理が早すぎて、制限に引っかかる問題 [#ted4387a]
Tier1という契約レベルだと、1分間に50リクエスト超えると制限に引っかかる。1つのお願いだったとしても、AIが内部で数十回リクエストを消費してしまうのだ。


いろいろやろうとすると、リクエストの頻度が高いせいか以下のエラーになる。

 RateLimitError
 
 You have been rate limited. Retry after 0:01:31 (HH:MM:SS). See our API documentation for more details.

感覚的には、今のリミットの20倍ぐらい制限を緩和しないと、業務に使えないと感じた。

翻訳の依頼対象が30ファイルぐらいになることがわかって、こちらが意図しない作業を30個やってしまったあとに、「いやいやそうではない」と再度指示した段階で、「リクエストのリミットなんで、お休みします」となるわけだ。

技術的にはできるけれども、サービスデザイン起因の制限によってダメになっているというのは、実にもったいないことをしていると思った。

** 急がば回れ的なやり方がよさそう [#d0a316f9]
今までうまくいかなかったので、方針を変えよう。

とりあえず、1つのファイルを丁寧にやって、小さな成功体験を積ませるのが、近道かもしれない。

*** ipynbファイルをmdファイルに変換するツールを作ってもらった。 [#p84c4ad4]
人為的な制限のため、ある程度、自分でやるようにしないといけない。

ツール作ってもらって、処理はツールでやるなどして、リクエスト回数を減らす工夫が必要だ。


本当は、ipynbファイルを直接翻訳してもらおうとしたのだが、なぜかpythonライブラリを使おうとしてしまうので、だったら、ツール作ってもらおうと思って、以下を作ってもらった

- ipynb_to_md.py
 #!/usr/bin/env python3
 import sys
 import os
 import nbformat
 from nbconvert import MarkdownExporter
 
 def convert_ipynb_to_md(input_path, output_path=None):
     """
     Jupyter NotebookファイルをMarkdownファイルに変換する
     
     Args:
         input_path (str): 入力.ipynbファイルのパス
         output_path (str, optional): 出力.mdファイルのパス。指定がない場合は同じディレクトリに同名の.mdファイルを作成
     """
     try:
         # 出力パスが指定されていない場合、入力ファイルと同じディレクトリに.mdファイルを作成
         if output_path is None:
             output_path = os.path.splitext(input_path)[0] + '.md'
         
         # .ipynbファイルを読み込む
         with open(input_path, 'r', encoding='utf-8') as f:
             notebook = nbformat.read(f, as_version=4)
         
         # MarkdownExporterを初期化
         markdown_exporter = MarkdownExporter()
         
         # notebookをMarkdownに変換
         (body, resources) = markdown_exporter.from_notebook_node(notebook)
         
         # Markdownファイルとして保存
         with open(output_path, 'w', encoding='utf-8') as f:
             f.write(body)
         
         print(f"変換が完了しました: {output_path}")
         
     except Exception as e:
         print(f"エラーが発生しました: {str(e)}")
         sys.exit(1)
 
 def main():
     # コマンドライン引数をチェック
     if len(sys.argv) < 2:
         print("使用方法: python ipynb_to_md.py input.ipynb [output.md]")
         sys.exit(1)
     
     input_path = sys.argv[1]
     output_path = sys.argv[2] if len(sys.argv) > 2 else None
     
     # 入力ファイルの存在確認
     if not os.path.exists(input_path):
         print(f"エラー: 入力ファイル '{input_path}' が見つかりません。")
         sys.exit(1)
     
     # 変換を実行
     convert_ipynb_to_md(input_path, output_path)
 
 if __name__ == '__main__':
     main()

** .ipynbファイル一覧を出すプログラムも作ってもらった [#kedb3037]
- find_ipynb.py

 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 import os
 import glob
 import sys
 
 def find_ipynb_files(directory="."):
     """
     指定されたディレクトリ配下の.ipynbファイルを再帰的に検索して一覧表示する
     
     Args:
         directory (str): 検索を開始するディレクトリパス(デフォルトは現在のディレクトリ)
     """
     try:
         # 絶対パスに変換
         abs_directory = os.path.abspath(directory)
         
         # .ipynbファイルを再帰的に検索
         pattern = os.path.join(abs_directory, "**", "*.ipynb")
         ipynb_files = glob.glob(pattern, recursive=True)
         
         # 結果を標準出力に出力
         for file_path in ipynb_files:
             print(file_path)
             
     except Exception as e:
         print(f"エラーが発生しました: {str(e)}", file=sys.stderr)
         sys.exit(1)
 
 def main():
     # コマンドライン引数からディレクトリを取得(指定がない場合は現在のディレクトリを使用)
     directory = sys.argv[1] if len(sys.argv) > 1 else "."
     
     # ディレクトリの存在確認
     if not os.path.exists(directory):
         print(f"エラー: ディレクトリ '{directory}' が見つかりません。", file=sys.stderr)
         sys.exit(1)
     
     if not os.path.isdir(directory):
         print(f"エラー: '{directory}' はディレクトリではありません。", file=sys.stderr)
         sys.exit(1)
     
     # 検索を実行
     find_ipynb_files(directory)
 
 if __name__ == '__main__':
     main()

** 1つの修正が終わったら、dockerを再起動したほうがいいかもしれない。 [#gb1663d8]
おそらく、会話の履歴がたまってきたら、後半のリクエストって、前半のリクエスト全部をコストにしてしまっている感じがする。後半になるとリミット制限が、あっという間に来た。制限後の時間で1つのお願いをすると、すぐにリミットになったからそのような推測に至った。
いずれ、claude3.5のインターフェースのように新規チャット開始、みたいなインターフェースになるのだと思う
トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS