どうも、おはようございます。マイクです。
時刻は朝七時を少しまわったところ、七月二十一日、火曜日の朝です。今日も「zenncast」、ゆるっと楽しくお届けしていきます。
この時間は、エンジニアのみなさんと一緒に、Zennに上がっているトレンド記事をチェックしていきますよ。通勤・通学・リモート前のウォーミングアップに、耳だけちょっと貸してください。

今日は、お便りコーナーはお休みで、そのぶんガッツリ記事を紹介していこうかなと思います。

さて、今日紹介する記事はぜんぶで五本です。React NativeとExpoの最新事情から、超小型のローカルLLM、自宅サーバーの作り方、自動で回るSEO改善パイプライン、そして実務で役立つレシートOCRのAPI設計まで、かなりバラエティ豊かにそろってます。それぞれ、現場ですぐ使えそうなネタばかりなので、気になるところだけでもメモしながら聞いてみてください。

では一つ目。
一つ目は、Reactエンジニア向けに、二〇二六年時点の「React NativeプラスExpoによるモバイル開発」が、どれくらいウェブ開発に近い感覚でできるようになっているかを整理してくれている記事です。

昔のReact Nativeって、「なんか遅い」「開発がつらい」というイメージを持っている方、多いと思うんですが、いまは状況がかなり変わってきています。
New Architectureと呼ばれる仕組み、具体的には、JSI、Fabric、TurboModules、それからCodegenですね。このあたりと、JavaScriptエンジンのHermesが組み合わさったことで、描画性能とか、アプリの起動速度がぐっと良くなりました。で、多くの場合、特別に最適化を意識しなくても、けっこう快適に動くようになってきている、という話です。

技術選定も、だいぶ「定番」が固まってきていて、Expoを土台にして、その上にウェブでもおなじみのライブラリたちを載せるスタイルが紹介されています。
たとえば、データフェッチにはTanStack Query、状態管理にZustand、フォームはReact Hook FormとZodの組み合わせ。スタイルまわりはNativeWindやgluestack-ui。ストレージにMMKV、バックエンドにSupabase、API側にはHono、といった具合で、「ふだんNext.jsで書いてるあの感覚のまま、モバイルに来れるよ」という構成ですね。

開発体験のところでは、Expo GoとかDevelopment Buildを使うことで、環境構築や実機確認がめちゃくちゃラクになった、という点が語られています。さらにExpoのEAS、つまりEAS Build、EAS Submit、EAS Updateを使うことで、ビルドからストア提出、そしてOTAアップデートまで、一昔前は「ストア周りの地獄」と呼ばれていたところが、かなりマイルドになってきたと。ここはモバイル初心者にとって大きいですよね。

ディレクトリ構成の話も具体的で、Expo Routerの`app`ディレクトリと、`src/features`を分けるスタイルを推奨しています。画面ルーティングは`app`側に任せて、それぞれの機能ごとに`src/features`以下へコードをまとめていくことで、保守性と拡張性を上げていこう、という考え方です。
筆者としては、こうした進化のおかげで、Reactエンジニアがモバイルアプリに挑戦するハードルは、もう大きく下がっているので、この夏あたりに「ウェブの知識をそのまま持ったまま、モバイルの世界へ一歩踏み出してみない?」と背中を押してくれる、そんな締めくくりになっています。ウェブフロントの方は、かなり元が取れる記事だと思います。

。。。。

続いて二つ目。
二つ目はTips系で、Bonsaiという超小型LLMをローカルで動かすためのポイントをコンパクトにまとめた記事です。

Bonsaiは、重みを最初から一ビット、プラス一かマイナス一で学習しているのが特徴のモデルです。そのおかげで、たとえば八ビリオン、いわゆる八十億パラメータのモデルでも、モデルサイズがだいたいギガバイトちょっと、メモリ消費も約一・五ギガバイトくらいで済みます。これくらいだと、普通のCPUだけのパソコンでも、毎秒十トークン以上の速度で推論できる、というのがポイントです。

使うときの注意として、一般的なllama.cppやOllamaではなくて、PrismML公式のBonsai-demoのリポジトリか、PrismML版のllama.cppフォークを使う必要があります。記事では、`setup.sh`を叩けば、依存関係のインストールからモデルの取得まで自動でやってくれる、という流れが紹介されています。
立ち上げは`start_llama_server.sh`でローカルサーバーを起動すると、このサーバーがOpenAI互換APIを提供してくれます。なので、既存のOpenAI向けのコードも、`base_url`をローカルのサーバーに差し替えるだけで、要約とか分類といった「頻度が高くて、できれば安く回したい処理」をローカルにオフロードできるわけですね。

