業務常駐AIサービスの技術的実現可能性を、事業企画担当の私が自分の手で確かめてみた

業務常駐AIサービスの技術的実現可能性を、事業企画担当の私が自分の手で確かめてみた

構想中の「業務常駐AI」サービスをAWS Bedrock + Knowledge Bases + Guardrails + Lambda + Step Functionsで自分の手で組み、技術的実現可能性を確かめた記録。VPC内完結・RAG・ガードレールの3仮説を実機検証し、つまずいた7点と次の論点まで共有する。
2026.05.04

こんにちは。クラスメソッドでリテールアプリ共創部の事業企画を担当しているかめだです。

私はこの数か月、社内で「業務常駐AI」というサービス構想を温めています。顧客企業のAWS環境内に常駐し、業務マニュアルや社内FAQを理解したうえで情報収集・定型レポート作成・質問対応といった業務を自律的に担うAIエージェントを、月額契約のマネージドサービスとして提供する、というものです。

ただ、構想は構想にすぎない。本当にClassmethodがこのサービスを提供できるのか。AWS Bedrockだけで技術的に成立するのか。顧客のVPC内で完結する構成は現実的なのか。提案資料を書く前に、これらを自分の手で確かめることにしてみました。


1. 構想中のサービスと、私が確かめたかったこと

業務常駐AIサービスの一文サマリー

特定業務に継続的に携わるAIエージェントを設計・構築・継続運用し、月額課金で提供するマネージドエージェントサービス。

設計の起点は「顧客のAWS環境に常駐する」という制約にあります。社外のSaaSにデータを送らず、顧客が運用するAWSアカウントとVPCの中で完結する。これがセキュリティ面での購買障壁を下げ、情報セキュリティ部門の承認を通しやすくすると考えます。

技術的に確かめたかった3つの仮説

  1. 顧客VPC内に閉じた構成が成立するか(セキュリティ訴求の根拠になるか)
  2. RAGで社内ナレッジを引き、業務に関連する質問に答えられるか(サービスの中核機能が動くか)
  3. 拒否トピック・PII遮断などのガードレールが業務利用に耐えるレベルで機能するか(顧客に説明できる安全設計が組めるか)

この3点が確認できれば「技術的に提供可能」という判断材料になります。反対に、どれかが動かなければ、別構成への切り替えを検討するか、この時点でサービス化を見直す必要があります。


2. サービス仮説をAWSにどう載せるか

全体構成図

採用サービスとその理由 『技術選好ではなくサービス価値起点で』

サービス 役割 なぜこの構成にしたか
Bedrock(Claude Sonnet) 主推論エンジン AWS統合請求で稟議が通りやすい。顧客のAWSコスト管理の中で一括管理できる
Bedrock Knowledge Bases RAGストア ナレッジの更新(S3へのファイル追加・同期)を顧客側で完結できる。継続運用時に弊社エンジニアの手を借りずに更新できることがサービス設計上の要件
Bedrock Guardrails 安全フィルター 事故時の責任分界を技術的に補強できる。PII遮断・禁止トピックの設定をコンソールで管理でき、変更の監査証跡が残る
Lambda 処理ステップ VPCエンドポイント経由でBedrockを呼ぶことで、インターネットを経由しないネットワーク経路が設計できる
Step Functions オーケストレーション 将来的なヒューマン・イン・ザ・ループ(AI生成の内容を人間が確認してから出力するワークフロー)への拡張が宣言的に書ける
S3 ナレッジ置き場 顧客が持つ業務マニュアルやFAQをそのまま配置できる。Knowledge Basesのデータソースとして直接指定可能

この構成が事業上で重要なのは、顧客のAWSアカウント内に完全に収まるという点です。Bedrock Knowledge BasesのRAGベクターストアも、Lambda・Step Functionsも、すべて顧客自身のクラウドコスト管理の中に存在します。解約時に「業務ナレッジが自社VPCに残る」という顧客側の主体性確保は、共用SaaS型サービスとの比較で説明しやすい差別化軸になると考えます。


