AIの「投資会社」をGitHubとVPSで運用する。本番を安全に更新できる仕組みを作った

11 / BUILD DEPLOY 本番を安全に更新する。PC・GitHub・VPSの役割分担の図

個人の投資戦略を、AIエージェントの「部署」に分けて組み立てています。毎朝決まった時間に、売買の推奨をメールで届ける仕組みも、すでにレンタルサーバー(VPS)の上で動いています。

ただ、これまではパソコンのコードとサーバーのコードを手作業で行き来させていて、どちらが最新なのか、いつ何を変えたのかが分からなくなりかけていました。本格的に運用する前に、GitHubとVPSの役割を分けて、本番を安全に更新できる形に整えました。この記事は、その作業の記録です。

AIの「部署」で投資戦略を回すフォルダ

最初に、土台になっている仕組みを説明します。投資戦略に関わる仕事を、会社の部署のように5つに分けました。部署ごとに専用のAIエージェントがいて、フォルダも部署ごとに分かれています。

  • 経営企画:目標のリターンや許容できる下落幅、戦略ごとの資金配分を決める
  • リサーチ部:市場の環境やデータの質を調べ、新しい戦略のアイデアを探す
  • 戦略部:個別の戦略を作り、過去のデータで検証(バックテスト)する
  • リスク管理部:本番に出す前に、戦略が過去のデータに合わせすぎていないかを確かめる
  • 運用部:本番のサーバーを動かし、毎朝のシグナル配信を見守る

私が話しかけるのは「社長役」のAIで、社長役が内容に合う部署へ仕事を振ります。ここで決めているルールは2つあります。リスク管理部が承認していない戦略は本番に出さないこと。そして、実際の注文はAIではなく私が出すことです。AIがするのは、推奨と計算までです。

運用を始める前の状態

仕組み自体は動いていましたが、運用の面ではいくつか不安がありました。

  • パソコンにある開発用のコードと、VPSで動いている本番のコードが別々にあり、手作業でコピーして合わせていた
  • どちらにも変更の履歴が残っておらず、何をいつ変えたのか後から追えなかった
  • メールを送るためのGmailのパスワードが、本番のコードの中に直接書かれていた

3つ目が一番の問題でした。このままコードをGitHubに置くと、パスワードも一緒にアップロードされてしまいます。GitHubを使い始める前に、まずここを直す必要がありました。

PC・GitHub・VPSに役割を分ける

考え方はシンプルで、3つの場所にそれぞれ1つずつ役割を持たせます。

  • パソコン:コードを書き、試す場所
  • GitHub:正式なコードを置き、変更の履歴を残す場所。非公開のリポジトリ(保管庫)にした
  • VPS:GitHubからコードを受け取り、毎朝の処理を実際に動かす場所

本番を更新するときの流れは、次のように決めました。

  1. パソコンでコードを直して、GitHubに送る(push)
  2. リスク管理部が変更を確認する
  3. 私が承認する
  4. VPSがGitHubから最新のコードを受け取る(pull)

Gitは、ファイルの変更を履歴として残す道具です。履歴があれば、何かおかしくなったときに前の状態へ戻せます。これまでの「手でコピーする」方法では、コピーし忘れや上書きのミスが起きても気づきにくく、戻す手段もありませんでした。

リポジトリには、戦略のコードだけでなく、部署ごとの資料やAIエージェントの設定も含めて、フォルダ全体を入れることにしました。部署の判断とコードの変更が同じ履歴に並ぶほうが、後から読み返しやすいと考えたからです。

パスワードをコードの外に出す

Gmailのパスワードは、コードから「.env」という別のファイルに移しました。コードは起動したときにこのファイルを読み、中にある値を使ってメールを送ります。.envはGitの対象から外しておき、本番のVPSの中にだけ置きます。

Gitの対象から外すファイルは「.gitignore」という一覧に書きます。今回はこう決めました。

  • パスワードなどの認証情報のファイル(.env と、データ取得サービスの認証ファイル)
  • Pythonの実行環境のフォルダ(あとで作り直せるため)
  • 手作業で取ったバックアップのフォルダ

最初にアップロードする前に、送る予定のファイルをすべて洗い出し、パスワードやメールアドレス、APIキーのような文字列が混ざっていないかを確かめました。このとき、データ取得サービスの認証ファイルがデータのフォルダに置かれていることにも気づき、これも対象から外しました。パスワード以外にも、秘密の情報は思わぬ場所にあるものです。

また、.envをどう書けばよいかが分かるように、値をダミーにした見本のファイル(.env.example)だけはGitに入れています。

何をGitに入れて、何を入れないか

迷ったのは、データのフォルダの扱いです。ここには、株価のデータ、本番で使うパラメータ(戦略の設定値)、毎朝のシグナルの履歴、損益の記録が混ざっていました。

結論として、Gitで管理するのはパラメータだけにしました。

  • パラメータ:戦略の動きを決める大事な設定。いつ変えたかを履歴に残したいので、Gitに入れる
  • 株価・シグナル・損益の記録:VPSが毎朝自動で書き足していく。Gitに入れると、VPS側で毎日ファイルが変わり、GitHubから最新のコードを受け取るときにぶつかってしまう。そこで、VPSの中にだけ置く

「人が決めるもの」はGitで管理し、「機械が毎日作るもの」はVPSに置いておく、という分け方です。

VPSは「読むだけ」の鍵でGitHubにつなぐ

VPSがGitHubからコードを受け取るには、鍵が必要です。今回は、このリポジトリだけに使える「デプロイキー」という鍵を作り、権限を読み取り専用にしました。

