はじめに
あまり外部に公開したくないデータを外部で稼働するLLMに送信することなく、RAGっぽいシステムを作ってみよう!って記事です。
AgentCore + S3 Vectorsは時間課金のないサーバレス、LLMはローカルでの稼働なので、セキュアかつ、低コストで実現できそうです!
作ってみる。
S3 Vectors
作成そのものは名前を設定するだけです。
Bedrock knowledge Base
ナレッジベースとして使うには、作成時のステップ3 データストレージと処理を設定
でAmazon S3 Vectors
を選択するだけです。
なお、追加設定の埋め込みタイプに関しては、S3 Vectorsを選択する場合、バイナリベクトル埋め込み
は利用できない模様です。
Agent Runtime
MCPサーバー自体の作成は以下の記事の作れば、すぐ作成可能です。
今回は以下で作成したものを流用しています。
(Auth0を使い、1ヶ月有効なベアラトークンを使ってます。)
ソースは以下のようにしました。
# my_mcp_server.py
from mcp.server.fastmcp import FastMCP
from starlette.responses import JSONResponse
import boto3
import json
import os
from typing import List, Dict, Any, Optional
mcp = FastMCP(host="0.0.0.0", stateless_http=True)
@mcp.tool()
def knowledge_search(
query: str,
max_results: int = 5,
region_name: str = "us-west-2"
) -> Dict[str, Any]:
"""
Search for knowledge using AWS Bedrock Knowledge Base with S3 Vectors
Args:
query: The search query text
max_results: Maximum number of results to return (default: 5)
region_name: AWS region name (default: us-west-2)
Environment Variables:
KNOWLEDGE_BASE_ID: The ID of the knowledge base to search
Returns:
Dictionary containing search results and metadata
"""
try:
# Get knowledge base ID from environment variable with default
knowledge_base_id = os.getenv('KNOWLEDGE_BASE_ID', 'xxxxxxxxxx')
# Initialize Bedrock Agent Runtime client
client = boto3.client(
'bedrock-agent-runtime',
region_name=region_name
)
# Configure retrieval parameters
retrieval_config = {
'vectorSearchConfiguration': {
'numberOfResults': max_results
}
}
# Perform the search
response = client.retrieve(
knowledgeBaseId=knowledge_base_id,
retrievalQuery={'text': query},
retrievalConfiguration=retrieval_config
)
# Format results
results = []
for result in response.get('retrievalResults', []):
formatted_result = {
'content': result.get('content', {}).get('text', ''),
'score': result.get('score', 0),
'location': result.get('location', {}),
'metadata': result.get('metadata', {})
}
results.append(formatted_result)
return {
'query': query,
'knowledge_base_id': knowledge_base_id,
'results_count': len(results),
'results': results,
'status': 'success'
}
except Exception as e:
return {
'query': query,
'knowledge_base_id': knowledge_base_id,
'error': str(e),
'status': 'error'
}
if __name__ == "__main__":
mcp.run(transport="streamable-http")
LM Studio + gpt-oss 20bのセットアップ
セットアップについては、以下のページが分かりやすいので、紹介させていただきます。
容量はgpt-oss 20b
で11GBくらい必要です。
なお、Macbook Air M4 24GBで動作させてみた感じ、とりあえずもっさりとは動きます。
MCPの設定
LM StuidoはMCPに対応しているので、画面右側のスパナアイコンからMCPの設定をしていきます。
設定自体は他のツールと同じような設定です。
"mcpServers": {
"bedrockAgentRuntime-MCP": {
"url": "[agent core endpoint]",
"headers": {
"Authorization": "Bearer [bearer token]",
"KNOWLEDGE_BASE_ID": "[knowledge base ID]"
}
}
聞いてみる!
ナレッジからデータを引っ張ってくるか動作確認してみます。
なお、利用する際は事前にintegrations
から対象のMCPを有効にしておく必要があります。
今回は、以下の資料をS3に格納し、札幌市はオリンピックでどのように変わりましたか?ナレッジで検索し、要約して
といった質問をしてみます。
すると、MCPの使用可否を聞いてきます!
Reached context length of 4096 tokens with model
初期設定だと、回答の途中でReached context length of 4096 tokens with model
のエラーで処理が止まってしまうことがありました。
とりあえず、Context Length
を4096
->8192
にしておくことで対処しました。
まとめ
データをS3に置くだけで、安全なローカルLLMでデータを検索することができました!
セキュアなナレッジ検索システムが必要な場合、こんな構成がいいんですかねー?