この記事は、Bill One開発Unitブログリレー2025の第14弾です。

こんにちは、Bill One開発エンジニアの西野(@takapiro_99)です。
2025年6月から10月までの約5カ月間、AI自動照合機能の(プロダクト組み込み部分の)開発プロジェクトリードを担当しました。
本記事では、このプロジェクトで直面した課題と、それに対して実際に試した工夫をふりかえります。海外拠点や外部チームを含む体制で開発を進めている方にとって、ひとつの事例として参考になれば幸いです!
プロジェクト全体像
今回開発したのは、請求書と仕入れに関するデータを総額・明細単位で照合する「AI自動照合」機能です。 従来は請求書全体の合計金額での照合が中心でしたが、明細単位で照合できるようになることで、照合精度の向上や確認作業の負荷軽減が期待できます。
詳しくは次のプレスリリースをご参照ください。
体制は、日本拠点1チーム、セブ島にある開発拠点(Sansan Global Development Center、以下SGDC)3チームの計4チーム、総勢約20名。
加えて、請求書明細の構造化されたデータ化を開発するグループ会社(株式会社言語理解研究所)や、AI照合エンジンを開発する社内R&Dチームなどとの連携も必要なプロジェクトでした。
難しかった点
プロジェクトは、大きく3つのレイヤーに分かれていました。
- 請求書明細データ化:グループ会社での開発
- AI照合エンジン:社内R&Dチームでの開発
- プロダクトへの機能組み込み:日本拠点1チーム+SGDC 3チームの4チーム体制
設計段階では、これらはAPIを介して接続される疎結合なコンポーネントとして捉えていました。それぞれが独立して開発・改善されるという前提です。
ただ、実際に開発を進めると、いくつかの難しさが見えてきました。
ステークホルダーの多さと言語の壁
今回のプロジェクトは、プロダクト開発チームだけでなく、2つの外部チームと、設計・開発を同調させる必要がありました。ステークホルダーが多い分、「誰が何を決めていて、最新の仕様はどこにあるか」が曖昧になりがちでした。
加えて、日本側でも英語での情報共有の前提が揃っているとは言えず、言語による情報格差をどう吸収するかは、プロジェクトとして意識的に取り組む必要がありました。
多数のコンポーネントを結合した状態での品質確保
今回の機能は、請求書明細データ化・AI照合エンジン・プロダクト側の複数マイクロサービスが連携して初めて動作します。理想を言えば、各チームが開発を進めながら早い段階で「つないだ状態」を確認していくべきでしたが、スケジュールの都合上、後半でまとめて結合せざるを得ない状況でした。
各コンポーネントでのテスト実施後、「つないだ状態」での品質をどう担保するかも課題になりました。
やって良かったこと
情報の一元化とAI活用
Notionにプロジェクトのルートページを作成し、仕様、設計、議事録、テスト観点をすべて集約しました。狙いは、情報を置く場所を減らすことではなく、「迷ったときに全員が同じ入口から辿れる状態」を作ることです。
議事録はNotion AIで自動生成し、過去の議論や決定事項をAIへ質問できる状態にしました。ただ正直なところ、プロジェクト期間中の活用は限定的でした。当時のNotion AIは精度に課題があり、期待したほどの効果は得られませんでした。
プロジェクト終盤の9月下旬にNotion AI 3.0がリリースされ、パーソナルエージェント機能や、GPT-4oやClaude Sonnet 4といった強力なモデルが登場してから、実用レベルになった印象です。「口伝」に頼らず意思決定の背景を追える仕組みとして、今後のプロジェクトでは本格的に活用できそうです。
また、ドキュメントはNotion AIのAIカスタムブロック日英併記を徹底しました。翻訳の精度以上に、「同じ内容が同じ場所にある」ことが、情報共有の前提を揃えるうえで効果的でした。
QAチームにも早期から参画してもらい、テスト分析やテストケース作成にもNotion AIを活用しました。このように、上流工程でも積極的にAIを活用することで、ドキュメント作成やテスト準備の工数を削減し、より本質的な開発業務に集中できるようになりました。
バーチャルオフィスの模様替え
開発が進むにつれて、細かい認識合わせを同期的に行う場面が増えてきました。私たちは、音声通話や画面共有ができるTeamflow というバーチャルオフィスを使って日常的にコミュニケーションを取っていましたが、使用率はあまり高くありませんでした。実際には、各チームのデスクが離れた場所に配置されていて、話しかけるまでに一手間かかる状態でした。
そこで、Teamflow内のデスク配置を見直し、関係するチームをひとつのエリアに集約しました。距離感を縮め、気軽に声をかけられる環境を作る狙いです。
結果として、テキストで詰める前に「ちょっと確認したい」と声をかける場面が増えました。細かい疑問をその場で解消できるようになり、仕様のズレを早い段階で揃えられるようになったのは大きな変化でした。ちょっとしたことですが、オンラインであっても、メンバーの存在が視界に入ることで、チームとしての一体感が生まれることを実感しました。
Bug Bash
結合後、QA工程でバグ検出がなかなか収束してこなかったため、Bug Bashを実施しました。 Bug Bashとは、所定時間内でアプリケーションのバグを全員で見つけ出すイベント形式のテスト手法です。
リリースブランチを反映した専用環境を構築し、チームごとにユーザーアカウントを割り当て、自由に機能を触れる状態にしました。
当日はスプリントレビューを少し延長する形で、次の流れで進めました。
| フェーズ | 時間 | 内容 |
|---|---|---|
| Round 1 | 25分 | 自分の担当領域をテスト |
| 共有 | 5分 | 共有タイム |
| Round 2 | 25分 | 自チーム以外の領域をテスト |
| 共有 | 5分 | 共有タイム |
結果として、見落としていたバグや仕様のズレをリリース前に洗い出すことができました。短時間で多人数が同時に触ることで、同時実行時の整合性や、パフォーマンス面の違和感も表に出やすくなることが分かりました。
加えて、開発者自身がユーザー視点でプロダクトを触る機会にもなり、品質に対する共通認識を揃える効果もありました。
念のため第2回を「リリースリハーサル」として実施し、当日の流れをシミュレーションしました。ほぼバグを検出しない状態でリリースに臨めたのは、Bug Bashの効果が出た部分だと思います。
もっとうまくできたこと
おかげさまで、リリースは予定通り完了できました。 ただ、振り返ってみると「こうしておけばよかった」と思う点もあります。
段階的リリース
今回は、すべての機能を一度にリリースする形となりました。純粋な新規機能だったことを考えると、Feature Flagを活用した段階的リリースも有効だったはずです。段階的にリリースしていれば、本番環境での接続確認を早い段階で済ませられ、リリース当日の不安や作業量も分散できました。
スキーマ駆動開発
プロジェクト初期に、サービス間通信のインターフェースを定義し、設計ドキュメントとして合意しました。ただ、開発を進める中で仕様変更が少しずつ発生し、変更のたびに関係者間で合意を取り直す必要がありました。社内チーム内であれば比較的軽く回せる変更でも、外部チームや別組織が関わる場合は調整コストが増えます。
実は、プロジェクト初期にProtocol Buffersを使ったスキーマ駆動開発も検討しました。Bill One内での前例もあり、型レベルで契約を結べば変更時の不整合を機械的に検知できるメリットがあります。ただ、今回は準備の実装コストが大きかったこともあり、より慣れていたHTTP/REST(JSON)形式を選択しました。
結果的に、結合テストの段階でプロパティ名のずれなどの修正が複数発生しました。個々は小さな差分でも、結合フェーズで一気に顕在化すると、原因の切り分けコストが高くなります。今振り返ると、TypeSpecなどのスキーマ駆動のアプローチを導入できていれば、こうした手戻りを仕組みで減らせたはずです。
まとめ
今回のプロジェクトを通じて改めて感じたのは、結局のところ「プロジェクト管理の基本を愚直にやり切ることが一番効く」という点です。情報をなるべくオープンにし、不確実な部分を早めに洗い出して潰していく。この積み重ねが、海外拠点や外部チームとの協働においても効いてきました。
情報の一元化、バーチャルオフィスの模様替え、Bug Bashといった取り組みは、いずれも特別なものではありませんが、組み合わせることで効果を発揮しました。 今回の経験が、同じような体制で開発を進める方の参考になれば幸いです。
最後まで読んでいただき、ありがとうございました!
Sansan技術本部ではカジュアル面談を実施しています

技術本部では中途・新卒採用向けにカジュアル面談を実施しています。Sansan技術本部での働き方、仕事の魅力について、現役エンジニアの視点からお話します。「実際に働く人の話を直接聞きたい」「どんな人が働いているのかを事前に知っておきたい」とお考えの方は、ぜひエントリーをご検討ください。