見出し画像

社内の蓄積メモを横断検索できるサイトを、AIと一緒に作ってみた話

最初に言っておくと、私はコードなんて全く読めない人。

それでも、小さな塾経営会社のバックオフィスを担当している立場上、「社内に散らばっている業務記録を一発で引っ張れる仕組みが欲しい」というのは長年のモヤモヤだった。今回、ついにClaudeと一緒に、社内向けの「情報ログ検索サイト」を自分の手で(正確にはAIに手伝ってもらいながら)立ち上げてみた。

当たり前の話もあるかもしれないけど、日記として残しておきたい。もっと良い方法があれば、ぜひ教えてください。

Before:何に困っていたか

社内の業務メモって、気づいたら本当にあちこちに散らばっている。

  • 業務報告メモはWordファイル

  • 日々の業務メモはテキストやスプレッドシート

  • 雑談ベースの気づきメモも、別のフォルダに別形式で

「あの件、前にどこかにメモしたよな…」と思っても、どのフォルダのどのファイルに書いたかが思い出せない。フォルダを順番に開いて、ファイルを順番に開いて、Ctrl+Fで検索して…をやっているうちに、何を探していたのかを忘れる、みたいなこともしばしば。

「社内で蓄積したログ検索サイト」みたいなものが欲しい、けど外部クラウドに載せるのは情報の性質的にちょっと怖い。自社のレンタルサーバーの中だけで完結する、社内専用の検索サイトが作れたらいいのにな、というのが今回のスタート地点。

やったこと(ざっくり)

技術構成は、Claudeと相談しながらこんな感じに落ち着いた。

  • レンタルサーバーの中にPHPで小さなサイトを置く

  • データはSQLiteというファイル型のデータベースに入れる

  • 検索の高速化にはFTS5という全文検索の仕組みを使う

  • 入口にはBASIC認証+HTTPS強制をかけて、社外からは原則触れないようにする

…と、書き出してみると専門用語が並ぶけど、私自身は「PHPって何の略だっけ」レベルからのスタート。「全部Claudeに書いてもらって、自分はファイルを置く・置き換えるだけ」という分業で進めた感じかな。

ローカルでまずUIモックアップを作って、配色・ヘッダ・バッジ表示を比較。「これでいきましょう」と決まったらサーバー側にPHP一式(トップ/検索/個別表示/アップロード/DB初期化)を入れて、実データを85件アップして稼働確認、という流れ。

ここまでは順調に見えるけど、もちろん壁はあった。

壁①:「複合語ならヒットするのに、その一部分だとヒット0件」問題

データを85件入れて、いざ検索してみた段階で気づいた違和感がこれ。

たとえば「講習報告書」という複合語で検索すると、ちゃんと3件ヒットする。本文中に【講習】というタグが付いている記録なら、見出し検索で5件ヒットする。

ところが、「講習」だけで検索すると、ヒット0件。

「いや、本文の中に講習報告書って思いっきり書いてあるじゃん…」と画面を二度見した。

Claudeに「これダメだった、なぜ?」と相談したら、原因はFTS5のトークナイザという仕組みらしい。デフォルトの「unicode61」トークナイザは、日本語の漢字が連続している部分を「1つのカタマリ」として扱ってしまう。なので「講習報告書」というカタマリに対して「講習」で部分一致を探しても、トークン単位では別物になってヒットしない、ということだった、みたい。

…正直、最初は何を言われているのか半分くらいしか分かっていなかった。なので「コード読めない人にも分かるように、もう一度噛み砕いて」と頼んで、ようやく「日本語が苦手な検索エンジン使っちゃってたのね」というところまで腹落ちした感じかな。

解決策はClaudeから4つ提示された。

  • A案:trigram(3文字単位で区切る)トークナイザに切り替える

  • B案:FTS5を使わずLIKE検索(昔ながらの部分一致)に切り替える

  • C案:キーワードを別テーブルに分けて、タグとして検索する

  • D案:データを取り込むときのスクリプト側で、複合語を細かく分割して登録する

それぞれメリット・デメリットがあって、ここはまだ即決しないことにした。データの中身は85件のうちまだ複合語フル一致でヒットすればOKなケースの方が多いので、いったん「部分検索の課題は次回まわし」として、本日は他の整備を優先する判断にした、というのが正直なところ。

「全部いま解決しなきゃ」じゃなくて、「壁の存在を認識した上で次回テーマに置く」だけでも、自分ひとりだったらできなかったかもしれない、と思う。AIと一緒だと、判断材料がそろうのが早い。

壁②:「VACUUM INTO のSQL残存エラー」

これは部分検索とは別の場面で出たエラー。

DB(データベース)の状態を整えるために、移行用のスクリプトをClaudeに書いてもらって走らせたら、こんな英語のエラーが出た。

cannot VACUUM - SQL statements in progress

…見た瞬間、軽く絶望、の一言。SQLite用語+英語、という二重の壁。

ただ、ここでもClaudeに「このエラー読めないから、何が起きていてどう直せばいいか、コード読めない人向けに教えて」と相談したら、ちゃんと噛み砕いて教えてくれた。

要するに、

  • DBのファイルを「キレイに掃除して別ファイルに保存」する操作(VACUUM INTO)をしようとしたら、

  • そのDBに対して「まだ別の処理が途中だよ」という状態のままだった

  • だから「他の作業が終わってないからVACUUMできません」と怒られている

