見出し画像

「あの資料どこだっけ?」が秒で解決。エラーログを貼るだけの“泥臭い”AIアプリ開発

プログラミングの新しい手法「Vibe Coding(バイブコーディング)」は、AIとの対話し「こういうものを作りたい」という意図を伝えながら開発を進めるスタイルです。

前回はOpenAIの「Whisper」を使った音声入力アプリを紹介しました。実際の開発現場は、スマートに進むわけではなく、割と泥臭いトライ&エラーの繰り返しです。今回は、非エンジニアである私が最新のAI(Gemini)を使い、PCの画面を記録・検索できる「Time Machine Memory」というアプリを形にするまでの「試行錯誤」のプロセスを、技術的な側面と合わせて書きたいと思います。

※ちなみに、この記事はエンジニアや技術に詳しい方にも読んでいただけるよう、特に技術やロジックの部分については、AIの力を借りながら制作しました。つたない部分もあるかと思いますが、ご容赦ください。


開発の背景「個人的な忘却対策」

今回のアプリ開発の「最大の動機」は、私自身の個人的な特性にあります。特定の物事に集中するにスイッチが入ってしまうと「ついさっきまで何をしていたか」「どの資料を見ていたか」といった記憶が抜け落ちてしまうことがあるのです。さらに、誤ってアプリを終了させてしまい、冷や汗をたらたら流しながら記憶をたどる、なんてこともあります。

そもそも、この「情報の濁流」の中では、画面の一部に表示された特定のテキストや画像を記憶として保持し続けることには限界があります。そこで、自分の記憶を補完するために「PCの画面をすべて記録し、後から検索できる外部脳」を自作しようと考えました。

環境構築で「エラー」続出

まず手始めにGeminiとブレストしながら、プロンプトを固めていきました。
Geminiには「自分がアプリを作ってやりたいこと」「操作感」「守ってほしいこと」などを、音声入力で少しずつ伝えていき、一通り伝え終わったら、「CursorかGoogle Antigravityでこのアプリをコーディングしたいです。プロンプトを生成してください」と指示しました。そして、生成されたプロンプトがこちらです。

指示書:常駐型デスクトップ「記憶」アプリのプロトタイプ作成

1. 役割定義
あなたは熟練したPythonエンジニアです。ユーザーのPC作業画面を定期的に「記憶(データ化)」し、後から検索可能にするデスクトップアプリケーションのプロトタイプを作成してください。

2. アプリケーションコンセプト

バックグラウンドで一定間隔ごとにデスクトップのスクリーンショットを撮影。Vision AIを用いて画像内のテキストや状況を解析・要約し、その内容をローカルのベクトルデータベース(ChromaDB)に保存します。ユーザーは後ほど自然言語を用いて、過去の作業画面を検索・特定できる仕組みです(Macのアプリ「Rewind」の簡易版イメージ)。

3. 技術スタック
・言語:
Python 3.x
GUI / 常駐管理: pystray (システムトレイ常駐) または tkinter (簡易検索窓)
キャプチャ: mss または pyautogui
ベクトルDB: chromadb (ローカル完結型)
解析モジュール: google-generativeai (Gemini) または openai (Visionモデル) を呼び出すための共通インターフェース

4. 基本機能と処理フロー
以下のループ処理をメインスレッドで実装してください。
待機: 指定されたインターバル(例:60秒)待機。
撮影: 画面全体をキャプチャし、一時フォルダへ保存。
解析: 関数 analyze_image(image_path) を呼び出し、AIに以下のプロンプトを投げる。
「この画像に写っているアプリケーション名、ウィンドウのタイトル、表示されている主要なテキスト内容を、検索しやすいように詳細に要約して」
保存: 解析結果のテキスト、画像パス、タイムスタンプをChromaDBに登録(Embedding)。
検索: 検索窓に入力されたクエリに対し、類似度の高いレコードを抽出。該当するスクリーンショットのパスと要約を表示。

