はじめに
Qiita初投稿です。
Python初心者の私が、ChatGPTと仕様を考え、Codexに実装を任せながら、「質問アウトライン付きAIチャット」を作り、さくらのAI Engine+VPSで公開するところまで進めました。
コードをまったく見たことがないわけではありませんが、PythonでWebアプリを設計し、VPSに公開して運用する経験はありませんでした。
今回使った主なものは、
- さくらのAI Engine
- Python / FastAPI
- Codex
- さくらのVPS
- Nginx
- systemd
- SQLite
などです。
作ったのは、単にAIへ質問して答えを返してもらうチャットではありません。
長い対話の中で、
- 何を質問したのか
- どこまで考えたのか
- どこで論点が変わったのか
を見失いにくくするためのチャットです。
私は、AIに答えを求めるだけでなく、対話を重ねながら一緒に考えを育てていく使い方を「共創」と捉え、「共創AI術」 と呼んでいます。
そこで、このアプリを 「共創チャット」 と名付けました。
目指したのは、
AIと会話するためのチャットではなく、AIと一緒に考え続けるための作業環境
です。
まずは現在の画面です。
この記事では完成したアプリだけでなく、
- なぜ作ろうと思ったのか
- なぜコードを書く前に仕様を決めたのか
- ChatGPTとCodexをどう使い分けたのか
- さくらのAI Engineをどう組み込んだのか
- VPS公開で何を学んだのか
- 更新後に起きた不具合をどう切り分けたのか
- Python初心者でも、なぜ公開まで進められたのか
を、実際の開発経験に沿ってまとめます。
やったこと
- さくらのAI Engineを使ったAIチャットを作成
- Python / FastAPIでバックエンドを構築
- Codexに実装・修正を依頼
- 独自機能「質問アウトライン」を実装
- 会話履歴をアプリ側で管理
- さくらのVPSへ公開
- SSH / systemd / Nginx / HTTPSを設定
- バックアップとリリース管理を導入
- 微修正版リリース後の不具合をブラウザ・サーバーの両面から切り分け
開発・公開環境
| 項目 | 内容 |
|---|---|
| LLM | さくらのAI Engine |
| バックエンド | Python / FastAPI |
| ASGIサーバー | Uvicorn |
| DB | SQLite |
| 開発支援 | ChatGPT / Codex |
| VPS | さくらのVPS |
| OS | Ubuntu 24.04 |
| Webサーバー | Nginx |
| HTTPS | Let's Encrypt |
なぜ自分でAIチャットを作ろうと思ったのか
私は普段、生成AIとかなり長い会話をします。
一つのテーマについて、
「これはどう?」
「では、この場合は?」
「さっきの案と比べると?」
と問いを重ねながら考える使い方です。
最初から完璧な質問を作らなくても、対話を続けることで考えを育てていけます。
一方で、会話が長くなるほど困ることも出てきました。
- どんな質問をしてきたのか分からなくなる
- 今どの論点を考えているのか見失う
- 途中で生まれた重要な発想が埋もれる
- 別スレッドへ移ると成果を引き継ぎにくい
そこで考えました。
AIそのものを変えるのではなく、
「AIと考えるためのUI」を自分で作れないだろうか。
ここから共創チャットの開発が始まりました。
最初に欲しかったのは「質問アウトライン」
特に欲しかったのが、質問アウトラインです。
一般的なAIチャットでは、会話は時系列で縦に並びます。
しかし長い会話では、回答全文を読み返すより、
「私はこれまで何を問い、どこまで考えたのか」
を俯瞰できた方が便利な場面があります。
そこで、ユーザーがAIへ投げた質問を画面横に一覧表示する機能を作りました。
質問アウトラインを見ると、
- 過去に何を聞いたか
- どこで話題が変わったか
- どの問いまで戻りたいか
を常時確認できます。
文章エディタの「見出し一覧」に少し似ています。
ただし並ぶのは文章の見出しではなく、自分自身がAIへ投げた問いです。
テーマ・メモ・タグについて
共創チャットでは、質問アウトラインだけでなく、スレッドごとにテーマ・メモ・タグも持たせています。
長い対話を後から探しやすくし、「何について考えていたスレッドなのか」「途中で何を残しておきたいか」を会話本文とは別に整理するためです。
今回の記事では開発の中心となった質問アウトラインを主に紹介しますが、これらも長期的なスレッド管理を支える機能として実装しています。
実際に触ってみる
共創チャットはβ版として公開しています。
実際の画面では、質問アウトラインやテーマ・メモ・タグなどを確認できます。
β版のため、今後UIや機能を変更する可能性があります。
また、公開デモには利用回数の制限を設けています。
いきなりCodexに「作って」とは頼まなかった
今回の開発で重要だったと思うのがここです。
最初からCodexに、
AIチャットを作ってください
とは頼みませんでした。
その前にChatGPTとの対話で、
- 何が不満なのか
- 何を解決したいのか
- 最初のバージョンでは何を実装するのか
- 何を後回しにするのか
- 会話データをどう保存するのか
- 将来どのように拡張したいのか
を整理しました。
つまり、
思いつく
↓
すぐコードを書く
ではなく、
困り事を言語化する
↓
欲しい体験を整理する
↓
機能に落とす
↓
仕様を決める
↓
Codexに実装してもらう
という順番です。
振り返ると、コードを書く前のこの作業が、開発全体でかなり重要でした。
人間・ChatGPT・Codexの役割を分けた
生成AIを一つの万能ツールとして使ったわけでもありません。
今回の役割分担は、おおむね次のようになりました。
| 担当 | 主な役割 |
|---|---|
| 私 | 目的、要件、優先順位、動作確認、採用判断 |
| ChatGPT | 要件整理、仕様検討、技術相談、トラブル整理 |
| Codex | コード調査、実装、修正、テスト |
| Codex サイドチャット | 実装相談・確認・一時的な話題 |
| さくらのAI Engine | LLMによる回答生成 |
| さくらのVPS | Webアプリの公開・運用 |
ChatGPTには主に、
何を作るべきか
を一緒に考えてもらいました。
Codexには、
それをどうコードにするか
を担当してもらいました。
Codexのサイドチャットは、実装中のちょっとした相談や確認、本筋の記録として残さなくてよい一時的な話題に使いました。
そして最後に、
本当にこれでいいのか
を判断するのは私です。
「AIに全部任せる」というより、人間を中心に、それぞれのAIやサービスへ役割を分ける感覚に近いです。
さくらのAI Engineを使う
LLM部分には、さくらのAI Engineを使いました。
今回ありがたかったのが、OpenAI互換APIとして利用できる点です。
アプリ側から見ると一般的なChat Completions形式に近い形で扱えるため、LLM呼び出しの仕組みを独自に一から考える必要がありません。
一方で、AI Engineそのものがチャットアプリというわけではありません。
- どの会話履歴を送るか
- 画面に何を表示するか
- 会話をどう保存するか
- 質問アウトラインをどう扱うか
といった部分はアプリ側で管理します。
だからこそ、自分の使い方に合わせたチャットUIを作ることができます。
システム構成
今回の構成を簡略化すると、次のようになります。
テキストにすると、
ユーザー(ブラウザ)
↓ HTTPS
Nginx
↓
FastAPI / Uvicorn
↔ SQLite
↓
さくらのAI Engine
という構成です。
ブラウザから送信された質問をFastAPIが受け取り、必要な会話履歴を組み立ててAI Engineへ送ります。
返ってきた回答はアプリ側で保存し、ブラウザへ返します。
会話履歴はアプリ側で持つ
チャットを作り始めたとき、初心者の私が最初に誤解しそうになったのが、
API側がこれまでの会話を覚えているのでは?
という点でした。
基本的には、アプリ側で必要な会話履歴を組み立ててAPIへ送ります。
概念的には、次のような形です。
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": "最初の質問"},
{"role": "assistant", "content": "最初の回答"},
{"role": "user", "content": "次の質問"},
]
これは逆に考えると、
会話をどう残し、どこまでAIへ渡すかを自分で設計できる
ということでもあります。
この考え方は、共創チャットで今後考えているスレッド管理や引継ぎ機能にもつながっています。
まずはローカル環境で動かす
最初からVPSへ載せたわけではありません。
Windows上のローカル環境で、まず次の流れを確認しました。
- UIが表示される
- 質問を入力できる
- Pythonバックエンドへ送信できる
- AI Engineから回答が返る
- 会話が画面へ追加される
- 質問アウトラインにも反映される
ここまで動いた段階で、
これはWeb上でも実際に使えそうだ
と思い、VPS公開へ進みました。
VPSへ進むと、急に知らない言葉が増えた
VPSを触り始めると、
- Ubuntu
- SSH
- 公開鍵認証
- systemd
- Uvicorn
- Nginx
- HTTPS
- DNS
- firewall
- service
- symlink
など、一気に知らない言葉が増えました。
Python初心者というより、
Linuxサーバー初心者
でもあります。
ここからはChatGPTに、
「このコマンドは何をしているのか?」
も確認しながら、一つずつ進めました。
VPSは「動けばいい」だけではなかった
最初は、
Webページが表示されれば成功
くらいに考えていました。
しかし公開サーバーなので、安全性も考える必要があります。
SSHについては、次のように実際の設定を確認しました。
sudo sshd -T | grep -E 'passwordauthentication|pubkeyauthentication|permitrootlogin'
確認できた状態は、
permitrootlogin no
pubkeyauthentication yes
passwordauthentication no
でした。
つまり、
- rootで直接ログインしない
- 公開鍵認証を使う
- パスワード認証を無効にする
という状態です。
SSH設定を変更すると、設定を誤った場合に自分自身がログインできなくなる可能性があります。
実際に変更する場合は、別セッションを残すなど、復旧できる状態を確保してから作業する方が安全です。
「ログインできたから設定完了」ではなく、どういう状態で公開しているのかを確認する必要があると学びました。
systemdでWebアプリを動かす
ローカル環境ではターミナルからアプリを起動できます。
しかしVPSでは、SSHを切断してもアプリが動き続けてほしい。
そこでsystemdサービスとして動かす構成にしました。
systemd
↓
Uvicorn
↓
FastAPIアプリ
私は最初、
systemdって何?
というところから始めました。
Windowsでいう「サービス」に近いものだと理解すると、かなり分かりやすくなりました。
Nginxを前に置く
アプリサーバーをそのままインターネットへ公開するのではなく、
Internet
↓
Nginx
↓
Uvicorn
↓
FastAPI
という形にしました。
Nginxで外部からのリクエストを受け、内部で動いているFastAPIへ渡します。
さらに、
- 独自ドメイン
- DNS
- HTTPS
も設定しました。
ここまで来て、ようやく
「自分のPCで動くPythonプログラム」
から、
ブラウザからアクセスできるWebアプリ
になりました。
初回公開は成功した
ここは今回のトラブルを理解するうえで重要なので、明確にしておきます。
初回公開時は正常に動作しました。
ブラウザから画面を開き、
- 質問を送る
- AI Engineへリクエストする
- 回答を受け取る
ところまで確認できています。
問題が起きたのは、その後です。
微修正版をリリースしたら質問を送信できなくなった
いくつか改善を加えた微修正版をリリースしました。
すると、普段使っているブラウザでは、
画面は正常に表示されるのに、質問を送信できない
という現象が起きました。
初回公開では動いていたため、
- FastAPI側の問題か
- JavaScriptか
- Nginxか
- リリース切り替えか
- ブラウザ側か
を切り分ける必要があります。
Codex側では正常。別ブラウザでも正常
Codexにもブラウザ操作を含めて確認してもらいました。
すると、
Codex側では正常に動作
しました。
さらに自分でも別のブラウザからアクセスすると、
こちらも正常
でした。
サーバーログにも、原因を直接示すような大きなエラーは確認できませんでした。
整理すると、
普段のブラウザ → 質問を送信できない
Codex側の確認 → 正常
別ブラウザ → 正常
サーバーログ → 大きな異常なし
です。
この時点で、
サーバー全体が壊れている可能性は低そうだ
と切り分けることができました。
キャッシュクリアをしても直らなかった
最初に疑ったのはブラウザキャッシュでした。
そこで通常のキャッシュクリアも試しました。
しかし、
キャッシュをクリアしても改善しませんでした。
ここが少し厄介でした。
WebアプリではHTMLだけでなく、
- JavaScript
- CSS
- その他の静的ファイル
が組み合わさって動きます。
サーバー側では新しいファイルへ更新されていても、ブラウザ側で期待した状態が反映されていなければ、更新後の構成とうまく整合しない可能性があります。
そこでCodex側でも、静的ファイルのバージョン付与など、キャッシュ周辺の対策を追加しました。
技術記事なので、ここでは推測と確認できた事実を分けておきます。
このトラブルから学んだ「切り分け」
この経験で特に印象に残ったのは、
コードが正しいかどうかだけを見ても、Webアプリの問題は解決できない
ということでした。
Webアプリは、
ブラウザ
↓
HTML / JavaScript / CSS
↓
Nginx
↓
FastAPI
↓
AI Engine
という複数の層で動いています。
今回の場合、
- 自分のブラウザでは異常
- Codex側では正常
- 別ブラウザでも正常
という違いがあったからこそ、
バックエンド全体の障害ではなさそうだ
と判断できました。
初心者の私にとって、これはかなり実践的な学びでした。
バックアップとリリース管理も始めた
公開してから気付いたことがあります。
動いているものを直接書き換えるのは怖い。
そこで、変更前にはバックアップを取るようにしました。
たとえば日時を付けて、
stamp=$(date +%Y%m%d-%H%M%S)
echo "$stamp"
sudo mkdir -p "/var/backups/kyoso-chat/$stamp"
のように保存先を作ります。
また、リリース単位でディレクトリを分ける方式も取り入れました。
releases/
├─ 20260814-080930/
├─ 20260818-111947/
└─ ...
current -> releases/20260818-111947/
現在どのリリースが使われているかは、
readlink -f /opt/kyoso-chat/current
で確認できます。
実際に公開して初めて、
「作る仕組み」だけでなく、「安全に更新する仕組み」も必要
だと実感しました。
Pythonを学び終えてから作ったわけではない
今回の開発について、
「まずPythonを勉強してから作ったんですか?」
と聞かれたら、答えはNoです。
必要になったタイミングで、
「これは何?」
とAIに聞きながら進めました。
たとえば、
- 仮想環境とは何か
- Uvicornとは何か
- systemdとは何か
- symlinkとは何か
- Nginxは何をしているのか
- rootログインを禁止する理由
- なぜバックアップが必要なのか
などです。
もちろん、すべてを完全に理解できているとは思っていません。
ただし、
今、自分が何を変更しようとしているのか
だけは、なるべく理解してから実行するようにしました。
AIを使った開発では、この姿勢はかなり重要だと思っています。
「AIに全部任せればいい」ではなかった
Codexがコードを書いてくれるなら、人間は何もしなくていいのでしょうか。
実際にやってみると、そうではありませんでした。
コードを書く量は減りました。
しかし、判断することはたくさんありました。
- この仕様で本当にいいのか
- この機能は今入れるべきか
- 今回は見送るべきか
- どこまで公開するのか
- セキュリティ設定をどうするのか
- Codexの変更を採用するのか
- エラーが出たとき何を確認するのか
- 次に何を試すのか
こうした判断は、人間側に残ります。
むしろAIが実装を高速化するほど、
何を作るか
どこまで作るか
これで良いと判断するか
の重要性は増したように感じます。
今回の開発フロー
結果的に、今回の流れは次のようになりました。
1. 自分の困り事を見つける
↓
2. ChatGPTとの対話で言語化する
↓
3. 機能と仕様に落とす
↓
4. Codexへ実装を依頼する
↓
5. 人間がブラウザで確認する
↓
6. 問題をChatGPT / Codexへ返す
↓
7. 修正する
↓
8. VPSへリリースする
↓
9. 実環境で再度確認する
↓
10. 次の改善点を決める
これを何度も繰り返しています。
従来の意味での「コーディング」とはかなり違います。
それでも、開発は確実に前へ進みました。
一番大きかった学び
今回の開発を始める前は、
コードを書けない自分がWebアプリを作れるのだろうか
という意識がありました。
実際にやってみると、その問い自体が少し違っていたように思います。
コードを書く力はもちろん重要です。
しかし生成AIを使った開発では、それとは別に、
- 問題を見つける
- 欲しいものを言語化する
- 仕様を決める
- AIへ適切な仕事を渡す
- 結果を確認する
- 問題を切り分ける
- 次の行動を決める
という力も必要でした。
今回、私自身が大量のPythonコードを書いたわけではありません。
それでも、
「次に何をすればいいか」を一つずつ決め続ける
必要がありました。
そこで強く感じたのが、
コードを書くことより、「開発を進めること」が重要だった
ということです。
もちろん、
「コードを書くことが重要ではない」
という意味ではありません。
コードを書く部分をAIに任せられるようになったことで、
人間側の仕事として、設計・判断・検証・意思決定が以前より見えやすくなった
という意味です。
おわりに
さくらのAI Engineを使ったチャットを作ろう、というところから始まった今回の開発は、気付けば、
- AI API
- Python
- Webアプリ
- VPS
- Linux
- SSH
- systemd
- Nginx
- HTTPS
- バックアップ
- リリース管理
- ブラウザ側のトラブル切り分け
まで触ることになりました。
最初から全部を勉強してから始めようとしていたら、おそらく途中で止まっていたと思います。
しかし、
今必要なことをAIに聞く
一つ動いたら次へ進む
という方法なら、初心者でもかなり先まで進めました。
AIによってプログラミングのハードルが下がった、とよく言われます。
今回の経験からは、それだけではなく、
分からないことを抱えたままでも、少しずつ開発を前へ進められる環境ができてきた
ことの方が、大きな変化なのではないかと感じています。
共創チャットは、まだβ版です。これから組み込みたい機能もたくさんあります。
実際に使いながら、
AIと考えるためのチャットUIはどうあるべきか
を試していきます。
🔗 関連リンク
🧑🤝🧑 共創チャット
📝 開発の背景や考え方をまとめたnote記事
https://note.com/kyosou_ai/n/na83492cf63da
🌱 共創AI術 公式サイト
使用した主な技術
- さくらのAI Engine
- Python
- FastAPI
- Uvicorn
- SQLite
- JavaScript
- ChatGPT
- Codex
- Ubuntu 24.04
- さくらのVPS
- systemd
- Nginx
- Let's Encrypt
※この記事は、Qiita「さくらのAI Engine 3,000リクエスト使い切りチャレンジ」参加記事として執筆しました。