…という、家事で言うなら「まだ食器使ってる途中なのに、シンクごと丸洗いしようとした」みたいな話、かな。

Claudeから提案されたのは「v2では、DBに接続したらまっさきにVACUUM INTOを実行する形に直しましょう」というやり方。順番を入れ替えるだけのシンプルな修正で、エラーは解消した。

ここで気づいたのは、英語のエラーメッセージって、AI相手なら怖くないということ。前は英語のエラーを見るたびに「もう無理…」と画面を閉じたくなっていたけど、貼り付けて「読んで・砕いて・直して」と頼めば、3行で意味と直し方が返ってくる。これが一番の心理的な変化だったかも。

壁③:「DB本体は触らず索引だけ再構築」って、本当に大丈夫?

部分検索の課題(壁①)に向き合うとき、4つの案のうちA案「trigramトークナイザに切り替える」を選ぶと、索引(インデックス)の作り直しが必要になる。

ここで急に怖くなった。「索引の作り直し」って、データ本体に何か影響あるんじゃない?85件、ちまちま入れたデータが消えたりしない?という気持ち。

Claudeに「この操作で、データ本体は触られない?絶対に?」と何度も確認した。返ってきた説明はこんな感じ。

  • データ本体(記録の中身)が入っているテーブルと、検索用の索引は別物

  • 索引だけを作り直しても、本体テーブルには手を触れない

  • それでも心配なら、操作前にDBファイルを丸ごとコピーしてバックアップを取ればいい

…という流れで、「バックアップ取ってから索引だけ作り直す」というやり方なら安全、というところまで合意できた。

これも、コードが読めない人にとっては「Claudeが大丈夫って言ってるから、たぶん大丈夫」では足りない。「何が触られて、何が触られないのか」を、自分の言葉で説明できるところまでは噛み砕いてもらう、というのが安心材料になった、かな。

実際の切り替え作業は壁①と同じく次回まわしにしたけど、「やる前提の心の準備」はここで整った感じ。

After:何が変わったか

  • 社内の業務メモ85件が、サイトの検索ボックスから一発で引ける状態に

  • 「あれどこに書いたっけ」とフォルダを掘り返す時間が、ほぼゼロに

  • BASIC認証+HTTPS強制で、社内の決まった人だけがアクセスできる構成

  • 部分検索の課題は次回テーマとして見えている(trigramかLIKEに切り替え予定)

  • 削除機能などの細かい運用整備も次回課題として一覧化できた

完全自動とか完全完成、ではない。けど、「横断検索できる小さな入り口が立ち上がった」というのは、自分にとっては結構な節目だった、かも。

そして何より、コードが読めない私が、サーバーに自分でPHPを置いて検索サイトを動かしているという事実そのものが、ちょっと不思議。Claudeに「ここのファイルを丸ごと差し替えて」と言われたとおりにアップロードするだけで、画面が動く。

「半自動化」というより「半自作」という言い方の方が近いかもしれない。

注意点

社内向けとはいえ、Webにファイルを置く以上、安全運用は最初から固めておきたかったポイント。

私の場合、ここは最初の構成段階でClaudeに相談して、こうしている。

  • BASIC認証+HTTPS強制を、入口に必ずかける

  • セキュリティ用のヘッダ(CSPなど)を入れて、ブラウザ側にも余計な動きをさせない

  • データ本体が置いてあるフォルダは、Webから直接アクセスできないように設定(Deny from all)

  • 移行スクリプト等の管理用ファイルも、常時公開はしない方針

「あとから付け足す」だと忘れてしまいそうなので、最初の構成段階で固定で入れておく、という運用にしている。

それから、データを入れる前に必ずDBファイルのバックアップを取る、というのも自分の中のルール。トークナイザの切り替えなど、索引まわりを触る時にも同じ。「壊れても元に戻せる」状態を先に用意してから、壊しに行く、というのが、コードを読めない人間がやれる最大の備えかな、という気がしている。

まとめ

今回の体験で一番大きかったのは、「英語+専門用語のエラーメッセージが、もう怖くなくなった」ということ。

前なら、画面いっぱいの英語エラーを見た瞬間に「もう無理、誰か助けて」となっていたところを、Claudeに貼り付けて「読んで、砕いて、直して」と頼めば、3行で原因と対処が返ってくる。コードが読めなくても、「何が起きていて、何をすれば直るか」を日本語で受け取れるようになっただけで、自分でやれる範囲は何倍にも広がった気がする。

それと、AIと一緒だと「いま全部解決しなくていい」という判断もしやすい。部分検索の問題は4つの案が並んだ時点で「どれを選ぶか」を急がず、次回テーマに置けた。ひとりで抱えていたら、たぶん「全部今日中に解決しないと…」と無理して結局途中で挫折していただろうな、と思う。

完全に自動とか、完全に自作とか、そういう極端な形を目指すんじゃなくて、ちょうどいい半自動・半自作で、自分の手と頭が無理なく回る範囲に収めながら、社内の便利な仕組みを少しずつ立ち上げていく。今回もまた、そんな進め方ができた一日だったかな。

次回は、部分検索の壁にちゃんと向き合おうと思っている。

このシリーズでは、小さな塾の経営管理をAIとノーコードツールで効率化した実体験を紹介しています。

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