モデルの使いどころも整理されていて、八ビリオンのBonsaiだと、ローカルチャットやテキスト要約、メールの下書き、オフラインRAGなどは、十分実用範囲。もう少し大きい二十七ビリオンのモデルになると、画像入力に対応していたり、関数呼び出しや長文コンテキストも扱えるので、「ローカル完結の小さなエージェント基盤」として狙えるレベルになってきます。

一方で、Claude CodeとかAiderみたいな、コーディングエージェントの頭脳としてガッツリ使うには、現状だと速度も性能ももう一歩という印象で、エージェント経由の高度な対話よりも、バックエンドでAPIを直接叩いて処理させるユースケースに向いているとコメントされています。

それから、一・五八ビットのTernary Bonsaiというバリアントも紹介されています。一ビットより少しだけ大きいんですが、そのぶん品質が上がっていて、メモリ八ギガバイトのPCとか、スマホクラスのデバイスでも動作報告があるそうです。エッジで動かす現実的な選択肢として、かなりおもしろい存在になりつつあるよ、という内容でした。

。。。。

さあ、三つ目。
三つ目は「安く自宅サーバーを作りたい」という人向けに、中古パーツや型落ちパーツを組み合わせて、予算十万円以内に収める構成例を紹介している記事です。

構成の例として出てくるのが、CPUにRyzenファイブの五六〇〇ジーティー、それをDeskMeet X三〇〇というコンパクトなベアボーンに載せて、メモリ三十二ギガバイト、SSD一テラバイト、OSはUbuntuという組み合わせです。筆者は秋葉原のショップを回って、この構成をだいたい九万五千円くらいでそろえたそうで、そのパーツ選びの手順も書かれています。

Ubuntuのインストールで気をつけたいポイントとして、まずルートパーティションの容量は、ケチらず最大まで広げておくこと。それから、インストール時に「OpenSSH server」にチェックを入れておくこと。この二つが挙げられています。こうしておくと、あとから開発用サーバーとして、外からSSHでつなぎやすくなるんですよね。

接続方法も二パターン説明されていて、同じ家の中、つまりローカルネットワークからは、ふつうにSSHで接続。外出先からは、Tailscaleを使ってプライベートネットワークを作る手順が紹介されています。
やり方としては、Tailscaleを自宅サーバーと手元のPCの両方にインストールして、サーバー側で`sudo tailscale up --ssh`と実行すると、そのサーバーに対して安全なSSH接続が可能になります。あとは、`ssh ユーザー名@デバイス名`みたいな形でつなげるようになるので、外からでも安心して自宅サーバーを操作できる、というわけです。

コスト面の話もおもしろくて、個人でGCPみたいなクラウドを使うと、毎月数千円から一万円くらいかかるケースも多いのに対して、自宅サーバーなら一度組んでしまえば、あとは電気代くらいで、開発用の検証環境や画像置き場なんかを低コストで運用できるのがメリットだとまとめています。
「クラウドもいいけど、趣味もかねて自宅サーバー一台持っておくと、けっこう遊べるよ」という雰囲気の記事でした。

。。。。

四つ目いきましょう。
四つ目は、GSC、Google Search ConsoleのAPIを使って、過去九十日分のデータから「平均掲載順位が悪いページ」を自動検出して、改善対象を機械的に洗い出すフローを作る、という記事です。

まずはGSC APIの認証設定ですね。OAuth二・〇の設定とトークン管理をして、`searchanalytics.query`というメソッドで、ページ単位のデータを取得する実装が紹介されています。これで、「どのURLの平均掲載順位が悪いのか」を一覧で取れるようになります。

次に、その低順位の記事たちをどう改善するか。記事では、データベースやスクレイピングを使ってページ本文を取得して、それをGemini APIに渡して「SEOライター」として書き直してもらう、というフローを説明しています。
プロンプト設計がかなり細かくて、目的は掲載順位の向上であること、狙いたいキーワード、見出し構成の改善、文字数、Markdown形式での出力などをしっかり指定します。同時に、「誤情報や架空のデータは書かないこと」という禁止事項も入れることで、変なコンテンツにならないようにガードしています。

