Site
全記事

公開日 2026年9月29日約11分で読了

ツーリズムアプリのためのAI Cities:すでに接続された12都市、ひとつの統合、そして出荷できる旅行プロダクト

AI Citiesで12都市がすでに稼働し、各都市が8つのシステムに接続されています。なぜ観光がこの配線に最初にフィットする製品面であるか、TypeScriptでのアーキテクチャ、今四半期に出荷できる4つの製品。

Renato Marinho

著者 Renato Marinho

Founder · Vinkius

AI Cities for tourism apps: a traveler question goes through one governed Vinkius connection over MCP, scoped per traveler with a signed audit trail, and fans out to six live city systems, mobility, culture, environment, geography, safety and public services, across twelve cities wired, eight systems per city and forty Connectors live in Amsterdam

AI Cities 公開以降、受ける問いが変わった。以前は「Connector とは何か」、今は「これを土台にプロダクトを作れるか」。聞くのはプラットフォームの人ではなく、目的地マーケティング組織、旅程プランナー、ホテルのコンシェルジュ製品の運用者だ。全員が同じスプレッドシートを持ってくる。1都市をカバーするための API 統合一覧だ。

この記事は在庫・アーキテクチャ・難しい部分で答える。要約:ツーリズムは、配線された都市がほぼ1対1で消費者プロダクトに写るドメインだ。旅行者は最初の72時間で8システムのうち6つに触れ、その一つひとつはライブの読み取りで、1都市用に書いた統合は12都市でも同じになる。

都市の最初のプロダクト・サーフェスとしてのツーリズム

AI Cities の都市は8システムに整理される。モビリティ、エネルギー、環境、公共サービス、文化、地理、商業、治安。これは都市政府の捉え方で、観光客の捉え方ではない。差が空いているところに旅行プロダクトは成立する。

アムステルダムを3日訪れる観光客を想定する。モビリティ:自転車ドック、路面電車、二度と見つからないパーキングゾーン。文化:今夜の公演と、チケット2枚が残るか。環境:9時の雨帯と水辺の大気。公共サービス:住所、記念物レコード、その裏のオープンデータセット。地理:距離、標高、坂道を避ける経路。商業:価格とカード。治安:6時に運河ルートを塞ぐ道路工事。

都市の8システムのうち6つを初日に横断し、観光客はシステムという名前を一度も知らない。これほど広く、これほど速く触れるカテゴリは他にない。

2つ目の理由はワークロードの形だ。ツーリズムは読みが重く書きが軽い。観光客は千の問いを投げ、数件だけ予約する。質問の瞬間にソースからライブで読み、Connector が動く箇所では都市でなくサービスに作用するデータプレーンにとってこれが理想だ。AI Cities ページの契約も明快で、エージェントが公共インフラを操作する手段はない。旅行プロダクトにとって制約ではなく、正しい契約である。

3つ目の理由は計算だ。見てきた旅行プロダクトは皆、同じ隠れ費目を持つ。統合だ。1都市をカバーするとは、交通、シェアサイクル、駐車場、天気、大気質、イベント、チケット、ジオコーディング、地域のオープンデータポータルを指し、それぞれに独自のキー、レート制限、エラー形状、変わる当日がある。都市数を掛ければ、ほとんどのプロダクトが3市場で止まる理由が出る。

正直な在庫:実際に配線されているもの

ベータで12都市が公開中だ。アムステルダム、ベルリン、リスボン、ロンドン、マドリード、モスクワ、ニューヨーク、パリ、リオデジャネイロ、サンフランシスコ、シンガポール、東京。いずれも汎用の世界フィードではなく、自都市向けの Connector が裏付けている。

アムステルダムは最も完成度が高く、本日40 Connector を跨ぐ8システムが稼働する。モビリティ:ライブのシェアサイクル CityBikes、TomTom Parking Availability、Google Maps、Mapbox、Uber、キー不要の都市パーキング・交通ゾーンデータセット。文化:Rijksmuseum アーカイブ、Eventbrite、Ticketmaster、Bandsintown、都市の登録イベント・会場・スポーツデータセット。環境・治安:AccuWeather、AirVisual、AQICN、OpenWeather、Open-Meteo、停電と道路工事の都市インシデントフィード、Global Flood Awareness System の洪水予報。公共サービス:122以上のデータセットを持つ DSO オープンデータエクスプローラー、BAG 住所登録、ごみ・リサイクルの収集日程、EU オープンデータポータル。

