LinuxとPythonとGitHubとDockerを学びながらLangChainの公式チュートリアルをやろうと思い立ち勉強し始めたブランク7年元オンプレWindowsCエンジニアの勉強メモ
はじめに
最近のAIをキャッチアップするため再び開発ができるようになりたい!と思い立ち、3ヶ月程度で最近の環境を学んでAIを使ったちょっとしたコードを書けるようになる!という目標を立てました。
これまでの経験
2017年までソフトウェアエンジニアをやっていました。
主に、Windows Serverで動作する全文検索エンジンの開発(Cとオレオレフレームワーク)や、そのサービスと通信するWindows COMのクライアントコンポーネント(C++とATL)の開発をしていました。ソース管理は伝説のVisual SourceSafeです。コンテナなんてものはなく、VirtualPCやVMwareやHyper-VでOSごと仮想化してました。他にもVBやVBAやVBScript、C#などの開発を経験し、仕事で最後に作ったのはWindowsのGUIアプリ(C#とWPF)です。
2018年以降は職種が変わり、仕事でコードを書く機会がなくなりました。趣味でもDeepLearningの入門書を読んでみたりLangChainの入門書を読んでみたりしてPythonのコードを軽く書く程度で、本格的な開発はしていません。
学ぶ段取り
何を学べば良いのかChatGPTのo3-miniと壁打ちしたところ、Linux、Python、GitHub、Dockerを学ぶべきというお告げをもらい、題材はLangChainの公式チュートリアルに決めました。
ただ、Linuxは軽く触った程度でコマンド5個くらいしか知らないですし、Pythonは前述のように入門レベルです。GitHubも単にソース公開のサービスとしてしか使ったことがなく、Dockerはまともに触ったことすらありません。浦島太郎状態もいいところです。
手元にあるMac miniとParallels Desktopを使う前提でo3-miniと相談したところ、次のようなプランができあがりました。
- 開発用OSとしてUbuntuの仮想マシン(VM)を用意
- それをMacのVS CodeからSSHで接続して利用
- Ubuntuで開発環境を構築
- LangChainのチュートリアルに挑戦しながらGitHubでバージョン管理
- Dockerはここまでできたら挑戦しましょう
Dockerははみ出ちゃいましたね😅
というわけで
平日は本業が忙しいので週末メインです。3ヶ月でどこまで行けるのか不安ですが、3日坊主にならないようにメモを公開していくことにしました。何か間違ったことをやっていたり変な方向に進んでいたら、アドバイスをいただけますとうれしいです!
Parallels DesktopでUbuntuのVM作成
使っているのはParallels Desktop 20 for Mac Pro Edtionです。バージョンは20.2.2 (55879)でした。
Ubuntuのインストールはすごく簡単で、Parallelsの「ファイル」メニューの「新規...」を選んで、無料システムのUbuntu Linuxを選ぶだけです。何もつまずくことなくVMができあがりました。Parallels Desktopがちょっと便利すぎる。これじゃLinuxの勉強にならなそう……
MacにVS Codeをインストール
これはすでに入れていたのでそのまま使います。
Visual Studio Code extension for Parallels Desktopのインストール
Parallelsの起動時にVS Codeの機能拡張Visual Studio Code extension for Parallels Desktopを紹介してくるので入れてみたら、VS Codeの画面内でVMの起動や終了、スナップショットの作成などができるようになりました。これは便利かも。なお、Parallels Desktop ProかBusiness Edtionが必要とのことなのでご注意ください。
ちなみにここでターミナルのアイコン(マウスオーバーで「Get inside VM」と出てくるボタン)をクリックすると、なんとrootでログインできました。すごいな、これ。まだMacとのネットワークすらつながってないはずなので、Parallelsがバイパスしてくれているみたいです。
Macのデフォルトシェルをzshへ切り替え
あと、zshがお勧めですよ、のメッセージが出てますね。ターミナル使う機会があまりなかったので放置してましたが、Apple公式曰くzshいいよ!とのことなので、Macのターミナルを起動して切り替えます。
chsh -s /bin/zsh
これでMacのターミナルでは切り替わったのですが、あれ?VS Codeが連動しない。ChatGPTに聞いたらVS Codeの統合ターミナルのデフォルトシェルも切り替えないとダメとのことで、VS CodeのコマンドパレットでTerminal: Select Default Profile
と入力してzshを選択することで切り替えました。
UbuntuにSSHサーバーをインストール
ChatGPT曰くパッケージ管理のツールにはapt
とapt-get
があって、日常的なパッケージ管理はapt
がいいよとのことなので、apt
でセットアップします。なお、作業前にVMのスナップショットを作ったので、失敗しても簡単にやり直せます。VMだとこれがホント便利ですね。
なお、先ほどのVS Code機能拡張の「Get inside VM」ボタンで入ったrootで作業してもいいのですが、これだとUbuntuの画面に触れる機会がなくなってしまいそうなので、あえてVM側の画面からやってみます。
sudo apt update
これでaptのパッケージリストが最新になりました。
続いてopenssh-serverのインストールです。
sudo apt install openssh-server
問題なさそうなので起動します。
sudo systemctl start ssh
そして状態の確認です。
sudo systemctl status ssh
お、activeとなっているので良さそう!
あと、これだとUbuntuの起動と連動しないみたいなので、自動起動にしておきます。
sudo systemctl enable ssh
MacとUbuntu VMを同じネットワークに変更
MacのIPアドレスはDHCPで取得している192.168.210.92なのですが、VMのUbuntuは違うネットワークになっているので合わせます。
ParallelsのVMの初期設定では「共有ネットワーク」になっていてParallelsのNAT機能でIPが振られてしまうので「ブリッジネットワーク」に切り替えます。
これでMacと同じネットワークになりました。
ega@M2-Mac-mini ~ % ping 192.168.210.107
PING 192.168.210.107 (192.168.210.107): 56 data bytes
64 bytes from 192.168.210.107: icmp_seq=0 ttl=64 time=0.552 ms
64 bytes from 192.168.210.107: icmp_seq=1 ttl=64 time=0.491 ms
64 bytes from 192.168.210.107: icmp_seq=2 ttl=64 time=0.696 ms
64 bytes from 192.168.210.107: icmp_seq=3 ttl=64 time=0.779 ms
64 bytes from 192.168.210.107: icmp_seq=4 ttl=64 time=0.560 ms
^C
--- 192.168.210.107 ping statistics ---
5 packets transmitted, 5 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.491/0.616/0.779/0.106 ms
つながった!
MacのVS Codeに「Remote - SSH拡張機能」をインストール
MacのVS CodeからUbuntu VMを使うためにRemote - SSH拡張機能をインストールします。
接続先の設定を~/.ssh/config
に書かないといけないのですが、歯車アイコンを押すと新規ファイルを作ってくれます。便利!
我が家のPCはマンション共用のルーターのDHCPでIPアドレスが振られており(マンション各戸は同じネットワークを共用するのですがVLANで区切られているそう)、IPアドレスがきまぐれで変わります。そのため、本当はホスト名で指定したりIPを固定化しておきたいのですが、残念ながらDHCPの設定は変えられないので、変更に気づいたら都度直すことにします。
Host Ubuntu
HostName 192.168.210.107
User parallels
これでVS Codeから接続すると、フィンガープリントの確認とパスワードの入力を経て、無事接続できました!
これ、ファイル操作だけでなくプロセス動かしたりデバッグしたりできる訳ですよね。MacのVS CodeであたかもローカルのようにUbuntuが使えるとは。しばらく開発から遠ざかっていた間に、世の中がすごく進化していました😁
あと、ここまで数時間でつまずかずにこれたのはChatGPTのおかげです。昔だったらあっという間に1日溶けてたかも。AIの進化で勉強時間が短縮できるようになったのはホントありがたいです。
UbuntuでPythonの開発環境の構築
ここからはPythonの開発環境の構築なのですが、バージョン管理やパッケージ管理の仕組みが乱立してて、どれを使えばいいのかさっぱりわかりません。軽くググっただけでも、venv、pip、pyenv、Pipenv、poetry、asdf、……いやいや、ちょっと多すぎ。
そんな中で、この整理に最適な記事を発見しました!なんと知り合いの@oshima_123さんの記事!これはありがたい!
こちらの動画でも解説されています!
また、最近だとこの問題を解決すべく、uvというのがあることもXで教えていただきました。
どれを使うか悩みましたが、いきなり統合された便利なものを使うと中身がブラックボックスになってしまい仕組みが理解ができなくなりそうなので、まずはシンプルな機能しかないpyenv、venv、pipを触ってみて、その後でasdf+Poetryやuvなどの統合されたものに進もうと思います。
ということで、Pythonのバージョン管理にpyenv、仮想環境の管理にvenv、パッケージ管理にpipを使う形で環境構築に挑みます。
pyenvのインストール
公式の手順に従ってインストールしてみます。2025/04/06時点の手順です。
A. Getting Pyenv
まず、推奨になっているインストーラーの実行です。
curl -fsSL https://pyenv.run | bash
bash用のスクリプトがダウンロードされて実行される形です。なるほど、デフォルトのシェルがなんであれ、この形ならbashのスクリプトだけ用意すれば済む訳ですね。
B. Set up your shell environment for Pyenv
続いてシェルの環境設定ですが、ここはシェルごとに異なります。そもそも、Ubuntuで動いてるシェルが何なのかすら知らない状態なので、その確認から。$SHELL変数を確認すればいいそうです。
$ echo $SHELL
/bin/bash
bashなことがわかったので、bashの手順で設定します。
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init - bash)"' >> ~/.bashrc
シェルの文法がさっぱりわからなかったので軽く調べました。
-
export
は環境変数を設定するもので、PYENV_ROOTに$HOME/.pyenv
を設定 -
[[ -d $PYENV_ROOT/bin ]]
は条件分岐で、-d
は指定パスがディレクトリかどうかチェック、もしそうなら&&
以降のexportでPATHの先頭に$PYENV_ROOT/bin
を挿入 -
eval
はシェルのコードを実行するもので、pyenv init - bash
が出力するシェルコードを実行 -
echo
は標準出力の表示で、それを>>
でリダイレクトすることで~/.bashrc
に追記
また、~/.profile
も存在したので同様に追記します。これは、bash以外のシェルでも共通で設定したいものを書く場所だそうです。
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.profile
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.profile
echo 'eval "$(pyenv init - bash)"' >> ~/.profile
~/.bash_profile
と~/.bash_login
は存在しなかったので、特に何もしないでよいのかな。
それにしても、シェルの文法やファイルの使われ方は、慣れるまでにちょっと時間がかかりそうです。Windowsとも違うしシェルも何種類もあるし、なんで人類は似たようなものをたくさん作ってしまうのか……
C. Restart your shell
手順にしたがってシェルを再起動します。
exec "$SHELL"
D. Install Python build dependencies
Pythonのビルドに必要な環境の構築です。手順に従ってapt
でインストールします。
sudo apt update; sudo apt install build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev curl git \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
また、以下のような説明がありました。
The Python's documentation reports a different set of dependencies in the documentation and in the script used in the GitHub Actions
If you are going build PyPy from source or install other Python flavors that require CLang, also install llvm.
(Google翻訳)
Pythonのドキュメントでは、ドキュメントとGitHub Actionsで使用されるスクリプトで異なる依存関係のセットが報告されています。PyPy をソースからビルドする場合、または CLang を必要とする他の Python フレーバーをインストールする場合は、 もインストールしてくださいllvm。
なるほど、いわゆる普通のC言語で作られたCPython以外に、PythonにはPyPyやその他のバリエーション(フレーバー)があるんですね。で、それらを入れる場合はビルドが必要なので追加でllvm
が必要になると。現時点では普通のCPython以外を使うかわからないので、とりあえず入れないでおきましょう。
pyenvを使ってみる
これで使えるはず。
まず、使えるPythonのバージョンの一覧を表示。
pyenv install --list
すごくたくさん出てきました。2025/04/06時点で最新の3.13.2を入れてみます。
pyenv install 3.13.2
無事インストールできたので、バージョン一覧を表示してみます。
$ pyenv versions
* system (set by /home/parallels/.pyenv/version)
3.13.2
これで元々のUbuntuに入っていたものと3.13.2の2種類が入った状態になりました。今のバージョンを調べてみます。
$ python3 --version
Python 3.12.3
今は3.12.3でした。これがUbuntsに入っていたものですね。これをグローバルで3.13.2に切り替えてみます。
$ pyenv global 3.13.2
$ pyenv versions
system
* 3.13.2 (set by /home/parallels/.pyenv/version)
$ python3 --version
Python 3.13.2
切り替わりました!
pyenvのインストール完了です!
python
とpython3
の違い
venvに進む前にふと思ったのが、python
とpython3
の違い。これはPython 2とPython 3の過渡期の名残り?のようで、最近はどちらもでPython 3が動くみたいです。
$ python --version
Python 3.13.2
$ python3 --version
Python 3.13.2
確かにバージョンは同じですね。Pythonの実行ファイルは同じなのでしょうか?
$ which python
/home/parallels/.pyenv/shims/python
$ which python3
/home/parallels/.pyenv/shims/python3
これはpyenvが環境切り替えのために用意しているスクリプトでした。中身はどちらもこんな感じです。
#!/usr/bin/env bash
set -e
[ -n "$PYENV_DEBUG" ] && set -x
program="${0##*/}"
export PYENV_ROOT="/home/parallels/.pyenv"
exec "/home/parallels/.pyenv/libexec/pyenv" exec "$program" "$@"
環境変数を追加してpyenv exec python〜
に読み替えているみたいですね。これだと、最終的にどの実行ファイルが動いているのかわかりません。
ChatGPTに聞いたら、Pythonのプログラム内からsys.executable
で実行ファイルのパスがわかるとのこと。こっちで調べてみましょう。
$ python
Python 3.13.2 (main, Apr 6 2025, 21:30:52) [GCC 13.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> print(sys.executable)
/home/parallels/.pyenv/versions/3.13.2/bin/python
$ python3
Python 3.13.2 (main, Apr 6 2025, 21:30:52) [GCC 13.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> print(sys.executable)
/home/parallels/.pyenv/versions/3.13.2/bin/python3
あれ?やっぱり実行ファイルが違う。ls
で確認してみます。
$ cd /home/parallels/.pyenv/versions/3.13.2/bin/
$ ls -al python*
lrwxrwxrwx 1 parallels parallels 10 Apr 6 21:31 python -> python3.13
lrwxrwxrwx 1 parallels parallels 10 Apr 6 21:31 python3 -> python3.13
-rwxr-xr-x 1 parallels parallels 72224 Apr 6 21:30 python3.13
-rwxr-xr-x 1 parallels parallels 3377 Apr 6 21:31 python3.13-config
-rwxr-xr-x 1 parallels parallels 70581 Apr 6 21:31 python3.13-gdb.py
lrwxrwxrwx 1 parallels parallels 17 Apr 6 21:31 python3-config -> python3.13-config
lrwxrwxrwx 1 parallels parallels 17 Apr 6 21:31 python-config -> python3.13-config
お、->
はシンボリックリンクだそうなので、Windowsのショートカットみたいなものですね。どちらも同じ実行ファイルpython3.13
を指していることが確認できました。これならどちらを使っても大丈夫そうですが、古い環境でも大丈夫なように以降もpython3
で進めます。
venvのインストール
venvをインストールしようと思ったのですが、python標準なのでインストール不要でした。公式の以下の説明を見て進めます。
今回は~/projects/langchain-tutorial
ディレクトリを作って、ここで作業する環境を作りました。
$ pwd
/home/parallels/projects/langchain-tutorial
$ python3 -m venv .venv
これでvenvの環境構築完了です。
$ source .venv/bin/activate
これでアクティベートできました。
$ which python
/home/parallels/projects/langchain-tutorial/.venv/bin/python
$ python3 --version
Python 3.13.2
きちんと.venv
以下のpython
が動いていますね。ここでpyenvとの関係が気になったので、ちょっと確認してみます。
$ ls -l /home/parallels/projects/langchain-tutorial/.venv/bin/python
lrwxrwxrwx 1 parallels parallels 49 Apr 7 00:28 /home/parallels/projects/langchain-tutorial/.venv/bin/python -> /home/parallels/.pyenv/versions/3.13.2/bin/python
お、きちんとpyenvの環境下のpythonを指していますね。ただ、シンボリックリンクになっているので、おそらくpyenvでPythonのバージョンを切り替えても動的には追従しないんじゃないかと思います。ちょっと試してみましょう。
$ pyenv versions
system
* 3.13.2 (set by /home/parallels/.pyenv/version)
$ pyenv global system
$ pyenv versions
* system (set by /home/parallels/.pyenv/version)
3.13.2
$ python3 --version
Python 3.13.2
ですよね。systemは3.12.3なのですが切り替わりません。
venvの環境を作る時は、先にpyenvを使ってPythonのバージョンを切り替えておく必要がありそうです。
venvの環境を終了してみましょう。
$ deactivate
$ python3 --version
Python 3.12.3
これで、pyenvの指定した環境に戻りました。
混乱しそうなので、pyenvでも最新の3.13.2に戻して先に進みます。
$ pyenv global 3.13.2
venvの仕組み
venvの仕組みについては、前回紹介した記事や動画のスライドがわかりやすかったです。
いくつか備忘のためにメモを。
- venvもpyenv同様、仮想環境と言っても使うディレクトリを切り替えているだけ
-
activate
コマンドで環境変数PATHの先頭に独立したディレクトリを追加してくれる -
activate
コマンドの実体はシェルスクリプトで、環境変数を変更するためにsource
(.
)コマンドで実行しないといけない(後述) - インストールするPythonのモジュールは独立したディレクトリに配置されていく
-
deactivate
で戻してくれる
ちょっとややこしかったのは、LinuxがWindowsのコマンドプロンプトとは違う点です。
Windowsではコマンドプロンプトでバッチファイルを実行しても同じプロセスで動き、別プロセスにするにはstart
コマンドが必要です。これに対してLinuxでは、普通にシェルスクリプトを動かすと別プロセスになり、同じプロセスで動かすにはsource
(.
)コマンドが必要ということですね。そのため、activate
ではsource
コマンドが必要になります。
あと、同じく環境変数を戻すdeactivate
はsource
コマンドなしでなぜ動くのかというと、これはactivate
のシェルスクリプト実行時にシェル関数として組み込まれるので、シェル関数として同じプロセスで実行されるからですね、なるほど。
それにしても、source
を.
と略しちゃうのはやりすぎでは?と思ったら、なんと.
が先で、後からsource
ができたそうです。UNIX系のシェルは奥が深いな。
pipのインストール
pipもPython標準なのでインストール不要ですが、最新版にするために、以下の公式の手順を実行します。
まず、venvのアクティベート。
$ . .venv/bin/activate
そしてpipの最新化です。
$ python3 -m pip install --upgrade pip
Requirement already satisfied: pip in ./.venv/lib/python3.13/site-packages (24.3.1)
Collecting pip
Downloading pip-25.0.1-py3-none-any.whl.metadata (3.7 kB)
Downloading pip-25.0.1-py3-none-any.whl (1.8 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.8/1.8 MB 19.8 MB/s eta 0:00:00
Installing collected packages: pip
Attempting uninstall: pip
Found existing installation: pip 24.3.1
Uninstalling pip-24.3.1:
Successfully uninstalled pip-24.3.1
Successfully installed pip-25.0.1
$ python3 -m pip --version
pip 25.0.1 from /home/parallels/projects/langchain-tutorial/.venv/lib/python3.13/site-packages/pip (python 3.13)
これで2025/04/13時点の最新である25.0.1がインストールされました。
LangChainのインストール
続いて、LangChainのインストールです。ここでLangChainの公式ページを見ていて気になったことが。
たとえばOpenAIのモデルを使う場合、セットアップのコマンドは公式だと以下の感じで直接pip
コマンドを叩いています。
pip install -qU "langchain[openai]"
でも、Pythonの以下の公式ガイドでは、python3 -m
を実行する形になっています。
python3 -m pip install requests
そもそも-m
は何するオプションなのかを調べてみたら、指定したモジュールの__main__
を実行するものでした。Pythonをまだちゃんとわかっていませんが、pip自体もPythonで作られたモジュールということですね。
そうなるとよくわからないのが、pip
でなぜ直接実行できるのかなのですが、これも調べたら、単にPythonで書かれたスクリプトになっていて、pipのmain()
を実行する形になっていました。
#!/home/parallels/projects/langchain-tutorial/.venv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from pip._internal.cli.main import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())
つまり、どっちも同じということみたいです。
ちょっと脱線してしまいますが、スクリプトファイルの先頭行で#!
付けてpythonの実行ファイルを指定したら、Pythonのコードをシェルスクリプトのように実行できるんですね。てっきりシェルの指定しかできないのかと思っていました。Windowsだと同じことするには拡張子の紐付けが絡んで面倒なことになるので、Linuxはいろいろと新鮮です。
どちらでも良さそうなことがわかったので、シンプルにpip
でインストールしてみます。私はすでにOpenAIのAPI-KEYがあるので、chat modelで「OpenAI」を選択して案内されるpipコマンドを実行してみました。
pip install -qU "langchain[openai]"
インストールが終わったので、公式ガイドの通りに実行してみます。Pythonのインタラクティブモードで試してみました。
$ python3
Python 3.13.2 (main, Apr 6 2025, 21:30:52) [GCC 13.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import getpass
... import os
...
... if not os.environ.get("OPENAI_API_KEY"):
... os.environ["OPENAI_API_KEY"] = getpass.getpass("Enter API key for OpenAI: ")
...
... from langchain.chat_models import init_chat_model
...
... model = init_chat_model("gpt-4o-mini", model_provider="openai")
...
Enter API key for OpenAI:
>>> model.invoke("Hello, world!")
AIMessage(content='Hello! How can I assist you today?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 10, 'prompt_tokens': 11, 'total_tokens': 21, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_44added55e', 'id': 'chatcmpl-BLkBXygmOENUNjSnWtL6YJdMCcA8N', 'finish_reason': 'stop', 'logprobs': None}, id='run-1421b243-2ba9-4d6c-9a4c-360730bf9786-0', usage_metadata={'input_tokens': 11, 'output_tokens': 10, 'total_tokens': 21, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})
>>>
おぉ、「Hello! How can I assist you today?」が返ってきた!
LangChainのインストール完了です!
Pythonの開発環境の構築
先週、LangChainのインストールまでしてしまいましたが、VS CodeでのPtyhonの開発環境を整えるのが先でした。
今日はVS Codeの本家サイトにあるチュートリアル「Getting Started with Python in VS Code」(VS Code で Python を使い始める)をGoogle翻訳で訳しつつ、VS CodeでPythonのhello world!に挑戦してみます。
Prerequisites(前提条件)
ややこしかったのが、VS Code拡張機能の「Python」をMac側に入れるのかUbuntu側に入れるのかです。今回はUbuntuを使うので、MacのVS Codeを使っていてもインストールはUbuntu側だそうです。Mac上のVS Codeは本当にUIの上っ面だけを実行している形ですね。
Install a Python interpreter(Pythonインタープリターをインストールする)
これは先週pyenvを使って完了しています。
Start VS Code in a workspace folder(ワークスペースフォルダでVS Codeを起動する)
先週は~/projects/langchain-tutorial
を作ってLangChainをインストールしたのですが、今回はそれとは別に~/projects/hello
ディレクトリを作成することにしました。ここをVS Codeの「ファイル」ー「フォルダーを開く...」メニューで開きます。
Create a virtual environment(仮想環境を作る)
なんと、コマンドパレットで「Python: Create Environment」するとvenvの環境が作れるそうです。
ここで「Venv」を選択して、
あれ?pyenvで入れた「3.13.2」の環境がでてこない😢
でも「Python: Select Interpreter」でインタープリターを選択する時はpyenv環境も出てきます。不思議。
どうやらこのissueが同じことを言っている風なのですが、すでに1年前に修正されている模様です(Google翻訳だとイマイチ正確に読み取れず違うかも😅)。
ちょっと調べた感じだとshim(先週、pipがなぜ直接実行できるのかを調べたらスクリプトになっていましたが、そのようなスクリプトの総称みたいです)のPATHが通ってないみたいな解説が出てくるのですが、先週pyenvをインストールした際に~/.bashrc
と~/.profile
に追記したeval "$(pyenv init - bash)"
でshimのPATHもきちんと通るようです。そもそも「Python: Select Interpreter」で出てくる段階でVS Codeは認識してますもんね。原因がよくわかりません。
とりあえず「Python: Create Environment」でインタープリターを選ぶ際に、pyenvで入れた3.13.2の場所/home/parallels/.pyenv/versions/3.13.2/bin/python
を選んで進んでみると、「.venv」ディレクトリができました!
どうやらpython3 -m venv .venv
をやってくれたみたいです。コマンドを覚えるのが苦手な私にとって、これは便利!
Create a Python source code file(Pythonソースコードファイルを作成する)
おぉ、インテリセンスもきちんと働きます。これもUbuntu側で動いてMacのVS Codeは表示しているだけなのか、なかなかすごいです。
Run Python code(Pythonコードを実行する)
動いた!
ということは、venvのアクティベートsource .venv/bin/activate
も自動でやってくれていますね。便利!
Configure and run the debugger(デバッガーを設定して実行する)
デバッガーも問題なく動きました。リモートデバッグもリモートであることをまったく意識させません。すごいな。ホント、浦島太郎状態です。
Install and use packages(パッケージをインストールして使用する)
新規でターミナルを開くと、自動的にvenvのアクティベートが実行されています。ターミナル名にマウスを持っていくと説明が出てきました。
$VIRTUAL_ENV
も確かに切り替わっています。
アクティベートの意識が不要なのは便利ですね。無事、venv環境にnumpyもインストールでき動きました!
以降、VS Codeでこのhelloディレクトリを開けば、このプロジェクト用のvenvがアクティベートされ、ターミナルを開いてpip installすればvenvの環境内にインストールされます。venvのコマンドは忘れても大丈夫かも。VS Code様さまです!
VS Code以外で作ったvenv環境をVS Codeで開くとどうなる?
コマンドパレットで「Python: Create Environment」するとvenv環境を作れることがわかりましたが、先週python3 -m venv .venv
で作ってしまったLangChainのインストール環境がどうなるのか確認しました。
VS Codeでこの~/projects/langchain-tutorial
を開いて、コマンドパレットで「Python: Create Environment」を選び「Venv」を選択すると「既存のものを使用」が!
これを選ぶとちゃんと使えました。新規のターミナルにもきちんと反映されていてLangChainがインストール済みになっています。
いいね!
GitHubの概要把握
GitHubをきちんと勉強したことがなかったので、本家サイトのGet Startedの「体験してみる」を一通り読んでみました。
なんとなく聞いたことがある程度だったブランチ、コミット、プッシュ、プルリクエスト、マージ、クローン、フォークなどの言葉が理解でき、すっきりしました。
クローンとフォークが少し迷いましたが、クローンはローカルにコピーする作業で、フォークは元を枝分かれさせてサーバ側でコピーする機能ですね。
VS CodeでのGitHubの使い方
続いて、VS CodeによるGitHubの使い方を、Google翻訳に頼りながら本家サイトの「Using Git source control in VS Code」で勉強してみます。YouTubeの動画も日本語の字幕が出せるのでなんとかなるかな。
Working in a Git repository(Gitリポジトリでの作業)
さっそく、LangChainの最初のチュートリアルBuild a simple LLM application with chat models and prompt templates(チャットモデルとプロンプトテンプレートを使用してシンプルな LLM アプリケーションを構築する)を題材にGitHubを使ってみようと思ったのですが、LangChainのこのチュートリアルはJupyter Notebookが前提になっていました。右上に「Open in Colab」のボタンまで用意されています。確かにGoogle Colabなら環境に依存する問題がないのでチュートリアルには最適です。
でも、Google Colabを使ってしまうとGitHubやVS Codeの勉強にならないので、このチュートリアルの内容を使いつつも自分でGitのリポジトリを作ってみようと思います。
Cloning a repository(リポジトリのクローン作成)
今回はクローンせずに自分で作るので、「Open Folder」で前回インストール時に作ったvenvのフォルダー~/projects/langchain-tutorial
を開きます。それにしても、開くだけでvenvのアクティベートを自動でやってくれるのは便利ですね。せっかく学んだvenvのことを忘れるのも時間の問題です😅
Initialize a repository(リポジトリを初期化する)
「Initialize Repository」ボタンでリポジトリを初期化し、「simple_llm_application.py」を作って、チュートリアルの最初のブロックを貼り付けます。
import getpass
import os
try:
# load environment variables from .env file (requires `python-dotenv`)
from dotenv import load_dotenv
load_dotenv()
except ImportError:
pass
os.environ["LANGSMITH_TRACING"] = "true"
if "LANGSMITH_API_KEY" not in os.environ:
os.environ["LANGSMITH_API_KEY"] = getpass.getpass(
prompt="Enter your LangSmith API key (optional): "
)
if "LANGSMITH_PROJECT" not in os.environ:
os.environ["LANGSMITH_PROJECT"] = getpass.getpass(
prompt='Enter your LangSmith Project Name (default = "default"): '
)
if not os.environ.get("LANGSMITH_PROJECT"):
os.environ["LANGSMITH_PROJECT"] = "default"
if "OPENAI_API_KEY" not in os.environ:
os.environ["OPENAI_API_KEY"] = getpass.getpass(
prompt="Enter your OpenAI API key (required if using OpenAI): "
)
環境変数を読み込むコードしかないですが、GitHubの練習なのでまずはこれでいいでしょう。
あれ?dotenvが見つからないと言ってますね。python-dotenvが必要みたいなのですが、Pythonと一緒には入らないのかな。VS Codeのターミナルでpip show
して確認してみます。
$ pip show python-dotenv
WARNING: Package(s) not found: python-dotenv
やっぱりないので、pip install python-dotenv
でインストールしました。そうしたら、インストール直後にソースから警告が消えました。リアルタイムで反映されるのすごい。
APIキーなどは、プロジェクトルートの.envファイルに書いておけばいい感じでしょうか。とりあえず必要になりそうなものを書き込んでおきます。LangSmithのAPIキーもOpenAIのAPIキーも以前の勉強で作成したものです。
LANGSMITH_TRACING="true"
LANGSMITH_API_KEY="hogehoge"
OPENAI_API_KEY="fugofugo"
LANGSMITH_PROJECT="langchain_tutorial"
あと、python-dotenvの「Getting Started」にある以下の注意に従い、.gitignoreファイルを作って記入しておきます。
You will probably want to add .env to your .gitignore, especially if it contains secrets like a password.
(特にパスワードなどの秘密情報が含まれている場合は、.gitignoreに.envを追加することが必要になる可能性があります。)
.env
そういえば、.venvディレクトリは何もしていないのに初めからGitの管理対象外になっています、不思議。ちょっと調べたら、公式サイト曰く、version 3.13から.venvディレクトリの直下に.gitignoreが作成されるようになったとのことで、ファイルの覗いたら*
が書いてありました。いたせりつくせりです。
Commit(コミット)
Gitはコマンド覚えるのが大変かと思ったら、VS Code使うと操作がGUIでできてしまいます。コマンド覚えないで済むのはありがたい!
なお、YouTubeの動画では「出力」タブに実行したgitのコマンドが表示されると解説されていたのですが、なぜか表示されません。が、よく見たら切り替えのメニューがありました。
動画ではスタッシュなどの操作説明もありますが、いつ使うのかピンときていません。この辺は使うようになった時に戻ってこようと思います。
初めてコミットしようとしたらGitの設定が足りない!と怒られました。「詳細を表示」ボタンで表示される本家のページを見ながらセットアップします。
$ git config --global user.name "segavvy"
$ git config --global user.email segavvy@yahoo.co.jp
これでコミットもできました!
あと、解説の中でGenerate a commit message with AI(AIでコミットメッセージを生成する)というのがあったので試してみます。
画面にあるcopilotアイコンをクリックするとMicrosoftアカウントの設定を求められるので、指示に従って設定するとGitHub Copilotのフリープランが使えるようになります。
なんと、もうGPT-4.1(Preview)が選べます。さっそく、この貼り付けたコードをチェックしてもらいました。
これはいいですね!
コミットメッセージの生成も試してみましょう。チュートリアルの続きのコードを追加してコミットしてみます。
# ----------------------------------------------------
from langchain.chat_models import init_chat_model
model = init_chat_model("gpt-4o-mini", model_provider="openai")
from langchain_core.messages import HumanMessage, SystemMessage
messages = [
SystemMessage("Translate the following from English into Italian"),
HumanMessage("hi!"),
]
model.invoke(messages)
ここでコミットメッセージの入力欄の右にあるアイコンをクリックすると、Copilotがコミットメッセージを生成してくれます!
いやはや、すごい時代になってきました。
Git blame information(Gitの責任情報)
Google翻訳の「責任情報」が何のことだかわからなかったのですが、最終のコミット情報を表示してくれる機能ですね。デフォルトではステータスバーに表示されていました。
コマンドパレットから「Git: Toggle Git Blame Editor Decoration」で切り替えるとエディタ上にもでてきます。便利!
ただ、ちょっとエディタ上のはちょっとウザいかな。OFFに戻して進みます。
Review uncommitted code changes with AI(コミットされていないコードの変更を AI で確認)
コミット前にCopilotがレビューしてくれる機能があるそうなので、ソースコードの終わりの部分をチュートリアルの続きのコードに変えて、ストリーミング呼び出しにしてみます。
for token in model.stream(messages):
print(token.content, end="|")
ここでCopilotにレビューさせてみました。
ストリーミングのループの最後に改行入れたらどう?とのご指摘です。確かにそうなので、
その下にある「Apply」ボタンを押してソースに反映し、Copilotにコミットメッセージを書かせてコミットしました。Copilot、なかなかいいじゃないですか!
なお、レビューのコメントが英語なのが残念ですが、これは本家サイトの説明曰く、カスタム指示の設定で直せそうです。
このページのUse settings(設定を使用する)に従って、Code reviewのgithub.copilot.chat.reviewSelection.instructions
を設定してみます。[Code]メニューの「基本設定」ー「設定」で設定を探せばOKですね。
すでにコミットしてしまったので、コマンドパレットから「Git: Undo Last Commit」して、最後のprint()
もない状態に戻して再度レビューさせてみます。
あれ?ダメですね。VS Codeを起動しなおしたり、Ubuntu側に反映できていないのかと思いコマンドパレットから「Developer: Reload Window」もやってみたのですが英語になってしまいます。今設定しているのは「選択範囲のレビュー」なのですが、もしかしたら今使っている「コミット前のレビュー」とは異なる機能なのかも!コミット前のレビューに対するカスタム指示はUse settings(設定を使用する)にないので、今はまだ設定できないのかもしれませんね。
今日は最後に、このコードをGitHubのサーバーに公開してみました。左下のアイコンを選んで、
サインインを許可して、
画面の指示に従っていけばOKです。プライベートなリポジトリが無事できあがりました!
それにしても、VS CodeだとGitのコマンドをまったく打たないですね。コマンド覚えなくて本当にいいのか不安になるレベルです。
あと、今日初めてGitHub Copilotを触りましたが、なかなかいい感じです。ただ、右下のCopilotアイコンで使用量を見たら、ちょっと使っただけなのにチャットメッセージはもう6%の消費。Freeプランだとあっという間になくなりそう。