5. 【重要】開発品質とセキュリティの厳守事項
実装にあたっては、以下のセキュリティ基準を最優先で遵守してください。
機密情報の分離: APIキーやトークンをコード内に直接記述(ハードコード)することを厳禁します。必ず環境変数(.envファイルなど)から読み込む構造にしてください。
入力値の徹底的な検証: 検索クエリなどのユーザー入力や外部データはすべて信頼できないものとし、形式チェックや無害化(サニタイズ)を行ってください。
安全なデータ処理: pickle などの不安全な形式は避け、データ保存や通信には JSON などの安全な形式を使用してください。
最小権限の原則: ファイル操作やネットワーク接続は、アプリの動作に必要な最小限の権限で実行されるように設計してください。
エラーハンドリングの徹底: 例外発生時、システムの内部パスや機密情報がエラーメッセージとして露出しないように配慮してください。
セキュリティ・セルフレビューの実施: コード生成後、あなた自身(AI)がセキュリティ担当者の視点で検証を行い、脆弱性を修正した「リファイン版」を最終回答として提示してください。
プライバシー保護の実装: 画面キャプチャ前にアクティブなウィンドウのタイトルを確認し、銀行、パスワード管理、個人チャットなどの機密情報が含まれるキーワードを検知した場合は、撮影と送信をスキップするロジックを組み込んでください。
APIポリシーの遵守: データの学習利用を避けるため、API経由でのデータ取り扱い設定に配慮した実装にしてください。

6. 出力への期待
コードはクラスや関数でモジュール化し、将来的にVision APIのモデルを容易に差し替えられる設計にしてください。
・必要なライブラリをまとめた requirements.txt を作成してください。
・まずはAPI部分をダミーテキストを返す「モック関数」とした状態で、全体の骨組みが動くコードを出力してください。

※長くて申し訳ありません

AIと最初に試みたのは、1分ごとにスクリーンショットを撮影し、AIがその内容を解析して保存するという仕組みの構築です。しかし、開発を始めてすぐに、環境構築の段階でいくつものエラーに直面しました。

具体的には「Microsoft Visual C++」の不足や、ライブラリである「NumPy」のバージョン不整合など、プログラミングに詳しくない人間にとっては原因の特定が難しいものばかりです。

とにかく、表示されたエラーログをそのままAIに貼り付け、解決策を求めました。AIは即座に、特定のライブラリをダウングレードするコマンドを提示し、それに従うと環境の問題は解消しました。

開発したアプリのコア・ロジック

以下は、AIと共に構築したPythonのコードの主要部分です。1分ごとに画面を保存してGeminiで解析し、その結果をローカルのベクトルデータベース(ChromaDB)に蓄積していく仕組みです。これにより、後から「あの時の画面」を言葉で検索できるようになります。

※以下は記録部分の主要ロジックです。これとは別に、検索用のGUI(tkinter等)もAIと作成しました。

import mss
import time
import os
import chromadb
import pygetwindow as gw  # アクティブウィンドウ取得用
from datetime import datetime
from dotenv import load_dotenv
from google import generativeai as genai

# 1. 環境設定とAPIキーの読み込み(セキュリティ対策)
load_dotenv()
API_KEY = os.getenv("GEMINI_API_KEY")

if not API_KEY:
    raise ValueError(".envファイルにGEMINI_API_KEYを設定してください。")

genai.configure(api_key=API_KEY)
model = genai.GenerativeModel('gemini-2.0-flash')

# 2. ベクトルデータベース(ChromaDB)の初期化
# データをローカルに保存し、後で「意味」で検索できるようにする
db_client = chromadb.PersistentClient(path="./memory_db")
collection = db_client.get_or_create_collection(name="screen_memories")

def is_sensitive_window_active():
    """機密情報が含まれそうなウィンドウを検知する(プライバシーガード)"""
    sensitive_keywords = ["銀行", "Slack", "Password", "機密", "証券", "設定"]
    try:
        active_window = gw.getActiveWindowTitle()
        if active_window:
            for keyword in sensitive_keywords:
                if keyword.lower() in active_window.lower():
                    return True, active_window
    except Exception:
        pass
    return False, ""