一覧を再読する価値がある。要点は混在だ。半分はアカウントが背後にある商用 API、半分は API キーなしで到達する都市自身の記録。旅行プロダクトには両方が要る。商用フィードがカバーと品質を、行政フィードが都市しか知る事実を出す。どの岸壁が閉鎖中か、嵐でどの木が倒れたかのような。

この在庫には2つのルールが付き物で、どのチームにも押し付ける。1つ目。都市ページは本日配線済みと接続中のシステムを明記し、ロードマップでなく存在するものに機能を約束する。2つ目。そのページのすべては質問した瞬間のライブ読み取りで、事前キャッシュはない。古い時刻表を出荷してプラットフォームのせいにはできない。

1つの問いが1本の Vinkius 接続でモビリティ、文化、環境、地理、治安、公共サービスに扇状展開し、1つの回答が返る

これはもう一つの旅行 API ではない

旅行に API があるのは何十年も前からだ。Amadeus と Duffel の世界、GDS の系譜はインベントリを解く。座席、運賃、予約、変更。取引には優れ、場所については何も知らない。14:00に着陸するフライトは教えてくれる。ホテルへの道路が6時に閉じることも、沿線の AQI が上がることも、今夜唯一のライブが3つ先にあることも教えてくれない。

都市レイヤーは2つ目の問い群に答え、両者は競合ではなく補完だ。運賃はあって街がないプロダクトは予約エンジン、街はあって運賃がないプロダクトはガイド。面白いプロダクトは両方を持ち、これまで両方を持つことは、維持曲線の異なる2つの統合プログラムの所有を意味した。

それが本当のシフトだ。取引 API は最初から借りるコモディティだった。都市側はコモディティとして一度も存在しない。自治体と統合するか、データを持たないかの二択だ。AI Cities は配線済みのすべて都市に同じ呼び出しパターンで、都市側を借り物にする。

アーキテクチャ:1つの統合、12都市

内部で各 Connector は MCP で公開される。MCP は既に使うアシスタントが話すオープンプロトコルだ。アプリケーションはダッシュボードで一度作る公開の app id と秘密の application key で識別される。旅行者には既に割り当てている id で宛らい、それぞれに SDK が接続済み都市システムへのスコープ付きハンドルを返す。Vinkius が接続をプロビジョニングし、資格情報を保持し、統治されたデータプレーンの背後で実行する。コードは上流の鍵も、OAuth も、都市ごとのリトライループも持たない。

スコープの単位はテナントではなく旅行者だ。これは旅行プロダクトで最も強く守りたい設計判断だ。誰かの予約を変更できるコンシェルジュが安全なのは、触る予約が質問者本人のものであるときだけだ。旅行者ごとの Connector は各自のトークンを持つ独立した接続で、各自のランタイム内で列挙・実行され、別々に計測・停止される。分離はポリシードキュメントではなく、データパスの形で強制される。

以下がループだ。SDK サンプルからそのまま、旅行者の都市システムをツールセットとして:

import OpenAI from 'openai';
import { Vinkius } from '@vinkius/connect';
import { toOpenAITools, runOpenAIToolCall } from '@vinkius/connect/openai';

const openai = new OpenAI();
const MODEL = process.env.OPENAI_MODEL ?? 'your-model-id';

const vinkius = new Vinkius({
  appId: process.env.VINKIUS_APP_ID!,
  apiKey: process.env.VINKIUS_APP_KEY!,
});

export async function concierge(userId: string, question: string) {
  const caps = await vinkius.user(userId).capabilities();
  if (caps.length === 0) {
    return 'Connect a city first and I can answer that live.';
  }

  const tools = toOpenAITools(caps);
  const messages = [{ role: 'user', content: question }];

  for (let step = 0; step < 4; step++) {
    const reply = await openai.chat.completions.create({ model: MODEL, messages, tools });
    const msg = reply.choices[0]?.message;
    if (!msg?.tool_calls?.length) break;

    messages.push(msg);
    for (const call of msg.tool_calls) {
      const result = await runOpenAIToolCall(caps, call, {
        idempotencyKey: `${userId}:${call.id}`,
      });
      const text = result.content.map((c) => c.text).join('\n');
      messages.push({
        role: 'tool',
        tool_call_id: call.id,
        content: result.isError ? `The tool reported an error: ${text}` : text,
      });
    }
  }

  return reply?.choices[0]?.message?.content ?? '';
}

その関数に都市固有のコードはない。アムステルダムにいることを知らない。都市は旅行者が接続した capabilities 経由で届く。だから同じ関数が12都市と13都市目を分岐なしで処理する。

実例:1つの問い、5システム