こうしておけば、VPSはGitHubからコードを受け取れますが、GitHubへ書き込むことはできません。万が一VPSが乗っ取られても、GitHubにある正式なコードは書き換えられません。正式なコードを変えられるのはパソコンからだけ、という一方通行にしました。

本番を止めずに引っ越す

VPSでは、毎朝8時にシグナルを作ってメールを送り、8時5分に損益を記録する処理が、cron(決まった時刻に処理を動かす仕組み)で動いています。これを止めずに切り替えるため、今の本番フォルダには手を付けず、GitHubから受け取ったコードを別の新しいフォルダに置きました。

  1. GitHubから新しいフォルダにコードを受け取る
  2. Pythonの実行環境を作り直す。本番と同じバージョンのPythonを使い、パッケージの一覧も本番から書き出したものを使った
  3. 古いコードに書かれていたメールの設定を、VPSの中だけで.envに移す。パスワードは画面に表示しない
  4. 株価やシグナルの記録を、古いフォルダから新しいフォルダへコピーする
  5. 動作を確認する
  6. cronの設定をバックアップしてから、実行先を新しいフォルダに切り替える

確認では、次のことを1つずつ見ました。

  • 新しい環境のパッケージが、本番の環境と完全に一致している
  • Gitで管理しているパラメータが、本番で使っていたものと一致している
  • .envからメールの設定を読めている
  • Gmailにログインできる。ただし、実際のメールは送らない

最後の確認でメールを送らなかったのは、このメールが実際の売買の推奨として届くからです。テストのつもりで送ったメールを、本物の推奨と取り違えるおそれがあります。ログインできるところまで確かめれば、送信に必要な設定がそろっていることは分かります。

古い本番フォルダとcronのバックアップは、消さずに残しています。新しい場所で問題が起きても、cronの設定を戻すだけで元の状態に戻せます。

つまずいたこと

作業は、AIエージェント(Claude Code)に任せて進めました。途中で2回、AIの操作が安全チェックで止められました。

1回目は、AIがVPSに鍵を作ろうとしたときです。AIが自分の判断でコマンドを実行するモードにしていたのですが、「リモートのサーバーに書き込む操作」として止められました。2回目は、それを解決するためにAIが自分の権限の設定を書き換えようとしたときで、「AIが自分の権限を広げる操作」として止められました。

どちらも、AIはチェックを迂回しようとせず、作業を止めて状況を説明してくれました。最終的には、私がサーバーへの接続を許可する設定を自分で追加し、VPSの作業中だけ、操作ごとに確認が出るモードに切り替えて進めました。本番のサーバーに触れる作業では、この「人が許可するまで進まない」という止まり方のほうが安心だと感じました。

関連記事:AIへWordPress作業を任せる前に、変更範囲と停止条件を決める(止まる条件を、作業の前に書いておく考え方)

もう1つは、日本語のファイル名でつまずいたことです。パラメータのファイルを照合したとき、日本語の名前のファイルだけが「差分あり」と表示されました。原因は、Gitが日本語のファイル名を記号に置き換えて出力していたことで、比較する相手のファイルが見つからなかっただけでした。日本語のまま出力する設定にして照合し直し、すべて一致していることを確かめました。

できたことと、まだ確かめていないこと

この作業で、次のことができるようになりました。

  • コードの変更が、すべてGitHubに履歴として残る
  • 本番の更新は、VPSでGitHubから受け取るだけで済む
  • パスワードは本番のVPSの中にだけあり、GitHubには上がらない
  • 問題が起きたときに、前のコードや古い本番フォルダに戻せる

新しい場所で毎朝の処理が実際に動くのは、作業をした翌朝が初めてでした。結果を早く確かめたかったので、翌朝は実行の時刻を8時から7時30分に早め、損益の記録も7時35分に移しました。

確認では、次のことを見ました。

  • cronが、新しいフォルダから7時30分と7時35分に処理を起動した
  • ログにエラーがなく、株価の取得もほぼすべての銘柄でできていた
  • シグナルのファイルができ、メールの送信が完了していた
  • 損益の記録に、新しい日付の行が増えていた
  • VPSの中のコードが、GitHubにあるものから変わっていなかった

この確認は、毎朝くり返すものなので、1回で全部を見られる読み取り専用のスクリプトにまとめました。サーバーの中は読むだけで、何も書き換えません。初回の実行は、すべての項目が問題なしでした。

関連記事:AI作業の完了を「操作した」で終わらせない。表示確認と証拠を残す方法(結果を別の画面で確かめる考え方)

やって分かったこと

一番大きかったのは、GitHubを使う前に「何を上げてはいけないか」を決める必要があったことです。パスワードは分かりやすい例ですが、データのフォルダに認証ファイルが紛れていたように、確かめてみて初めて気づくものもありました。

もう1つは、「人が決めるもの」と「機械が毎日作るもの」を分けると、Gitの使い方が自然に決まることです。全部を入れようとすると、毎朝の自動処理と衝突します。

本番を切り替える作業は、新しい場所を横に作り、確かめてから切り替え、古い場所を残しておく、という順番で進めました。地味な作業ですが、毎朝実際のメールが届く仕組みだからこそ、戻れる道を残しておくことを優先しました。

続き:この仕組みの土台になっている「部署」の考え方は、AIエージェントを「部署」に分けて、投資の仕組みを作る。止める役を別にした理由 にまとめました。

シリーズの目次:AIに作業を任せるときの決まり(このテーマの記事を、読む順に並べています)

※ この記事は、仕組みづくりの記録です。特定の銘柄や投資手法をすすめるものではありません。投資の判断は、ご自身の責任で行ってください。