Otodoke(おとどけ)
荷物に、予定を合わせない。
どの店で買った荷物も、何がいつ届くか、いつ家にいればいいか、今月いくら使ったかが 1 つの画面で分かる荷物カレンダーです。最初にメールの自動転送を 1 回設定すれば、あとは何もしなくていい。届いた注文・発送のメールを Claude が読み取り、コードのルールで荷物ごとにまとめます。
作者が自分の 1 年分の注文・配送メール 341 通を読んで分かった、店や運送会社ごとの書き方の癖を、読み取りの規則の土台にしました(docs/email-field-map.md)。
Built with Claude: Japan 2026(2026-11-02 〜 11-08)の提出作品として作りました。コードはすべてこの期間に新しく書きました。最初のコミットは 2026-11-02 17:19(日本時間)です。
課題
作者は Amazon、楽天、メーカーの直販など、いくつもの店で買い物をしています。自分のメールを数えると、注文と配送のメールは 1 年で 341 通ありました。
- 何を注文したか忘れる
- 発送されたのか、いつ届くのか分からない
- 置き配できない荷物の日を覚えていられず、不在票が溜まる
- 今月ネットでいくら使ったか分からない
店のアプリは店ごと、運送会社のアプリは運送会社ごとです。全部をまとめて見る場所がありません。
日本では年に約 50 億個の宅配便のうち、およそ 3.8 億個が再配達になっています。宅配便の取扱個数 50 億 3147 万個(国土交通省、令和 6 年度)に、再配達率 約 7.6%(国土交通省、宅配に関わる大手 6 社、令和 8 年 4 月)を掛けた数です。受け取る側が「いつ家にいればいいか」を知らないことは、その一因です。
何が変わるか
- 家で待たなくていい。 置き配できるかを文面から読み分け、家にいる必要のある日をカレンダーで赤く出します。メールに受け取り方法が書いていない荷物は、断定せず「念のため対面」と分けて出します
- 店のアプリを渡り歩かなくていい。 店のメールと運送会社のメールを伝票番号でつなぎ、1 つの荷物として見せます。初めての店で買っても、そのまま読み取ります
- 使ったお金が分かる。 今月の合計を、店ごと・分類ごと(食費・日用品など 7 種類)に出します
- AI の言うことを確かめられる。 読み取った値には、元メールの根拠の行が付きます。自信のない値は断定せず「要確認」にします
試し方(1 分)
実際のメールは要りません。まず自分のアカウントを作り、サンプルで中身を見てから、使いたくなったら自動転送を設定します。
- https://otodoke.app を開き、ログインの画面の「アカウントを作る」で、メールアドレスとパスワードを決めます。画面が「確認のメールを送りました」に変わります。届いた確認のメール(件名「Otodoke のメールアドレスの確認」)のリンクを別のタブで開いて「確認する」を押すと、元のタブが自動でログインし、最初の案内(/app/welcome)に着きます。そこで「あとで」を押します
- 確認のメールは [email protected] から送ります。届くまで 1〜2 分かかることがあります。見当たらないときは迷惑メールのフォルダも見てください
- 進めないときは次を見てください
- パスワードは 10 文字以上です。同じ文字のくり返し、1234… や abcd… のような連番、password のようなよくある言葉と数字だけの組み合わせは使えません(アカウントを作る画面にも同じ決まりが出ます)
- 新規登録とログインでは、人かどうかの確認(Cloudflare Turnstile)が出ます。ボタンが「確認のチェックを押してください」になったら、チェックを押してください。押すと、そのまま進みます。「確認を読み込めませんでした」と出たら、ページを読み込み直すか、別のブラウザで試してください
- 確認のメールが来ないときは、アカウントを作る画面で送ったあとに出る「メールを送り直す」を押します
- 「回数が多いため、しばらく時間をおいてから、もう一度お試しください。」と出たら、少し待ってからやり直してください
- それでも届かないときは [email protected] へ書いてください
- 「設定」タブの「サンプルで試す」で「サンプルのメールを読み込む」を押します。匿名化した実際の注文・発送メールと、作り物の 1 年分の注文履歴が、今日の日付に合わせて入ります(中身は下の「持ち込んだデータ」。保存済みの読み取り結果を使うので、Claude API は呼びません)
- 見どころ
- 「荷物」: 実際のメールが、注文から配達まで荷物ごとにまとまります。作り物の履歴はすべて「配達済み」なので、これから届く荷物には並びません。赤い 🤝 の印が、家にいる必要のある荷物です(サンプルでは 4 つ)。メールに対面での受け取りが書いてあったものは「対面受け取り」と出ます。「念のため対面」は、メールに受け取り方法が書いていないので、念のため家にいる必要がある扱いにした荷物です(サンプルの 4 つのうち 3 つ。Amazon はふだん置き配なので、この扱いにしません)
- 荷物の詳細: 根拠の行が出るのは、メールに書いてあった荷物だけです。サンプルでは、状態が「不在・再配達」の荷物(ヤマト運輸から届いた 1 つ。店名は「送り主不明」と出ます)を開くと、受け取りの欄に「根拠: 「■受取ご希望場所:対面での配達を希望」」が出ます。「念のため対面」の荷物では、根拠の代わりに「メールに記載なし」と出ます。どの荷物も「元メールを見る」で、読み取りメモと元のメールを開けます(暗号化して保存したメールは、パスワードで開きます)
- 「カレンダー」: 家にいる必要のある日が赤く出ます
- 「支出」: 店・分類ごとの内訳と、月ごとの棒グラフ。「全期間」では、作り物の履歴の 1 年分の棒が分類ごとに色分けされて出ます
- 自分のメールで使うときは、「設定」の「メールの転送」を開き、画面に出ている自分専用の受信アドレスへの自動転送を、使っているメール(Gmail / iCloud / Outlook など)で 1 回だけ設定します。(やり方は転送設定ガイドにもあります)。設定は最初の 1 回だけで、あとは何もしなくても、届いた注文・発送のメールが荷物にまとまります。サンプルの荷物を消したいときは、「サンプルで試す」の「すべての荷物を消す」を使います
- iPhone では、Web 版のトップにある「iPhone アプリ(ベータ版)」から TestFlight で入れて、同じアカウントでログインします(TestFlight のアプリが要ります)。TestFlight の公開ベータで、参加できる人数に上限があります。上限に達しているときは、参加できないことがあります
仕組み
- アカウントを作ってパスワードでログインすると、あなた専用の受信アドレスが出ます(パスワードは、保存するメールの暗号化にも使います。下の「あなたのメールの扱い」)
- 自分のメール(Gmail / iCloud / Outlook など)で、そのアドレスへの自動転送を最初に 1 回だけ設定します。店ごとの設定はありません。やり方は転送設定ガイドにあります
- Gmail は今後、「Google でつなぐ」(gmail.readonly での読み取り)に切り替える予定です。転送とフィルタの設定が要らなくなります。Google の審査(restricted スコープの確認と CASA の評価)は、これから申請します
- 届いたメールは Resend の webhook(署名を検証)で受け取り、広告を落としてから Claude が読みます。荷物へのまとめと運送会社の判定はコードです
- 一覧・カレンダー・支出として表示します。画面からはいつでも元メールに戻れます(パスワードで開きます)
Claude をどう使ったか
アプリの中で:Claude には「判断」だけを任せる
- メールが注文・発送・配達・キャンセルのどれか、どの値が配達日か、「置き配指定可能」が定型の案内か本当の指定かを読み分けます
- 出力は zod のスキーマで固定し、値ごとに
evidence(原文の行)と confidence を持たせます。根拠のない値は確信度を低くし、画面で断定しません
- 使う API の機能は、目的ごとに選びました。読み取りは構造化出力(
messages.parse と zod)で形を固定し、毎回同じ長い指示はプロンプトキャッシュに載せます。ふるいの 2 段目の Haiku には「この人の買い物の連絡か」の真偽 1 つだけを答えさせ、API が失敗したときは荷物を落とさないよう、読む側に倒します。モデルが辞退したメールは、値を作らず、捨てもせずに、読み取れなかったメールとして残します
- 運送会社の判定と荷物の名寄せはコードとルールで書き、Claude には任せません。作り話が入る場所を減らすためです
コードの場所: 読み取りは src/lib/extract/extract.ts(messages.parse・プロンプトキャッシュ・辞退の扱い)、指示文は prompt.ts、出力の形は schema.ts、2 段目のふるいは triage.ts、全体の流れは src/lib/pipeline.ts。
費用で続かなくならないように。 届くメールを全部読ませると、使う人が増えるほど赤字になります。1 段目は無料のルール(店の許可リストは使わず、文面だけで判定。迷ったら通す)。迷うものだけ 2 段目で Haiku に聞き、残ったものを読みます。
モデルは実測で選びました。 手で正解を付けたデモ 17 通の結果です(docs/eval-log.md)。
| モデル | 項目の一致 | 17 通の費用 |
|---|
| Claude Opus 5.5 | 73/73 | $0.46 |
| Claude Sonnet 5.5 | 73/73 | $0.23 |
| Claude Haiku 5.5 | 73/73 | $0.02 |
Haiku は最初 71/73 でした。外れは時間帯の書式の違いで、これをコード側で直し、最新の測定(2026-11-06)は 73/73 です。匿名化した 341 通では種類の判定を確かめ(314/320)、既定を Haiku にしました。項目の一致を手で付けた正解と照らしたのは、この 17 通だけです。作者の 341 通を本番と同じ処理で読み込んだときの費用は、1 年分で約 0.4 ドルでした。デモボタンの結果は Opus 5.5 で事前に作って保存したもので、あとから人の手が入っています。商品の分類を 17 通すべてに手で付け、読み取りメモ 6 件を null や項目名の出ない日本語に書き直しました(読み取った値はこの時点では変えていません)。公開前の匿名化では、伝票番号 4 種類(7 件の読み取りの値と根拠の行)を架空の番号に替え、おすすめ商品について書いたメモ 1 件を消しました。
開発で:Claude Code を中心に、止める仕組みを先に置く
コードは Claude Code が書き、人は決めることと確かめることに回りました。期間中にコードを変えた 626 回のうち 624 回に、Claude Code が書いたという署名(Co-Authored-By)が付いています。Web アプリ・iOS アプリ(ios/)と、テスト(Web 205 ファイル・iOS 94 ファイル)を、1 人と Claude Code で作りました(2026-11-08 時点。枝をつなぐだけの併合の記録は数えていません)。
This is the beginning of the README. Read the rest at the original. Read the full README ↗