「14:00に子供とベビーカーで着陸します。今夜は博物館の近くでどこで食べ、雨が降ったらどう行けばいいですか」

その回答が正直になるまでに何が起きるかを追う。

  1. ホテルと博物館を座標に解決する。地理:LocationIQ か OpenCage。
  2. 時間帯の雨帯と大気質を読む。環境:Open-Meteo と AccuWeather、沿線は AQICN。
  3. 近くで今夜何があるか、チケット2枚があるかを読む。文化:都市イベントデータセット、Eventbrite、Ticketmaster。
  4. 推薦予定の経路のインシデントフィードを確認する。治安:都市のステータス・インシデント Connector。
  5. 移動手段を選ぶ。ドックの自転車、路面電車、会場近くの駐車場。モビリティ:CityBikes、TomTom、Google Maps。

5システム、1つの会話、しかも旅行者は何もインストールしていない。各ステップはモデルが選んだツール呼び出し、各結果はライブの読み取りで、すべての呼び出しは旅行者 id 付きで監査証跡に残る。4ステップで岸壁の閉鎖が返れば、回答はゲストがそこに立った後ではなく送信前に変わる。

難しい点を率直に言う

都市ごとの差は本物だ。 アムステルダムは40 Connector を跨ぐ8システムを配線済み。リスト内の別の都市はモビリティと環境が動いていても、公共サービスは接続中かもしれない。エンジニアリングの答えは、実行時に capabilities を列挙し、変化する集合を前提に設計することだ。都市マトリクスを設定ファイルにハードコードしない。ユーザーに見せる答えは誠実さ、何がどこで使えるかを言えること。

鮮度こそが約束のすべてだ。 旅行プロダクトは路面電車が動いてるかで生死を分ける。読み取りは質問の瞬間に起きるので、設計すべき失敗は古いデータではなく、上流が一時的に使えなくなることだ。ツールレベルの失敗は例外ではなく結果として扱い、モデルには出発時刻を捏造させず、今は分からないと言わせる。

アクションは意図的に狭い。 Connector が動くのはサービスに対してだけだ。予約の確保、席の確保。公共インフラには決して動かない。読み取りと少数の明示的な書き込みを作れば、その境界に出会うことはない。都市の交通の時刻を変更できると前提したプロダクトは、出荷できないものを作る。

すべての呼び出しは記録に残る。 すべては Vinkius 上で動く。接続ごとの孤立した V8 実行、34以上のセキュリティルール、各操作の署名付き監査証跡、驚かずに止まる支出上限、すべてのエージェントを止める1つのスイッチ。消費者向け旅行プロダクトにとって、これは「昨夜 AI が変なことをした」という言葉と、ツール・旅行者・時刻を名指す領収書の違いだ。コントロールプレーンは AIガバナンス:エージェントのすべてのツール呼び出しの背後にあるコントロールプレーン に、サンドボックスそのものは 信頼できないコードのゼロコールドスタート に書かれている。

今四半期に出荷できる4つのプロダクト

1日のトリップコンシェルジュ。 チャットが先で、ダウンロードなし、サービスごとのログインなし。9時の雨、オフィス脇ドックの自転車、夕食前の2枚、22:50の最終電車。会話の入力はすべて、既に持っているライブの読み取りだ。

快適性とバリアフリーを考慮したルーター。 坂道を避け、AQI の高い沿線を避け、閉鎖された岸壁を避け、駅の段差を避ける旅程。大気質、標高、インシデント、経路は別の Connector で、それらを組み合わせることがプロダクトだ。既存のマップアプリはどれも組み合わせない。

目的地向けバックオフィス。 目的地マーケティング組織やホテルグループ向けに、今日のイベント、今夜の会場、オープンデータセットとインシデントフィードをサイトやメッセージングアシスタントに流す。昨年春に最終更新した静的ページではなく、訪問者の言語で答える。

既存の旅行プラットフォーム向け都市レイヤー。 ユーザーも予約も既にあれば、利点は別だ。1つの統合で済み、配線された都市が増えるたび、新しい統合プロジェクトなしで開ける市場になる。

ビルドは配線が終わったところから始まる

AI Cities のデモはアシスタントに都市を尋ねてライブの回答を得ることだ。それがプロダクトではない。プロダクトは同じ Connector の上で作り、プロトコルが下にあったことなど決して知らない旅行者のためのものだ。

AI Cities の索引 から始めて、気になる都市を開き、本日どのシステムが動くかを読む。次に AI Connect SDK で配線し、本来あるべきだったローカルアプリを作る。

トピックai-citiestourismconnectorsmcptravel