コードを1行も書かずに市場価格サイトを作ったら、AIはナスを卵と間違え、私は相関を読み違えかけた
フィリピン農業省(DA)が毎日出している市場価格のPDFを読み取り、メトロマニラの市場の価格推移と、USD/PHP(米ドルとフィリピンペソの為替レート)との相関をブラウザで見られる静的サイト「Presyo Bantay」を、今日(2026年10月24日)非営利の地域プロジェクトとして公開しました。公開時点で39市場・34品目ぶんのデータが入っています。コードは1行も書かず、opencode(AIにコードを書かせるツール)と Muse というAIモデルに全部書かせました。Las Piñasの市場では、輸入米の価格がUSD/PHPと1〜2週間遅れで相関係数 r=+0.92 と強く連動していました(ただしデータは2か月分ほどです)。
ソースは GitHub にあります(MITライセンス)。Presyo Bantay はタガログ語で「価格の見張り番」くらいの意味です。
作った理由
フィリピンに住んで日本の会社にリモートで勤めていると、物価の話は他人事ではありません。PSA(フィリピン統計庁)の発表では、2026年9月のインフレ率は7.2%で、米は前年同月比+20.3%でした(PSA)。
一方で、DAは市場ごとの価格を毎日PDFで公開しています。データはあるのに、PDFなので一般の人がグラフで見たり比べたりするのは大変です。AIエンジニアとしてフィリピンの役に立てることはないかと考えていて、まず手を付けたのがこれでした。
仕組み
構成はかなりシンプルです。
- DAの一覧ページから価格PDFを取ってきて、
pdfplumber(PDFから表を読み取るPythonのライブラリ)で表を読み取る - 市場×品目の価格をSQLite(ファイル1つで動くデータベース)にためる
- USD/PHPはECB(欧州中央銀行)の参照レートを、無料の為替API「Frankfurter」経由で取得(2019-10-01〜2026-10-23の1,810日分)
- 静的サイト(Vite + TypeScript + uPlot というグラフ用ライブラリ)用にJSONを書き出して、GitHub Pages(GitHubの無料のサイト公開機能)で公開
- 取り込みはGitHub Actions(GitHub上で処理を自動で動かす仕組み)で毎朝6時(マニラ時間)に実行
サイトでは品目と市場を選んで価格の推移を見られて、USD/PHPを右軸に重ねたり、相関係数を出したりできます。表示はTaglish(タガログ語と英語のまぜこぜ)と英語の切り替えです。トラッキング、広告、ログイン、外部から読み込むスクリプト(CDN)は一切入れていません。JSは約74KB(gzipで約31KB)です。
公開時点のデータは2026-10-23までです。過去分のPDFは一覧に1,892件あり、DAのサーバーに負担をかけないよう間隔を空けて少しずつ取り込んでいるところです。
コードは全部 opencode の Muse に書かせた
今回、私はコードを1行も書いていません。仕様を決めて、レビューして、テストを回しただけです。コードと設定の変更は全部 opencode の Muse モデル(opencode-go/muse-spark-1.3-contributor)に書かせました。無料枠が大きいのが選んだ理由です。
午後に「どーんといこうぜ」で始めて、その日のうちに次のところまで進みました。
- PDFパーサー(Oct 23版のPDFで34市場×28品目を取得)
- SQLiteへの蓄積と過去分の取り込み
- 品目名の表記ゆれの統一とUSD/PHPの取り込み、相関の計算
- 静的サイトと、GitHub Pagesでの公開
最終的にPythonのテストが167件、サイトのテストが17件で、全部通っています。
Eggplant を卵扱いした件
1回目の実行(約3分)で、仕様はほぼ満たしていて24件のテストも通りました。ところがレビューしてみると、卵かどうかを品名に「egg」が含まれるかで判定していたため、Eggplant(ナス)まで「1個あたり」の価格として扱われていました。
もう1つ、毎日動かすGitHub Actionsの設定ファイル(workflow)に書き込み権限(permissions: contents: write)がなく、変更を記録(commit)してもGitHubへの送信(push)で失敗する状態でした。
この2点を指摘すると、2回目(約2分)で直りました。単位はPDFの見出しに付いている「*」で判定する方式に変わり、再発防止のテストも追加されています。
/tmp に書けなくて止まった件
opencode は /tmp(一時ファイル用のフォルダ)への書き込みを拒否する設定になっていて、作業用のファイルを /tmp に置こうとしたところで止まりました。リポジトリの中に .scratch/ を作って作業場所にし(.gitignore 済み)、そこを使うように指示して解決しました。
AIに任せるときは、テストが通るかどうかだけでなく、「何を根拠に判定しているか」をレビューで見るのが大事だと改めて感じました。Eggplant の件はテストが全部通った状態で見つかっています。
取り込み部分を Python から Go へ
今のところ、取り込みの部分はPythonで書いています。ただ、最近の脆弱性のニュースを見ていると、サーバーで毎日動かすものはできるだけリスクの少ないものにしたいと思いました。
そこで、取り込み部分を、Go言語で作る単一バイナリ(それ1つで動く実行ファイル)に書き直している最中で、これもMuseに書かせています。依存はできるだけ少なくし、今のPython版と同じPDFを読ませて結果がまったく同じになるかを突き合わせて確認する方針です。終わったら、サーバーにはGoのバイナリを1つ置いてcron(定時実行の仕組み)で回すだけにするつもりです。
これから
- 過去分(2019〜2025年前半)のPDFの取り込み。形式がまた違う可能性があります
- Go版への移行
- 週次のTaglishまとめの配信(機能自体はできていて、Telegramへの投稿を準備中)
数字はすべてDAとECBの公開データから計算していて、店ごとに実際の価格は違います。非公式の非営利プロジェクトなので、気軽に見てもらえるとうれしいです。
Las Piñas の価格とUSD/PHPの相関
最後に、私が住んでいるLas Piñasの市場(New Las Piñas City Public Market)で、価格とUSD/PHPの相関を計算してみました。使ったのはピアソンの相関係数 r で、−1〜+1の値をとり、+1に近いほど同じ向きに、−1に近いほど逆向きに動いていることを表します。価格の日 d と、d からラグ(ずらす日数)ぶん前の為替レートを組にして計算しました。
10月24日の夕方、過去分の取り込みが途中だった時点ではこうなりました。
| 品目 | r | メモ |
|---|---|---|
| 輸入米(Premium Rice, Imported) | +0.92(ラグ7〜14日) | 8/18以降の59日分しかないので参考値 |
| Galunggong(アジの仲間の大衆魚) | +0.70 | |
| 赤玉ねぎ(Red Onion) | −0.31 | ほぼ関係なさそう |
輸入米はペソ安から1〜2週間遅れて値上がりしているように見えます。ただし、Las Piñasの輸入米は2026-08-18より前のPDFにはそもそも載っていません。2か月分のデータで、しかもその間ペソ安と米の値上がりがどちらも続いていたので、たまたま同じ方向に動いただけの可能性も十分あります。
書いている途中で、表が古くなった
実はこの表、記事を書いている途中で古くなりました。
過去分の取り込みが進んだところで同じ計算をし直すと、輸入米はラグ7日・14日とも r=+0.92(n=58。n は比べた日数)のままでしたが、Galunggongは+0.70から+0.39前後(n=178)に下がり、赤玉ねぎは−0.31から−0.48前後(n=309)になりました。「ほぼ関係なさそう」と書いた赤玉ねぎのほうが、絶対値ではGalunggongより大きくなっています。
読み込みすぎていたのは私だった
Eggplantの件で、AIが何を根拠に判定しているかをレビューで見るのが大事だと書きました。途中までのデータで数字を読み込みすぎていたのは、AIではなく私のほうでした。相関は因果ではありません。r が高いのは「この期間に同じ方向に動いていた」というだけで、為替が原因で価格が動いたとは言えません。サイトの相関パネルに r と n、「相関は因果ではない」の注意書きを出しておいたのは正解でした。
コードは1行も書いていないので、この記事で間違えかけたのは私だけです。Presyo Bantay はまず、作った本人の見張り番として役に立ちました。