def capture_and_analyze():
    # プライバシーチェック:特定のアプリが開いている時は記録しない
    is_sensitive, title = is_sensitive_window_active()    if is_sensitive:
        print(f"【スキップ】機密情報の可能性を検知:{title}")
        return

    with mss.mss() as sct:
        # メインモニタとサブモニタの両方をループして撮影
        # sct.monitors[1:] が各個別のモニタを表す
        for i, monitor in enumerate(sct.monitors[1:], 1):
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            filename = f"screenshot_mon{i}_{timestamp}.png"
            
            # スクリーンショットの撮影
            sct.shot(mon=i, output=filename)
            
            # Gemini APIによる画像解析
            sample_file = genai.upload_file(path=filename)
            response = model.generate_content([
                "この画面に何が映っているか、検索しやすいキーワードで詳細に要約してください。",
                sample_file
            ])
            summary = response.text
            
            # 3. 解析結果をChromaDBに保存
            collection.add(
                documents=[summary],
                metadatas=[{"path": filename, "time": timestamp}],                ids=[f"{timestamp}_{i}"]
            )
            print(f"モニタ{i} 記憶完了: {summary[:30]}...")

# メインループ
while True:
    capture_and_analyze()
    time.sleep(60)

モデルの選定と情報の補完

AIの「視覚機能」を実装する段階では、使用するモデルの選定に課題があったようです。当初検討していた実験用のAIモデルは、リクエストの回数制限が厳しく、1分ごとのキャプチャという用途には不向きだったそうです。

AIが提示した古いAIモデル名が既に利用不可となっていて、行き詰まりそうになる場面もありました。そこで、私がGeminiやOpenAIなどのAPIのリリースノートなどを確認し「現在の最新モデルはこれ」と情報を提示してやると、一気に作業が進むこともありました。バイブコーディングをやっていると、AIがあらゆる情報を正確に把握しているわけではないことがよくわかります。作りこむ際には、人間が事実確認を行い、方向性を修正するという「補完関係」が重要です。

また、技術的な選定以上にこだわったのが「プライバシーの担保」です。1分ごとに画面をクラウドAIに送るという仕組みは、利便性と引き換えにリスクを伴います。

そこで私はAIに「特定のアプリが開いている時は記録を止める機能」を要求し、さらにGemini APIの規約を読み込み、入力データがAIの学習に再利用されない「API経由の利用」であることを確認しました。「何でもAI任せ」にするのではなく、こうした安全性の最終確認を人間である私が主導することこそが、バイブコーディングにおける「口を出す」の真髄といえます。

ツールとしての完成と役割分担

最終的に、タスクトレイに常駐する形式のアプリが完成しました。アイコンの設定など、AIによるコード生成だけでは完結しにくい細かな設定については、AIが作成した手順書をもとに、私自身が手動で行いました。

2時間ほどで完成した「Time Machine Memory」は、1分に1回、ディスプレイのスクリーンショットを撮影し、GeminiAPIが画像を読み込んで、「その時PCで何をやっていたか」を記録する仕組みです。

「Time Machine Memory」の検索画面

例えば「きのう見ていたバイブコーディングのサイトはどこだっけ」と思って検索すれば、実際に何のサイトを見ていたかがわかります。作って10日余りたちましたが、今では毎日PCに常駐する、私にとって欠かせないアプリになりました。

自らが何らかの「ペイン」を感じていれば、バイブコーディングの強力なモチベーションになるはずです。そして、コードの中身を完全に理解していなくとも、適切な対話を繰り返していくことで、生活を補助する実用的なツールを1日で形にすることができると改めて感じたのでした。


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

ゆらぎ文系思考ログ 記事を楽しんでいただけましたら、サポートいただけると嬉しいです。いただいたチップは、AIエージェントのAPI利用料、検証用ガジェットの資金、そして時々、オフィスの癒やし(金魚やイモリのエサ代)に使わせていただきます。「次の実験も楽しみにしてるよ」という応援、励みになります!

この記事が参加している募集