
2026/06/24 17:54
味見のためにユニットテストを行うことはできません
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
著者は「In the Long Run」というアプリケーションを開発し、過去に歴史的名所を表示しようとした試みにおいて直面した重大なスケーラビリティの問題を解決するため、特定のルートを基盤として厳選された全世界の興味深いポイントを重ね合わせることで旅行地図を強化しています。本プロジェクトは、クリエイティブ・コモンズライセンスの下で提供される大規模な地理参照機能レポジトリである GeoNames を基盤としています。開発には Apache Parquet をストレージに使用し、クエリには DuckDB を使用する Python パイプラインが採用されており、開発支援として Claude AI コーディングエージェントも活用されました。このシステムは行政区分を除外し、公園、城館、山岳といった特定の機能コードのみを選択することで、生データを全球的に約 1300 万行から約 72.5 万件に削減しています。候補地点は GeoJSON バウンディングボックスとデフォルトの 50km の距離閾値を用いて特定のルート(例:アイスランドのリングロード、ケープタウン〜マグダガン)に対してマッチングされ、地図が単なる人口ヒートマップになることを防ぐために過疎地フィルタリングなどのルート固有のパラメータも追加的に適用されます。標準的なフィルタは客観的データを処理しますが、本アプリの独自の価値は、Anthropic の Haiku AI モデルを統合してランドマークに対する主観的な「味(テイスト)」評価を生成することにあります。このアプローチが重要な立ち止まり場所の特定に有用であることが証明されたものの、ハルシネーション(例:セントラルパークを誤分類)といった精度上の問題や、高いコスト(大きなルートバッチあたり約 10 ドル)の問題も発生しました。したがって、LLM を介したテキスト生成は見直されましたが、完全にユニットテスト化することが困難な主観的な評価には引き続きモデルが使用されます。最終的に、このオープンソースのパイプラインは、データ駆動型の精度と主観的な洞察の双方で地図を強化する方法を提供し、将来の反復版では手動でのオーバーライドやコミュニティフィードバックに依存することで改善が行われることを通じて、生地理情報と厳選された旅行体験との間のギャップを効果的に橋渡しします。
本文
アプリ「In the Long Run」開発ブログ:GeoNames 活用と LLM の適切な使い所を探る
「人生は短走ではなくマラソン」。私たちはランナーが世界各地の著名コースを仮想走行し、ストライダー(Strava)データを基に全距離での進行度を可視化するアプリを構築中です。長期的な動機付けこそが私たちのミッションです。
しかし、ユーザー自らが探索を楽しめる対話型地図を実現するにあたり、魅力的な景勝地や歴史的地点のデータ収集は大きな課題となりました。趣味への偏見や大規模言語モデル(LLM)による幻覚との格闘を経て、「AI は万能薬ではなく、補助的な道具の一つである」という結論に至りました。
本記事では、その開発プロセス、データパイプラインの構築、そして LLM をどう扱ったかについて振り返ります。
1. データ収集パイプラインの構築
プロジェクトをスケールさせるため、大規模な場所データのインテグレーションと処理に着手しました。Python と DuckDB という新しい技術スタックを採用し、学習曲線の管理を行いました。
技術スタック
- プログラミング言語: Python(ライブラリサポートが充実)
- データストレージ: Apache Parquet(ローカル保存)
- クエリ層: DuckDB(SQL クエリによる処理)
- LLM モデル: Anthropic の Haiku(コスト・速度のバランス重視)
開発方針:AI の適切な位置づけ
当初は AI が中核を担うことを想定していましたが、**「AI は既存ツールの一つに過ぎない」**という認識へ変化しました。主要な技術スタックを自分で理解しておくことで、エージェントを適切に操縦し、盲目に従うことなく情報に基づいた判断を下すことができました。
計画と反復改善
- プロジェクト当初から Claude(Anthropic)との連携で詳細な計画図を作成。
- 各マイルストーンごとに新しいエージェントセッションを開始し、前のステップの結果を短く要約して次へ文脈を渡す手法を採用。
- これにより、大きなコンテキスト依存による品質劣化を防ぎつつ、迅速で高品質なレスポンストライプを得ています。
2. データ前処理:注目性とバイアスの制御
GeoNames というクリエイティブ・コモンズライセンスのオープンデータソースを起点として、フィルタリングとバッチ処理を行いました。
ステップ 1:基本データの選定
ダウンロードした生データを結合し、不要なノイズを取り除く処理を実行。
- 除外対象: 国・州・地域などの行政区画情報。
- 選択対象(フィーチャーコード): パーク、歴史的建造物、城砦、記念碑、山岳など「興味深い地点」のみ。
- フィルター条件:
- 居住地:人口閾値を設定。
- 山岳:標高閾値を設定(偽陰性発生リスクありが許容)。
ステップ 2:注目性の指標追加
alternateNames.txt ファイルに含まれる Wikipedia リンクを活用しました。
- 利用方法: リンクの存在を「信号/関連性」の指標とし、Wikipedia 要約を文章データとして利用。
- 検証例: ストーンヘンジのような史跡も一時的に誤検知しましたが、フィルタリング設定を微調整することで改善。
成果: 当初の 1,300 万行から大幅削減され、約 72 万 5 千行のグローバル景勝地データを得ました。
ステップ 3:ルートの境界内フィルタリング
保有する各ルートと候補地点を一致させました。
- ルート用の GeoJSON から境界ボックスを作成し、遠い地点を除外。
- 残った地点に対して「ルート座標との距離」を計算(デフォルト 50km)。
とShapely
を使用し、ランナーが表示すべきタイミングの算出を実施。Pyproj
取得結果の偏り:
- イスラエント環状道路 (1,321km): 511 ポイント
- ケープタウン〜マガダン (23,257km): 約 1 万点
- ルート 66 (3,787km): 約 14 千点
問題: Wikipedia ベースの指標は**「英語話者が居住し、ウィキペディアを編集している地域」へのバイアス**が強いことが早期から明らかとなりました。
3. LLM の活用:幻覚と主観性の天秤
データを補完し評価スコアを生成する段階で、LLM の能力とその限界(幻覚)に直面しました。
スコアリングの経緯
- 初期試み: Wikipedia 要約や Wikidata を LLM に入力し、各地点の評価スコアを自動生成。
- 出力形式: Anthropic Markup Language (antml) など、ツール呼び出しの結果に奇妙なフォーマットが混入する等の不具合あり。
- コスト: バッチ処理を実施し、最大 50% の割引を利用。大規模ルート(1 万点以上)でも約 10 ドル程度で完結。
幻覚の発生と対策
初期プロンプトでは位置情報の制限が緩く、**「セントラルパークをイリノイ州デカターにある場所に誤認」**するなどの大きな幻覚が発生。
- 第 2 パス: 位置情報や行政データ(国・都市)を追加し、システムプロンプトで文脈を厳格に固定化。
- それでもなお: Haiku は町の人件変更や山の高さの誇張(90 年代映画『ビュータイ』のハUGH グラント演じるキャラクターのような挙動)が見られることが確認され、**「正確性よりも読みやすさを優先した LLM テキストは不適切」**と判断。
- 結論: 事実確認を重視し、LLM の要約テキスト生成自体を取りやめ、あくまでスコアリングのみでの活用に戻りました。
「主観的」評価の意義
事実誤認を防ぐために Wikipedia 要約を使用しましたが、**「重要性スコア」**の算出には依然として LLM を使用しています。
- 手法: フィーチャーコードと Wiki の言語版数(客観的指標)に加え、LLM による主観的評価を併用。
- 理由: 純粋に Wikidata に依存すると、150 の言語版を持つ小さな町すべてが重みなされすぎるため。
- 効果: LLM の「主観的な感覚」が、特に英語圏以外のルートにおいて**「より興味深い見どころ」を選別する助け**となりました。
注意点: 首都(レイキャビクなど)や巨大氷河であっても、プロンプトに明示的に指示されない限り、LLM はその重要性を過大評価しないよう慎重に対処しました。
4. 主観性の検証とパラメータ調整
完成したデータは JSON ファイルとしてバージョン管理対象となりましたが、「正解」と明確な単体テストが存在しないのが最大の課題です。
地域ごとの差異
- アイスランド: 自然・歴史・居住のバランスが良いルート。
- 人口密集地(都市部): ポイントがすべて都市部と集落に集中し、事実上「人口分布マップ」と化す傾向あり。
パラメータ調整の導入
この問題に対処するため、以下の調整を行いました。
- 人口フィルター: 極端な過密地域の除外。
- スコア相対評価: 「主観的」LLM スコアに対して、「客観的」Wiki リンク数を重み付け。
- 地理的重みづけ: ある半径内(例:都市圏)で見どころが飽和する場合は、郊外への表示バランスを調整。
検証の難しさ
- 困難点: 「機能か不機能か」で判断できる単純な指標にはならず、特定のルートに過剰最適化すると他の領域での劣化を招きやすい。
- アプローチ: データサイエンティストが用いる評価フレームワークや、手動によるオーバーライド(補正)による反復改善を継続。
まとめ:AI は道具である
開発を通じて得られた最も重要な教訓は、**「AI が問題を解決するのではなく、ツールボックスの中に新しい道具を追加されるに過ぎない」**という視点でした。
- 事実を捏造するリスクがあるため、LLM を事実確認ツールとして排除しました。
- その一方で、人間の直感を補完し「面白さ」を数値化するスコアリングツールとして活用しました。
- Ironyとして:このプロジェクト自体も、仕様書を提供してから AI に実装コードを書かせ、それを人間がレビュー・承認するという工程を経て完成しています。
現在、開発は V1 リリースへと至っており、
InTheLongRun.app において一部のルートで利用可能となりました。複雑な現実世界のデータを扱いながら、ランナー一人ひとりに新しい発見をもたらすことを目指してまいります。