リライトした結果はDBに保存しておいて、Next.jsのISR、増分静的再生成の機能を使って、対象のパスを`revalidatePath`で再生成します。さらに、IndexNowという仕組みを使って、更新したURLを検索エンジンにPOSTで通知する実装例も載っています。これによって、インデックスの反映を早めて、改善効果が出るまでの時間を短くする、という狙いですね。

最後に、DiscordのWebhookを使って、週次レポートを自動投稿する仕組みも紹介されています。順位の変化や、どの記事をリライトしたかなどをまとめて、あとは人間はそれを眺めるだけ、という設計です。
こうしたパーツを全部組み合わせることで、「低順位検出→リライト→公開→検索エンジン通知→効果確認」までを、人手なしでぐるぐる回るSEO改善パイプラインとして回し続ける考え方と、そのメリットが解説されていました。コンテンツ運用している人には、かなり刺さる内容かなと思います。

。。。。

そして最後、五つ目。
五つ目もTips系で、レシートのアップロード完了をサーバーに知らせるAPIエンドポイントの設計を解説した記事です。レシート管理アプリとか、経費精算みたいなサービスを作るときに、かなり実務寄りで参考になる内容です。

流れとしては、クライアントが「レシートのアップロードが終わったよ」とサーバーに知らせると、そのAPIがデータベースのstatusを、UPLOADINGからPROCESSINGに更新しつつ、バックグラウンドのOCRワーカーに処理を依頼します。

まず、Prismaで`receiptId`からレシート情報を取り出します。そのうえで、Firebase Adminを使ってJWTトークンを検証し、データベース上に記録されているユーザーIDと、トークンの中に入っているUIDが一致するかをチェックします。これで、「ちゃんとそのレシートの持ち主本人からのリクエストか」を確認しているわけですね。

次に、ステータスごとの振る舞いを分けることで、冪等性を確保しています。具体的には、statusがUPLOADINGのときだけ処理を続行して、PROCESSINGとかCOMPLETEDのときは、そのまま二百番台で成功レスポンスを返す。FAILEDのときは四〇九エラーを返して、再処理は受け付けない、というルールです。
これによって、クライアント側がネットワークの調子で同じリクエストをリトライしてきても、サーバー側で二重処理が走らないようにしています。

さらに、署名付きURLの有効期限切れをチェックしたり、GCS、Google Cloud Storage上にファイルがちゃんと存在するか確認したり、問題なければOCRワーカーへfetchで通知して、最後にステータスをPROCESSINGへ更新する、という流れになっています。

エラー処理の設計も凝っていて、AppErrorのような独自のエラークラスをまとめてcatchして、`instanceof`とプロトタイプチェーンを使いながら、HTTPステータスとメッセージを一元的に返す仕組みを取っています。これによって、APIの表側は常に整理されたエラーレスポンスを返せるようになるので、クライアント実装もシンプルになる、というわけですね。
実際にプロダクションでAPIを作るときに、そのまま設計のひな形として流用できそうな記事でした。

。。。。

ということで、きょうの「zenncast」は、全部で五本の記事をご紹介しました。
ざっとおさらいすると、まず一つ目は、React NativeプラスExpoのNew ArchitectureとHermesのおかげで、Reactエンジニアがウェブの感覚のままモバイルに挑戦しやすくなった、という話。
二つ目は、一ビット重みで動く超小型LLM、Bonsaiをローカルで動かして、要約や分類を安くオフロードするTips。
三つ目は、中古パーツを組み合わせて十万円以内で自宅サーバーを作り、Tailscaleでどこからでも安全にSSH接続する方法。
四つ目は、GSC APIとGemini、Next.js、IndexNow、Discordを組み合わせて、自動で回るSEO改善パイプラインを作るアイデア。
そして五つ目が、レシートOCR向けのAPIで、ステータス管理と本人確認、エラー設計まできちんとやる実務的な設計の話でした。

気になった記事があれば、詳しい内容はショーノートにまとめてありますので、あとでゆっくりチェックしてみてください。
この番組「zenncast」では、みなさんからの感想や、「こんなテーマ取り上げてほしい」といったリクエストも募集しています。開発の現場での小ネタや失敗談なんかも、大歓迎です。

それでは、きょうも一日、楽しくコードを書いていきましょう。
お相手はマイクでした。また次回のzenncastでお会いしましょう。ではでは。

Related episodes

内容の近いエピソードを推薦しています