
MaaS
イベント
該当するコンテンツが見つかりませんでした
マガジン
技術ブログ
G-gen の佐々木です。当記事では、Pub/Sub から直接 Vertex AI 上の AI モデルによる推論を取得することができる AI 推論 SMT 機能について解説します。 前提知識 Pub/Sub とは Single Message Transforms(SMTs) AI 推論 SMT の機能 基本事項 AI 推論 SMT の利点 使用できるモデル Model Garden で提供されているモデル Vertex AI Endpoints にデプロイしたモデル モデルの入力・出力 入力するメッセージの形式 推論後のメッセージの形式 制限事項 設定手順 手順の概要 サービスアカウントの作成・権限付与 定義ファイルの作成 トピックの作成 AI 推論 SMT を使用するサブスクリプションの作成 動作確認 メッセージのパブリッシュ メッセージの受信 前提知識 Pub/Sub とは Pub/Sub は Google Cloud におけるフルマネージドなメッセージングサービスです。 メッセージングサービスは、システム間に配置することでメッセージを非同期に中継することができます。これにより、システムの拡張性や保守性を向上することができます。 Pub/Sub を始めとしたメッセージングサービスの詳細やユースケースについては、以下の記事をご一読ください。 blog.g-gen.co.jp Single Message Transforms(SMTs) Single Message Transforms (以下、 SMTs )は Pub/Sub を使用したストリーミング処理のパイプラインにおいて単純なデータ変換を実現する機能です。 この機能では、Pub/Sub のトピックとサブスクリプションのそれぞれに対して単純なデータ変換処理を実装します。これにより、データの形式の変換やマスキング、フィルタリングなどの処理を、メッセージの配信前に行うことができます。 SMTs の詳細については、以下の記事をご一読ください。 blog.g-gen.co.jp AI 推論 SMT の機能 基本事項 当記事で紹介する AI 推論 SMT (AI Inference Single Method Transform)は、SMTs の機能の1つであり、Vertex AI にある AI モデル(Gemini など)に Pub/Sub のメッセージを渡し、 推論を取得してメッセージに追加することができる 機能です。 通常の SMTs 同様に、AI 推論 SMT はトピックとサブスクリプションのどちらでも設定することができます。 トピックに設定した場合、推論結果がメッセージに追加されたあと、トピックに紐づくすべてのサブスクリプションにメッセージが配信されます。 トピックに対して AI 推論 SMT を設定した場合 サブスクリプションに設定した場合は、そのサブスクリプションでのみ推論を取得するような動作となります。Pub/Sub のユースケースに合わせて設定するとよいでしょう。 サブスクリプションに対して AI 推論 SMT を設定した場合 参考 : AI 推論 SMT 参考 : 単一メッセージ変換(SMT)の概要 - SMT のサンプル メッセージ フロー AI 推論 SMT の利点 AI 推論 SMT を使用してモデル推論とデータ変換を行う場合、以下のようなメリットがあります。 メッセージに対してリアルタイムで AI モデルによる推論結果を追加することができる(データ エンリッチメント) モデルから推論を取得するための処理をアプリケーション側に実装する必要がなくなる サブスクリプションに設定した場合、Pub/Sub はモデル エンドポイントの過負荷を回避し推論のスループットを最大化するため、リクエストレートを最適化する(フロー制御) ※ 単項 pull では最適化されない点に注意 参考 : AI 推論 SMT - メッセージ フロー 使用できるモデル Model Garden で提供されているモデル AI 推論 SMT では、トピックまたはサブスクリプションを作成する際にモデルの推論用のエンドポイントを指定します。 Vertex AI Model Garden で提供されているモデルを使用する場合、以下のような形式でエンドポイントを指定します。 - ai - aiInference : endpoint : "projects/<プロジェクトID>/locations/<モデルを利用するリージョン>/publishers/<モデルのパブリッシャー>/models/<モデル名>" 使用できるモデルの一覧については、以下のドキュメントで最新の情報を確認してください。 参考 : AI 推論 SMT - 互換性のある MaaS モデル Vertex AI Endpoints にデプロイしたモデル ユーザーが Vertex AI Endpoints を使用して Google Cloud 上にデプロイしたモデル(セルフデプロイ モデル)を推論に使用することもできます。 セルフデプロイ モデルを使用する場合は、モデルのエンドポイントの指定の仕方が異なります。 - aiInference : endpoint : "projects/<プロジェクトID>/locations/<エンドポイントのリージョン>/endpoints/<エンドポイント>" 参考 : エンドポイントにモデルをデプロイする モデルの入力・出力 入力するメッセージの形式 AI 推論 SMT による推論を行うためには、Pub/Sub に入力されるメッセージが特定の形式になっている必要があります。 例えば gemini-2.5-flash のような Gemini 基盤モデルを使用する場合、 Chat Completions API を使用して Gemini が呼び出されるため、以下のように Pub/Sub トピックに送信するメッセージの形式を API の仕様に合わせます。 { " model ":" google/gemini-2.5-flash ", " messages ": [ { " role ": " user ", " content ": " Explain how AI works in a few words " } ] } 参考 : AI 推論 SMT - メッセージ処理 推論後のメッセージの形式 AI 推論 SMT によって取得したモデルのレスポンスは、以下のように元のメッセージに追加されます。 { " original_message ": " <元のメッセージ> ", " model_output ": " <推論によって取得したモデルのレスポンス> " } 制限事項 AI 推論 SMT には以下のような制限事項があります。 トピックまたはサブスクリプションに設定できる AI 推論 SMT の数は1つまで Vertex AI Endpoints のプライベート エンドポイントはサポートされていない(公開エンドポイントのみ使用可) グローバル エンドポイントは、Gemini 基盤モデルでのみサポートされる。その他のモデルではリージョン エンドポイントのみ使用可能 Pub/Sub 側では入力されたメッセージのデータ形式などの検証は行われない。トピックにメッセージを送信する前に検証する必要がある 1つのメッセージごとに1つの推論リクエストのみが可能であり、バッチ推論は不可 指定したモデルによる推論は60秒以内に完了する必要がある 推論が60秒を超過するとタイムアウトとなり、Pub/Sub に設定したメッセージ保持期間と再試行回数の上限まで再試行が行われ、その後デッドレタートピックにメッセージが転送されます。 その他、制限事項に関する最新情報は以下のドキュメントをご一読ください。 参考 : AI 推論 SMT - 制限事項 設定手順 手順の概要 当記事で紹介する手順は、サブスクリプションに対して AI 推論 SMT によるメッセージ変換を設定し、そのサブスクリプションのコンシューマーに対してのみ推論結果を含めたメッセージを配信できるようにするためのものです。 参考 : AI 推論 SMT - AI 推論 SMT を作成する サービスアカウントの作成・権限付与 AI 推論 SMT を使用する場合、Cloud Pub/Sub サービスエージェント( service-<プロジェクト番号>@gcp-sa-pubsub.iam.gserviceaccount.com )に対して Vertex AI サービス エージェント ( roles/aiplatform.serviceAgent )ロールを付与するか、カスタムサービスアカウントに対して Vertex AI ユーザー ( roles/aiplatform.user )ロールを付与します。 当記事ではカスタムサービスアカウントを使用します。 # サブスクリプション用のサービスアカウントを作成 $ gcloud iam service-accounts create pubsub-ai-inference-smt \ --display-name =" Pub/Sub AI Inference SMT " # Vertex AI ユーザー ロールの付与 $ gcloud projects add-iam-policy-binding < プロジェクトID > \ --member =" serviceAccount:pubsub-ai-inference-smt@<プロジェクトID>.iam.gserviceaccount.com " \ --role =" roles/aiplatform.user " 定義ファイルの作成 ai-smt.yaml という名前で AI 推論 SMT の定義ファイルを作成します。これをトピックもしくはサブスクリプションの作成時に指定することで、AI 推論 SMT を使用することができます。 - aiInference : endpoint : "projects/<プロジェクトID>/locations/asia-northeast1/publishers/google/models/gemini-2.5-flash" unstructuredInference : { parameters : { "temperature" : 0.5 , "max_tokens" : 1000 } } serviceAccountEmail : "pubsub-ai-inference-smt@<プロジェクトID>.iam.gserviceaccount.com" endpoint にはモデルのエンドポイントを指定します。 unstructuredInference.parameters には、モデルに推論リクエストを送信する際のパラメータや最大トークン数などを指定できます。 serviceAccountEmail には、先ほど作成したサービスアカウントを指定します。 トピックの作成 Pub/Sub のトピックを作成します。 # トピックの作成 $ gcloud pubsub topics create ai-smt-topic トピックに AI 推論 SMT を設定する場合、ここで --message-transforms-file オプションを使用します。 参考 : gcloud pubsub topics create AI 推論 SMT を使用するサブスクリプションの作成 トピックに紐付けるサブスクリプションを作成します。 当記事ではサブスクリプション側に AI 推論 SMT によるメッセージ変換処理を設定するため、 --message-transforms-file で先ほど作成した定義ファイルを指定します。 # AI 推論 SMT を使用するサブスクリプションの作成 $ gcloud pubsub subscriptions create ai-smt-topic-sub \ --ack-deadline = 600 \ --topic ai-smt-topic \ --message-transforms-file ai-smt.yaml 動作確認 メッセージのパブリッシュ 作成したトピックに対してメッセージをパブリッシュしてみます。 AI 推論 SMT で Gemini モデルを指定しているため、 --message には、 Chat Completions API の仕様に合わせた形式でメッセージを設定します。 # プロンプトを含むメッセージのパブリッシュ $ gcloud pubsub topics publish ai-smt-topic --message =$' { "model":"google/gemini-2.5-flash","messages":[{ "role": "user", "content": "Vertex AI について簡単に説明して" }] } ' 参考 : gcloud pubsub topics publish メッセージの受信 サブスクリプションに配信されたメッセージを確認します。 # メッセージを受信し、データを復号したあと JSON に変換 $ gcloud pubsub subscriptions pull ai-smt-topic-sub \ --auto-ack \ --format =" value(message.data.decode(base64)) " | jq . 受信したメッセージには、元のメッセージである "original_message" に加え、サブスクリプション側の AI 推論 SMT によって "model_output" が含まれていることがわかります。 以下は受信したメッセージの例です。 { " model_output ": { " choices ": [ { " finish_reason ": " stop ", " index ": 0 , " logprobs ": null , " message ": { " content ": " Vertex AI は、Google Cloud が提供する、**機械学習(ML)開発のための統合プラットフォーム**です。 \n\n 簡単に言うと、MLモデルを開発する際に必要な「データの準備」「モデルの構築」「トレーニング」「デプロイ(公開)」「監視・管理」といった**あらゆる工程を、一つの場所で効率的に行えるようにするための「ワンストップショップ」**のようなものです。 \n\n **主なポイント:** \n\n 1. **統合された環境:** これまでバラバラだったML開発のツールやサービスを一つにまとめ、開発プロセスをシンプルにします。 \n 2. **効率化と高速化:** データサイエンティストやMLエンジニアが、インフラの管理に時間を取られることなく、モデルの開発や改善に集中できるよう設計されています。 \n 3. **幅広い対応:** カスタムモデルの構築はもちろん、画像認識や自然言語処理などの特定のタスクに対応した事前学習済みモデルの利用や、AutoML(自動機械学習)機能も提供します。 \n 4. **スケーラビリティ:** Googleの強力なインフラ上で動作するため、大規模なデータや複雑なモデルのトレーニングも柔軟に対応できます。 \n\n 例えるなら、ML開発に必要なあらゆる道具が揃った「高機能な作業台」のようなものです。これにより、企業はより迅速にMLをビジネスに導入し、価値を生み出すことができるようになります。 ", " role ": " assistant " } } ] , " created ": 1775550770 , " id ": " MsHUaYLcFaKTp_QP1_SwiAw ", " model ": " google/gemini-2.5-flash ", " object ": " chat.completion ", " system_fingerprint ": "", " usage ": { " completion_tokens ": 263 , " completion_tokens_details ": { " reasoning_tokens ": 1066 } , " extra_properties ": { " google ": { " traffic_type ": " ON_DEMAND " } } , " prompt_tokens ": 6 , " total_tokens ": 1335 } } , " original_message ": { " messages ": [ { " content ": " Vertex AI について簡単に説明して ", " role ": " user " } ] , " model ": " google/gemini-2.5-flash " } } 佐々木 駿太 (記事一覧) G-gen 最北端、北海道在住のクラウドソリューション部エンジニア 2022年6月に G-gen にジョイン。Google Cloud Partner Top Engineer に選出(2024 / 2025 Fellow / 2026)。好きな Google Cloud プロダクトは Cloud Run。 趣味はコーヒー、小説(SF、ミステリ)、カラオケなど。 Follow @sasashun0805
はじめに NTTビジネスソリューションズの辻本です。 この記事では、NTTの国産LLM「tsuzumi」を用いたRAG実装をガイドするとともに、ベースモデル(RAGなし)とRAG構成を同一の質問で実行し、精度・応答時間の実測値に基づいて効果を比較検証した結果を紹介します。 なお、本記事中で扱うサービス(Microsoft Azureなど)に関する記載は2025年11月時点の情報に基づきます。また、比較検証結果は筆者の実行環境・設定に依存し、 記事内で掲載しているコードは、理解しやすさを優先した簡略版(抜粋)です。実際の実装には、エラーハンドリングなどが含まれています。 対象読者 LLM(大規模言語モデル)を初めて触る方 Azureを使ったことはあるが、AI機能は初めての方 RAGという言葉を聞いたことはあるが、実装経験がない方 tsuzumiとRAG tsuzumiとは tsuzumiは、NTTが開発した日本語に特化した大規模言語モデル(LLM)で、軽量ながら高い日本語処理能力を持つとされています。 特徴 : Azure上で利用可能 : MaaS(Model as a Service)形式で提供されており、サーバー管理不要 軽量モデル : 7B(70億)パラメータで、大規模モデル(175B等)よりコンパクト RAG(検索拡張生成)とは なぜRAGが必要なのか : ベースモデルの制約 : LLMは基本的に学習データに含まれる範囲をもとに回答する 例: 企業固有の情報(社内マニュアル等)は学習していない場合が多い RAGの考え方 : 最新情報や専門知識を検索して、LLMに与えたうえで回答させる RAGの仕組み : 質問「NTTパビリオンのテーマは?」 ↓ ① ベクトル検索 ──→ ナレッジベース ↓ (8つのMarkdownファイル) ② 関連コンテキスト取得(Top 3件) ↓ ③ LLM(tsuzumi)へ送信 ↓「この情報を参考に回答して」 ④ 回答生成「PARALLEL TRAVELです」 RAGの仕組み(ステップバイステップ) : ユーザーが質問 : 「NTTパビリオンのテーマは?」 ベクトル検索 : 質問に関連する情報をナレッジベースから検索 ナレッジベース=事前に用意した文書集(Markdownファイル等) ベクトル検索=文章の意味的な類似度で検索 コンテキスト取得 : 関連度の高い情報をTop 3件取得 LLMへ送信 : 「この情報を参考に回答して」と質問+情報をセットで送る 回答生成 : LLMが情報を基に回答を生成する 今回のユースケース 題材 : 大阪・関西万博のNTTパビリオン案内ボットを構築し、tsuzumiのベースモデルとRAG構成を定量的に比較する ナレッジベース : 8つのMarkdownファイル knowledge/ ├── 01_overview.md # パビリオン全体概要 ├── 02_zone1.md # Zone1(コミュニケーション歴史) ├── 03_zone2.md # Zone2(IOWN × Perfume) ├── 04_zone3.md # Zone3(Another Me) ├── 05_finale.md # 参加型フィナーレ ├── 06_architecture.md # 建築コンセプト ├── 07_technology.md # 技術(IOWN, tsuzumi) └── 08_faq.md # よくある質問 環境構築 ステップバイステップ実装 Step 1: プロジェクト作成 tsuzumiのデプロイや利用方法について記事の下部に 参考リンク があるためこちらもご参照ください。 AI Foundryの概要ページ AzureポータルでFoundryを検索し、概要ページを表示します。「リソースの作成」を選択してください。 リージョンは East US 2 で作成します。 リソースグループの作成 Step 2: tsuzumi-7bデプロイ(Marketplace経由) AzureポータルからAzure Marketplaceを表示し、tsuzumiを検索します。 Marketplaceでtsuzumiを検索 検索結果から「購読する」を押下すると表示される「NTTDATA tsuzumi-7B Instruct」を選択すると、AI Foundryへ自動的に遷移します。「このモデルを使用する」を選択してください。 モデル選択画面 プロジェクトを作成します。下部の「高度なオプション」を開くとリソースグループを選択できます。プロジェクト名を入力し、先ほど作成したリソースグループを選択して「作成」を選択してください。 ⚠️ 新規作成する場合は、リージョンを「East US 2」に設定してください。 プロジェクト作成画面 作成処理が実行されます。 自動設定の実行中 プロジェクトの設定が完了すると、API情報を含む概要画面が表示されます。 tsuzumiデプロイ完了 Step 3: Pythonプロジェクト作成 仮想環境(venv)を利用します。 # プロジェクトディレクトリ作成 mkdir tsuzumi-rag-demo cd tsuzumi-rag-demo # 仮想環境作成 python3 -m venv venv # 仮想環境の有効化 source venv/bin/activate 依存関係インストール : pip install fastapi uvicorn chromadb sentence-transformers openai Step 4: 環境変数の設定 Azure AI Foundryで表示される設定情報から .env ファイルを作成します。 # Azure AI FoundryのエンドポイントとAPIキー AZURE_MAAS_ENDPOINT=https://xxx-xxx-xxxxx.xxx.xxxxx.xxx.xxx.xxx AZURE_MAAS_API_KEY=your-api-key-here ナレッジベースの準備 Markdownファイルの作成 knowledge/03_zone2.md の例: --- title: "Zone2: IOWN × Perfume ライブ体験" category: "exhibition" keywords: ["IOWN", "Perfume", "3D伝送"] --- # Zone2: IOWN × Perfume ライブ体験 ## 概要 Zone2は、IOWNを使って離れた場所のライブパフォーマンスを まるで目の前で繰り広げられているかのように体験できるゾーンです。 ## 技術的特徴 - **3D点群データのリアルタイム伝送**: 従来の映像とは異なり、人物の3D形状をリアルタイムで伝送 - **床振動装置**: 音楽に合わせた触覚フィードバック - **超低遅延**: IOWNによりライブ感を損なわない伝送 ## 体験内容 Perfumeの3人がリアルタイムでパフォーマンスを披露。 離れた場所にいるにも関わらず、まるで同じ空間にいるかのような臨場感を体験できます。 ナレッジベース読み込みスクリプト scripts/load_knowledge.py : from app.services.chroma_service import ChromaService def main (): chroma_service = ChromaService(persist_directory= "./chroma_data" ) count = chroma_service.load_knowledge_base( "./knowledge" ) print (f "Successfully loaded {count} documents" ) if __name__ == "__main__" : main() 実行: python scripts/load_knowledge.py # 出力: Successfully loaded 8 documents ChromaDBのセットアップ ChromaDBとは ChromaDBは「ベクトルデータベース」です。文章を数値(ベクトル)に変換して保存し、 似た意味の文章を高速に検索できます。普通のデータベース(MySQL等)とは異なり、 「意味的な類似度」で検索できるのが特徴です。 ファイル構成 backend/ ├── app/ │ ├── services/ │ │ └── chroma_service.py │ └── main.py └── chroma_data/ ChromaService実装 backend/app/services/chroma_service.py (抜粋): import chromadb from typing import List, Dict, Any from pathlib import Path import re class ChromaService : def __init__ (self, persist_directory: str = "./chroma_data" ): self.client = chromadb.PersistentClient(path=persist_directory) self.collection = self.client.get_or_create_collection( name= "pavilion_knowledge" , metadata={ "description" : "NTT Pavilion knowledge base" } ) def load_knowledge_base (self, knowledge_dir: str ) -> int : knowledge_path = Path(knowledge_dir) documents = [] for md_file in knowledge_path.glob( "*.md" ): content = md_file.read_text(encoding= "utf-8" ) content = re.sub( r'^---\n.*?\n---\n' , '' , content, flags=re.DOTALL) documents.append({ "id" : md_file.stem, "content" : content.strip(), "metadata" : { "source" : md_file.name} }) if documents: self.collection.add( ids=[doc[ "id" ] for doc in documents], documents=[doc[ "content" ] for doc in documents], metadatas=[doc[ "metadata" ] for doc in documents] ) return len (documents) def search (self, query: str , top_k: int = 3 ) -> List[Dict[ str , Any]]: results = self.collection.query( query_texts=[query], n_results=top_k ) formatted_results = [] if results[ "ids" ] and len (results[ "ids" ][ 0 ]) > 0 : for i in range ( len (results[ "ids" ][ 0 ])): formatted_results.append({ "id" : results[ "ids" ][ 0 ][i], "content" : results[ "documents" ][ 0 ][i], "metadata" : results[ "metadatas" ][ 0 ][i], "distance" : results[ "distances" ][ 0 ][i] }) return formatted_results RAGハンドラーの実装 RAGハンドラーとは RAGハンドラーは、ベクトル検索とLLM呼び出しを組み合わせる「橋渡し役」です。 ①ベクトル検索でコンテキスト取得→②プロンプト作成→③LLM呼び出しの3ステップを実行します。 ファイル構成 backend/ ├── app/ │ ├── handlers/ │ │ └── rag_handler.py │ ├── services/ │ │ └── chroma_service.py │ └── main.py └── .env RAGHandler実装 backend/app/handlers/rag_handler.py (抜粋): from app.services.chroma_service import ChromaService from openai import OpenAI import os import time class RAGHandler : def __init__ (self): self.chroma_service = ChromaService() self.endpoint = os.getenv( "AZURE_MAAS_ENDPOINT" , "" ) self.api_key = os.getenv( "AZURE_MAAS_API_KEY" , "" ) def process (self, question: str , temperature: float = 0.2 , max_tokens: int = 800 ) -> dict : start_time = time.time() search_results = self.chroma_service.search(question, top_k= 3 ) context = " \n\n " .join([ result[ 'content' ] for result in search_results ]) system_message = """あなたはNTTパビリオンの親切な案内スタッフです。 以下の参考情報を基にして、訪問者の質問に丁寧に答えてください。 参考情報に含まれていない内容については推測せず、「その情報は手元にございません」と正直に答えてください。""" user_message = f """# コンテキスト情報 {context} # 質問 {question}""" base_url = self.endpoint.rstrip( "/" ) + "/v1/" client = OpenAI( base_url=base_url, api_key=self.api_key, timeout= 30.0 ) response = client.chat.completions.create( model= "tsuzumi-7b-instruct" , messages=[ { "role" : "system" , "content" : system_message}, { "role" : "user" , "content" : user_message} ], temperature=temperature, max_tokens=max_tokens ) elapsed_time_ms = int ((time.time() - start_time) * 1000 ) return { "answer" : response.choices[ 0 ].message.content, "context_retrieved" : [r[ "metadata" ][ "source" ] for r in search_results], "elapsed_time_ms" : elapsed_time_ms } FastAPIエンドポイント メインアプリケーション backend/app/main.py (抜粋): from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel from app.handlers.rag_handler import RAGHandler app = FastAPI() app.add_middleware( CORSMiddleware, allow_origins=[ "*" ], allow_credentials= True , allow_methods=[ "*" ], allow_headers=[ "*" ], ) rag_handler = RAGHandler() class QuestionRequest (BaseModel): question: str temperature: float = 0.2 max_tokens: int = 800 @ app.get ( "/api/health" ) async def health_check (): return { "status" : "healthy" } @ app.post ( "/api/ask/rag" ) def ask_rag (request: QuestionRequest): return rag_handler.process( question=request.question, temperature=request.temperature, max_tokens=request.max_tokens ) 実行とテスト FastAPI起動 : source venv/bin/activate uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 curlでテスト : curl -X POST http://localhost:8000/api/ask/rag \ -H "Content-Type: application/json" \ -d '{ "question": "NTTパビリオンのテーマは何ですか?", "temperature": 0.2, "max_tokens": 800 }' ベースモデルvsRAG比較結果(実測値) 同一の質問3つを、ベースモデルとRAGパターンで実行した結果を比較します。 比較方法 同一質問3つを両パターンで実行 回答内容(公式情報との整合を含む)、応答時間、参照元を記録 Question 1 テーマ質問 質問 : 「NTTパビリオンのテーマは何ですか?」 項目 ベースモデル RAG 回答 "NTTパビリオンのテーマは、「未来への挑戦」です。" "NTTパビリオンのテーマは「PARALLEL TRAVEL(パラレル・トラベル)」です。" 応答時間 1.422秒 1.989秒 公式情報との整合(筆者判断) ❌ 整合しない ✅ 整合しやすい 参照元 なし 08_faq.md, 05_finale.md, 06_architecture.md スクリーンショット : ベースモデルのJSON応答(テーマが意図した内容と異なる) RAG版のJSON応答(テーマの回答とcontext_retrieved配列) ポイント : RAGではナレッジベースに沿った回答になり、ベースモデルでは異なる回答になることがありました。 Question 2 IOWN技術 質問 : 「IOWNとは何ですか?その特徴を教えてください。」 Before(ベースモデル) : 回答: IOWNとは、NTTが提供するインターネットの仮想空間です。 ユーザーは、自分のアバターを作成し、様々な衣装やアクセサリーを身につけることができます... 観察された点 : 仮想空間・アバターの話が中心となり、意図した「光通信基盤」の説明としては焦点がずれていました 応答時間 : 5.399秒 After(RAG) : 回答: IOWNは、光技術を活用した革新的な通信基盤です。 従来のネットワークでは実現困難だった、超大容量・超低遅延・低消費電力の通信を可能にします。 参照元: - 08_faq.md - 07_technology.md - 03_zone2.md 観察された点 : ナレッジベースに沿った形で、特徴が整理されて提示されました、応答時間がベースの方がかかっていました。ネットワークの状態などの影響が考えられます。 応答時間 : 4.790秒 スクリーンショット : ベースモデルの回答例(仮想空間・アバターの話が中心) RAG版の回答例(複数のナレッジファイルから情報取得) ポイント : ベースモデルは意図した観点と異なる内容が含まれる場合があり、RAGではナレッジベースに沿った説明になりました。 Question 3 Zone2の見どころ 質問 : 「Zone2の見どころを教えてください。」 項目 ベースモデル RAG 回答 "Zone2は、最新技術を体験できるゾーンです..." "Zone2の見どころは、NTTが開発する次世代通信インフラ「IOWN」の技術を体験できることです。離れた場所で行われているPerfumeのライブパフォーマンスを、まるで目の前で繰り広げられているかのように体験できます。" 応答時間 2.399秒 3.998秒 具体性(筆者判断) △ 抽象的 ○ 具体例を含む 参照元 なし 08_faq.md, 03_zone2.md, 07_technology.md ポイント : ベースモデルは一般論にとどまる回答となることがあり、RAGでは固有名詞を含む説明になりました。 総合評価 定量的比較 : 指標 ベースモデル RAG 備考 平均応答時間 3.21秒 4.06秒 +0.85秒(約26%増) 公式情報との整合(筆者判断) 0/3問 3/3問 具体性(筆者判断) 一般的 詳細・具体例あり 参照元明示 なし 全て3ファイル context_retrievedで確認 定性的評価 : RAGでは、固有名詞や技術用語がナレッジベースに沿った説明になりました(PARALLEL TRAVEL、Perfumeなど) ベースモデルは一般知識のみで回答し、固有情報については回答がぶれる場合がありました(例: IOWNを別概念として説明するケース) 応答時間は約0.85秒増加しました まとめ RAGで確認できたこと(本検証範囲) 観察できた点 : 本検証の3問では、RAG構成のほうがナレッジベースに沿った回答になりました 固有名詞を含む質問(PARALLEL TRAVEL、Perfumeなど)で、参照元を提示できました 技術用語(IOWNなど)も、ナレッジベースに沿った形で説明されました トレードオフ : 応答時間が約0.85秒増加しました(ベクトル検索の処理が追加されるためと考えられます) ナレッジベースの整備が継続的に必要になりそうです おわりに この記事では、国産LLM「tsuzumi」を使ったRAG実装の一例を紹介しました。 また、タスク処理能力の強化・知識の増強がうたわれた「tsuzumi 2」が記事執筆中にリリースされました。こちらも今後、機会を見て試していきたいです。 この記事のポイント : RAGは知識を拡張するための有力な手法の一つ ChromaDBとsentence-transformersで、RAGを実装可能 本検証範囲では、ベースモデルと比べてRAG構成のほうがナレッジベースに沿った回答になりました IOWNの質問で、ベースモデルが別概念の説明に寄るケースがあり、RAGの必要性を考えるきっかけになりました この記事が、皆さんのRAG実装の第一歩になれば幸いです。 参考リンク tsuzumi NTT版大規模言語モデル NTT版大規模言語モデル「tsuzumi 2」 Azure AI Foundry ドキュメント Azure AI Foundry tsuzumi Overview ChromaDB公式ドキュメント sentence-transformers公式サイト NTTパビリオン | EXPO2025 | NTT 執筆者 辻本傑(NTTビジネスソリューションズ株式会社 バリューデザイン部 システム開発部門) ビジネスチャットの開発・運用に携わっています。C#やクラウドが好きで、最近は生成AIの活用にも関心があります。 認定スクラムマスター(CSM) 商標 IOWNおよびtsuzumiはNTT株式会社の登録商標です。 「大阪・関西万博」「EXPO 2025」は、2025年日本国際博覧会協会が定める名称です。 Microsoft AzureおよびAzure AI Foundryは、米国Microsoft Corporationの商標または登録商標です。 Pythonは、Python Software Foundationの登録商標です。 FastAPIは、tiangolo(José Sebastián Ramírez)所有の商標です。 Chromaは、Chroma Inc.の商標です。 OpenAIは、OpenAI, Inc.の商標または登録商標です。 本記事中の固有名詞(アーティスト名、団体名等)は、それぞれの権利者に帰属します。 その他、本文中に記載されている会社名・製品名・サービス名等は、各社の商標または登録商標である場合があります。
Introduction and Summary Hi, I'm Iwamoto. Last month, I had the opportunity to write an introductory post as the group manager of the My route Development Group. As it happens, I also serve as the manager of the Mobile App Development Group. In this article, I'd like to introduce the group and share a bit about how I came to manage both. About the Mobile App Development Group What is the Mobile App Development Group? Formed in early 2022, the Mobile App Development Group is a relatively new team made up of engineers who, as the name implies, specialize in mobile app development. With pride as a mobile app development specialist, we take full ownership of all mobile app projects involving KINTO Technologies, transcending the boundaries between individual services. Basically, we create mobile apps in collaboration with the development groups in charge of each service (mainly those responsible for backend API development), but our involvement doesn't end at delivery. We stay actively involved in post-launch development and enhancements, working closely with each service group to take shared responsibility in driving the service forward. Our Journey So Far Let’s explore how the Mobile App Development Group was formed. The Early Days of KINTO Technologies KINTO Technologies has its roots in the development department of KINTO Corporation. At the time, the service primarily handled applications via the web and had no mobile app. So, the engineering team was made up almost entirely of web engineers, with very few members having any experience in mobile app development. my route Development Amid these circumstances, KINTO Technologies was assigned to develop my route , a MaaS app that originally began as a pilot project by Toyota Motor Corporation. At the time, My Route was being developed under contract by a partner company, and our first mission was to bring that development in-house. Although the in-house development of backend APIs progressed smoothly, mobile app development remained heavily reliant on partner companies for quite some time due to a shortage of specialized engineers. To turn things around, we gradually built up in-house expertise by reassigning engineers with mobile app experience and actively hiring new talent. By fall 2021, we had a solid internal foundation in place and were ready to kick off our in-house mobile app development project. Development of Apps Other Than my route As the mobile app engineering team within the My Route Development Group grew more capable, we started receiving an increasing number of inquiries about mobile app development from teams outside of My Route. By that time, KINTO Technologies had started handling several mobile apps besides my route. However, due to the ongoing shortage of mobile app engineers, much of the development work was still outsourced to partner companies. I wouldn't say that was the sole reason, but it's true that many of those projects faced challenges and didn't go very well. As we continued offering support and assisting with these external projects, our involvement in services beyond my route gradually increased, even though we were still technically part of the my route Development Group. The Birth of Mobile App Development Group Before we knew it, nearly half of our members were working on services other than my route. At that point, it no longer made sense from an organizational or operational perspective for us to remain a team within the my route Development Group. As a result, the Mobile App Development Group was established as an independent team in January 2022. We also considered embedding mobile app engineers directly into the development teams for each individual service. However, since the team had only just been formed—bringing together engineers with diverse backgrounds and skill sets—there were concerns that spreading them out too soon would make it difficult for KINTO Technologies to establish a consistent standard for mobile app development. This led to the decision to create a dedicated mobile app development group. Thanks to that, about a year later, we have established a number of development standards, and the group has grown into an organization of engineers capable of delivering high-quality mobile applications. Features of the Mobile App Development Group Team Composition As of the end of 2022, the group's size has grown to about 25 people. The number of Android and iOS engineers is roughly half and half, and some members are skilled in both platforms or have multi-platform experience using tools like Flutter and Unity. We also have a few members called "producers," who take on PM-like roles. Currently, our development work is centered on native apps, so the team is broadly divided into Android and iOS groups. However, we are considering reorganizing into service-based teams in the future. This would allow us to strengthen ties to each service and make better use of engineers who have the skills to work across both operating systems. International Diversity Compared to other groups, our team has a notably high ratio of non-Japanese members. In particular, around 80% of our Android specialists are global talent. Our group includes members from a wide range of countries, including Korea, China, Taiwan, Myanmar, Poland, and Germany, making for a truly international environment. Many of our members are fluent in English, but since English has not yet been adopted as the company's official language, all members are able to communicate in Japanese well enough to perform their daily work. With people from many different cultural backgrounds, the team enjoys a lively atmosphere and open, energetic communication on a daily basis. The communication style can feel much more direct compared to all-Japanese teams, which can be surprising at times. Even so, we aim to be an organization that embraces and enjoys these differences. What kind of People Work Here? When it comes to hiring, technical skills in mobile app development are a given. What we value even more is a strong interest in the field and a proactive mindset toward staying up to date with the latest trends. That's because the mobile app development landscape is constantly evolving, with new technologies and techniques emerging every day. Relying solely on existing knowledge quickly leads to obsolescence in such a fast-paced environment. As a result, the team is made up of members who are truly passionate about mobile app development. Many go beyond their daily work to improve their skills, and study sessions are held regularly. To Our Future Members If you're looking to grow as a mobile app specialist and want to work with the latest technologies, this is the perfect environment for you. Even if you don't have much hands-on experience yet, we warmly welcome those who bring passion and a willingness to learn. Let's work together to create mobile applications that support Toyota Group!