3. 事業企画担当が自分の手で構築した記録

前提条件

  • AWSアカウント(東京リージョン ap-northeast-1
  • IAMユーザーまたはロールに以下の権限:bedrock:*lambda:*states:*s3:*logs:*
  • Python 3.12 / boto3最新版

Step 1: Bedrockモデルアクセスの有効化

確認したかった点: そもそもClaude APIを自分のAWSアカウントで呼べるのか。モデルアクセスの有効化が複雑だと、顧客環境へのデプロイ時に障壁になります。

  1. AWSコンソール → Amazon Bedrock → 左メニュー「Model catalog」を開く
  2. 使いたいモデル(例: Claude 3.5 Sonnet)を選択
  3. 「Open in Playground」でPlaygroundが開き、初回invoke時に自動で有効化される

p1

Anthropicモデルだけ手順が1段階追加される。初回アクセス時にユースケースフォームの入力が求められる。用途(業務効率化・社内ツール等)を選択して「Submit」するだけなので、数分で通過できます。

Playgroundで日本語で話しかけて返答が来れば、モデルアクセスの有効化は完了です。

p8

今回使用するモデル:

  • Claude 3.5 Sonnet(主推論・Knowledge BasesとのRAG)
  • amazon.titan-embed-text-v2:0(Knowledge BasesのEmbedding用)

公式参照: Amazon Bedrockのモデルアクセス


Step 2: S3にナレッジをアップロードしてKnowledge Basesを作成

確認したかった点: 顧客の業務マニュアルを取り込んで、それを根拠に質問に答えられるか。ここがサービスの中核機能です。

S3バケットを作成し、エージェントが参照するナレッジ(業務マニュアル・FAQ・社内ルール等)を配置する。

Bedrockコンソール → 「Knowledge Bases」→「ナレッジベースを作成」を選択する。

設定値:

  • データソース: 上記S3バケット
  • Embeddingモデル: amazon.titan-embed-text-v2:0
  • ベクトルストア: Amazon OpenSearch Serverless(自動作成を選択)

「作成」を押すとインデックスの構築が始まる。

実測値: 検証時のファイル量(数KB程度)で同期完了まで4分かかりました。「データソースの同期」ボタンを押してから「完了」ステータスになるまでの実測です。コンソールで「同期完了」ステータスを確認してから次のステップに進むこと。

コスト注意: OpenSearch Serverlessは最小構成でも2 OCU = $0.48/時(実測: 約¥73/時)かかる。当日中に削除すれば数百円〜2,000円程度で済むが、そのまま放置すると月額¥52,560ほどになる。このコストは本番サービスではL3月額料金の設計に織り込んでいるが、検証用に立ち上げたまま忘れると思わぬ請求になるので注意。

公式参照: Amazon Bedrock Knowledge Basesの開始方法


Step 3: Guardrailsの設定(PII遮断 + 禁止トピック)

確認したかった点: 業務利用に耐えるガードレールが、アプリ側にフィルタリングロジックを書かずに組めるか。セキュリティ審査で「どう安全を担保しているか」を説明するときに使える設計が実現できるか。

Bedrockコンソール → 「Guardrails」→「ガードレールを作成」を選択する。

今回設定した内容:

  • コンテンツフィルター: 暴力・差別等のカテゴリを「HIGH」に設定
  • PIIの処理: メールアドレス・電話番号・氏名を選択し、アクションを「ブロック」に設定
  • 禁止トピック: 業務外の質問(投資アドバイス・法律相談など)を拒否するトピックを追記

作成後、「ガードレールID」と「バージョン」をメモしておく。Lambda から呼び出す際に使う。

p5

公式参照: Amazon Bedrock Guardrails


Step 4: Lambda関数の作成(Python / boto3)

確認したかった点: RAG検索と推論とガードレールを1つのAPI呼び出しで束ねられるか。コードの複雑さがどの程度か。

関数名: resident-ai-invoke / ランタイム: Python 3.12 / タイムアウト: 120秒

import json
import boto3
import os

bedrock_agent = boto3.client(
    'bedrock-agent-runtime',
    region_name='ap-northeast-1'
)

KNOWLEDGE_BASE_ID = os.environ["KNOWLEDGE_BASE_ID"]
GUARDRAIL_ID      = os.environ["GUARDRAIL_ID"]
GUARDRAIL_VERSION = os.environ["GUARDRAIL_VERSION"]

# 2026年仕様: オンデマンド利用は推論プロファイル ARN を使う
# "anthropic.claude-3-5-sonnet-..." の直接指定はエラーになる
MODEL_ARN = os.environ["MODEL_ARN"]
# 例: "arn:aws:bedrock:ap-northeast-1::foundation-model/apac.anthropic.claude-3-5-sonnet-20241022-v2:0"

def lambda_handler(event, context):
    query = event.get("query", "経費精算の締め日はいつですか")

    response = bedrock_agent.retrieve_and_generate(
        input={"text": query},
        retrieveAndGenerateConfiguration={
            "type": "KNOWLEDGE_BASE",
            "knowledgeBaseConfiguration": {
                "knowledgeBaseId": KNOWLEDGE_BASE_ID,
                "modelArn": MODEL_ARN,
                "generationConfiguration": {
                    "guardrailConfiguration": {
                        "guardrailId": GUARDRAIL_ID,
                        "guardrailVersion": GUARDRAIL_VERSION
                    }
                }
            }
        }
    )

    answer = response["output"]["text"]
    citations = [
        c["retrievedReferences"][0]["location"].get("s3Location", {}).get("uri", "N/A")
        for c in response.get("citations", [])
        if c.get("retrievedReferences")
    ]

    return {
        "statusCode": 200,
        "body": json.dumps(
            {"query": query, "answer": answer, "sources": citations},
            ensure_ascii=False
        )
    }

Lambda関数の環境変数:

環境変数名 値(例)
KNOWLEDGE_BASE_ID Step 2で作成したKnowledge BasesのID
GUARDRAIL_ID Step 3で作成したGuardrailのID
GUARDRAIL_VERSION DRAFTまたは公開バージョン番号
MODEL_ARN 推論プロファイルARN(apac.anthropic.claude-3-5-sonnet-20241022-v2:0プレフィックス)

コードを貼り付けたら、橙色の「Deploy」ボタンを押すのを忘れずに。押し忘れると前のコードのまま動き続けてしまいます。。。

公式参照: Bedrockクロスリージョン推論プロファイル


Step 5: Step Functionsステートマシンの定義

確認したかった点: 複数のLambdaステップをオーケストレーションする構造が、追加SaaSなしにAWS標準機能だけで作れるか。

Lambdaをステップとして呼び出す最小構成のASL(Amazon States Language)です。今回は検証目的のため、Lambdaの出力をOutputPathで直接次ステートに渡すシンプルな設計にしました。

{
  "Comment": "業務常駐AI ミニマル構成",
  "StartAt": "InvokeRAG",
  "States": {
    "InvokeRAG": {
      "Type": "Task",
      "Resource": "arn:aws:states:::lambda:invoke",
      "Parameters": {
        "FunctionName": "resident-ai-invoke",
        "Payload.$": "$"
      },
      "OutputPath": "$.Payload",
      "Retry": [
        {
          "ErrorEquals": ["Lambda.ServiceException", "Lambda.TooManyRequestsException"],
          "IntervalSeconds": 2,
          "MaxAttempts": 3,
          "BackoffRate": 2
        }
      ],
      "End": true
    }
  }
}

Step Functionsコンソール → 「ステートマシンを作成」→ 上記ASLを貼り付けて保存する。

[スクショ:Step Functionsステートマシン作成画面にASLを貼り付けている状態]

公式参照: Step Functionsでのエラー処理


Step 6: 動作確認

Step Functionsコンソール → 作成したステートマシン → 「実行を開始」を選択し、以下のJSONを入力する。

{
  "query": "経費精算の締め日はいつですか"
}

[スクショ:Step Functions実行ビジュアル(InvokeRAGステップが緑色で完了している状態)]

実行結果の「出力」タブにanswersourcesが返ってくれば成功だ。

実際に確認できた出力の形式(実測):

{
  "statusCode": 200,
  "body": "{\"query\": \"経費精算の締め日はいつですか\",
            \"answer\": \"経費精算の締め日は毎月25日です。...\",
            \"sources\": [\"s3://resident-ai-knowledge-202505/expense-policy.md\"]}"
}

sourcesにナレッジファイルのS3パスが返ってきているので、回答がどのドキュメントから来たかを追跡できます。


4. 動かして見えてきた手応えと壁

技術的実現可能性について出た結論

フロー全体の疎通(実測): Step Functions → Lambda → Bedrock retrieve_and_generate → Knowledge Bases(RAG)→ Guardrails → 応答返却、という一連のフローが通りました。

これが意味するのは「追加SaaSなしのAWSマネージドサービスだけで、サービス構想の中核機能を構成できる」ということです。

Guardrailsの動作(実機確認)

  • 投資助言クエリ(「○○株を買うべきですか」系)で拒否トピックが発火し、ブロックメッセージが返却された
  • 人名・メールアドレス・電話番号を含む入力でPIIブロックが発火し、入力段階でブロックされた
  • 通常の業務質問は過剰ブロックなしで通過した

GuardrailsのIDを渡すだけでAPIコール全体に適用される設計は、フィルタリングロジックをアプリ側に書く必要がなく、変更が監査証跡に残ります。セキュリティ審査の説明材料として使いやすいでしょう。

ハルシネーション抑制(実機確認): retrieve_and_generateを使うことで、ナレッジに存在しない情報を"作り上げる"ケースが明らかに減りました。sourcesに引用元が記録されるため、どこから引いた情報かの追跡も可能です。

VPC内完結のセキュリティ: Bedrockに対応するVPCエンドポイント(com.amazonaws.ap-northeast-1.bedrock-runtime)を設定すれば、LambdaからのBedrock呼び出しがインターネットを一切経由しない。「データがどこへ行くのか」という説明がシンプルになり、セキュリティ審査が通りやすくなります。

レイテンシ(実測): CloudWatch Logsで確認したところ、初回実行(コールドスタート)はInit Duration約1,000ms+関数実行約316msで合計1,316msでした。課金対象(Billed Duration)は2,316ms。コールドスタートを除いた純粋な処理時間(RAG検索 + Claude推論 + Guardrailsの3ステップ)は数百ms程度に収まる見込みです。リアルタイムのチャット応答としては許容範囲、バックグラウンドで定期実行するエージェント用途(週次レポート生成・毎朝の情報収集等)なら何の問題もないと考えます。

コスト概算: Claude Sonnetの場合、入力3$/1Mトークン・出力15$/1Mトークン(2026年5月時点)。1タスクあたり入力約2,000トークン・出力約500トークンを仮定すると1タスク約0.014ドル。月1,000タスクで約14ドル(約2,000円)。ただしOpenSearch Serverlessの固定コスト(最小2 OCUの顧客VPC占有構成で月52,560円)が別途かかる点は注意が必要です。このコストはL3月額料金の設計に織り込んでいます。

ハマりポイント7選

ここが本題かもしれない。「手順通りにやったのになぜか動かない」という詰まりポイントを7つ共有します!


ハマり1: .rtf形式はKnowledge Basesに非対応

Macで「新しいテキストファイル.txt」を作ろうとしてTextEditで作成すると、デフォルトがリッチテキスト形式(.rtf)になる。これをS3にアップロードして同期すると、Knowledge Basesは認識してくれない。

対応フォーマット: .txt.md.pdf.docx.html.csv.xlsx

TextEditで作成する場合は「フォーマット」→「標準テキストにする」を選択してから保存すること。これで最初の同期が全部空振りになった。

公式参照: Knowledge Basesでサポートされているデータ型


ハマり2: ファイルサイズが小さすぎるとチャンク0で失敗

テスト用に「経費精算の締め日は毎月25日です。」だけ書いた1行ファイルを作ったところ、ファイルサイズが423バイトだった。これを同期すると「同期成功」と表示されるのに、追加されたチャンク数が0件になる。

実測: 1KB以上のファイルで初めてチャンク化された。テスト用でも最低1KBを確保すること。複数の質問と回答を書いたFAQ形式にすると自然に超えられる。


ハマり3: LambdaのDeployボタン押し忘れ

Lambdaコンソールでコードを貼り付けて「保存(Ctrl+S)」しただけでは、変更は反映されない。コードエディタ上部に表示される橙色の「Deploy」ボタンを押す必要がある。

「コードを直したのに動きが変わらない」と15分悩んだ。Deployボタンを押したあとに「デプロイ完了」の緑色通知が出るので、それが確認できるまで次に進まないようにすること。

[スクショ:LambdaコンソールのDeployボタン(橙色)]


残った壁

技術的実現可能性は確認できた。ただし、実際のサービスとして提供するためには以下の課題が残っています。

CDKによるデプロイパッケージ化: Lambda・Step Functions・Knowledge Bases・Guardrails・IAMロールをCDK Stackとして定義し、顧客のAWS環境にcdk deploy1コマンドで展開できる状態にする作業が必要です。今回の検証はコンソール操作で完結したが、複数顧客への展開を考えると自動化が必須になります。

推論プロファイルARN等の最新仕様追従: Bedrockの仕様は更新頻度が高い。顧客デプロイ用のドキュメントとコードテンプレートを最新仕様に追従し続けるための管理体制が必要です。

SLA・免責の契約書整備: 技術検証とは別レイヤーとして、ハルシネーション事故時の免責範囲・損害賠償上限・稼働率SLA・解約条件を法務確認済みの契約書テンプレートとして整備する必要があります。サービスとして提供するための前提条件であり、技術が動いてからが本番の準備になる。


5. サービス化に向けて見えた次の論点

提供パッケージの三層構造

今回の検証を経て、サービスの提供パッケージは以下の三層で整理できると考えています。

L1(アセスメント): 顧客の業務フローをヒアリングし、どの業務にAIエージェントを常駐させるかの要件定義とROI試算を行う。この段階で「本番移行の判断基準」と「ハルシネーション許容値・免責範囲・SLA」を書面合意する。合意なしにL2に進まないことが、PoC止まりを防ぐ設計の中心にある。

L2(構築): 合意した要件にもとづいてRAG設計・プロンプト設計・Guardrails設定・評価ハーネス構築を行い、本番環境への移行を担う。

L3(月額継続運用): 本番稼働後の品質レビュー・プロンプト改善・業務SOP更新・障害対応を月額定額で継続提供する。業務SOP・判断パターンが顧客VPC内に蓄積されていくことが、乗り換えコストを形成する。

ターゲット仮説

今回確認した「顧客VPC内での完全完結構成」という技術的特性から、想定するターゲットはAWSをすでに本番環境として運用しており、売上100億円以上の中堅企業です。クラウドコスト管理のガバナンスが整っており、「AWS Bedrockコストとして統合管理できる」という説明が刺さりやすい規模感を想定しています。

Salesforceをメインのビジネスアプリとして使っている企業は、AgentforceとのPoC比較が発生しやすい。AWSが主軸の企業から優先的に検証を進める想定です。


参考リンク


注記 1: 本記事はあくまで技術検証の記録だ。本番業務への適用にあたっては、SLA・免責・賠償条項の整備、ならびに利用規約・業界固有の法規制への適合確認を別途行う必要がある。AI出力は必ず人間の確認を経て使用してください。

注記 2(検証後の削除手順): OpenSearch Serverlessは放置すると課金が継続する。検証完了後は以下の順で削除すること。

  1. Bedrockコンソール → Knowledge Bases → 対象を選択 → 「削除」
  2. OpenSearchコンソール → Serverless → Collections → 自動作成されたコレクションを削除
  3. S3バケット → バケットを空にしてから削除
  4. Lambda関数・Step Functionsステートマシン・Guardrailsを削除

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事