Gemini Personal Intelligence のグローバル展開が始まったとき、「GmailやPhotosと連携してくれるのは便利」という印象でした。でも実際にAPIを触ってみると、これが単なる「スマートな検索」ではなく、個人のデジタル行動を文脈として持つAIエージェントを構築できるプラットフォームであることがわかりました。
Personal Intelligence の実態と、それを使ったパーソナライズドAIシステムの構築方法を順を追って整理していきます。
Personal Intelligence とは何か
Gemini Personal Intelligence は、ユーザーの Google アカウントに紐づいたパーソナルデータ(Gmail、Photos、Drive、Calendar など)を Gemini の文脈として使えるようにする機能です。
従来の Gemini API と Personal Intelligence の最大の違いは、「誰が質問しているか」という文脈です。通常の Gemini はすべてのユーザーに同じ知識で答えます。Personal Intelligence は「あなたが先週誰とミーティングしたか」「あなたの写真から旅行のパターン」「あなたがよく使うフレーズ」を文脈として持ちながら回答できます。
この機能を使ったシステムが本質的に優れているのは、プロンプトエンジニアリングで補えない「個人の文脈」を最初から持っているためです。
セットアップと認証
Google Cloud プロジェクトの設定
Personal Intelligence を使うには、Google Cloud プロジェクトで以下のAPIを有効にします。
# 必要なAPIを有効化
gcloud services enable generativelanguage.googleapis.com gmail.googleapis.com photoslibrary.googleapis.com drive.googleapis.com calendar-json.googleapis.comOAuth 2.0 認証フロー
Personal Intelligence は OAuth 2.0 を通じてユーザーの同意を取ります。必要なスコープを明示的に要求する点が肝心です。
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
import json
# 必要なスコープを明示的に定義
SCOPES = [
"https://www.googleapis.com/auth/generative-language",
"https://www.googleapis.com/auth/gmail.readonly",
"https://www.googleapis.com/auth/photoslibrary.readonly",
"https://www.googleapis.com/auth/drive.readonly",
"https://www.googleapis.com/auth/calendar.readonly",
]
def get_credentials(credentials_file: str = "credentials.json"):
"""OAuth 2.0認証フローを実行して資格情報を取得する"""
creds = None
# 既存のトークンを読み込む
try:
with open("token.json", "r") as f:
creds = Credentials.from_authorized_user_info(json.load(f), SCOPES)
except FileNotFoundError:
pass
# トークンが無効または存在しない場合は再認証
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(credentials_file, SCOPES)
creds = flow.run_local_server(port=0)
# トークンを保存
with open("token.json", "w") as f:
f.write(creds.to_json())
return creds重要な注意点: ユーザーに要求するスコープは必要最小限にしてください。gmail.readonly であれば読み取りのみで、送信はできません。パーミッションの透明性はユーザーの信頼に直結します。
Gmail連携 — メールの文脈を活かした応答
最も実用的なユースケースの一つが、Gmailの文脈を活かした応答システムです。
from googleapiclient.discovery import build
import base64
from email.mime.text import MIMEText
import google.generativeai as genai
from datetime import datetime, timedelta
def get_recent_emails(creds, days: int = 7, max_results: int = 20):
"""直近N日間のメールを取得する"""
service = build("gmail", "v1", credentials=creds)
# 日付フィルターを設定
after_date = (datetime.now() - timedelta(days=days)).strftime("%Y/%m/%d")
query = f"after:{after_date} -category:promotions -category:social"
messages = []
result = service.users().messages().list(
userId="me",
q=query,
maxResults=max_results
).execute()
for msg in result.get("messages", []):
msg_detail = service.users().messages().get(
userId="me",
id=msg["id"],
format="full"
).execute()
# ヘッダーとテキスト本文を抽出
headers = {h["name"]: h["value"] for h in msg_detail["payload"]["headers"]}
body = extract_email_body(msg_detail["payload"])
messages.append({
"from": headers.get("From", ""),
"subject": headers.get("Subject", ""),
"date": headers.get("Date", ""),
"body": body[:500] # 最初の500文字
})
return messages
def extract_email_body(payload):
"""メール本文を再帰的に抽出する"""
if "parts" in payload:
for part in payload["parts"]:
if part["mimeType"] == "text/plain":
data = part["body"].get("data", "")
if data:
return base64.urlsafe_b64decode(data).decode("utf-8", errors="ignore")
return extract_email_body(payload["parts"][0])
data = payload.get("body", {}).get("data", "")
if data:
return base64.urlsafe_b64decode(data).decode("utf-8", errors="ignore")
return ""
def create_personal_ai_assistant(creds):
"""メールの文脈を持ったパーソナルAIアシスタントを作成する"""
recent_emails = get_recent_emails(creds, days=7)
# メールサマリーをコンテキストとして構築
email_context = "\n".join([
f"[{e['date'][:16]}] From: {e['from']}\n件名: {e['subject']}\n{e['body'][:200]}"
for e in recent_emails[:10]
])
system_prompt = f"""あなたはユーザーのパーソナルAIアシスタントです。
直近1週間のメール(要約):
{email_context}
このコンテキストを踏まえて、ユーザーの質問に答えてください。
メールの内容に基づいて、具体的で文脈のある回答を提供してください。"""
model = genai.GenerativeModel(
"gemini-2.5-flash",
system_instruction=system_prompt
)
return model
# 使用例
creds = get_credentials()
assistant = create_personal_ai_assistant(creds)
response = assistant.generate_content("今週フォローアップが必要なメールはありますか?")
print(response.text)Photos連携 — 視覚的な記憶を持つAI
Google Photos との連携で、AIが「あなたがどんな場所に行って、何を食べて、誰と会ったか」を視覚的に理解できるようになります。
import requests
def get_recent_photos_metadata(creds, max_results: int = 20):
"""直近の写真のメタデータを取得する"""
headers = {"Authorization": f"Bearer {creds.token}"}
response = requests.post(
"https://photoslibrary.googleapis.com/v1/mediaItems:search",
headers=headers,
json={
"pageSize": max_results,
"filters": {
"dateFilter": {
"ranges": [{
"startDate": {"year": 2026, "month": 3, "day": 1},
"endDate": {"year": 2026, "month": 4, "day": 30}
}]
}
}
}
)
items = response.json().get("mediaItems", [])
return [
{
"filename": item.get("filename", ""),
"description": item.get("description", ""),
"creation_time": item.get("mediaMetadata", {}).get("creationTime", ""),
"base_url": item.get("baseUrl", "")
}
for item in items
]
def analyze_life_patterns_with_photos(creds):
"""写真から生活パターンを分析する"""
photos = get_recent_photos_metadata(creds)
# 写真の説明をテキストとして渡す(プライバシーに配慮してURLは使用しない)
photos_summary = "\n".join([
f"{p['creation_time'][:10]}: {p['filename']} - {p['description']}"
for p in photos if p['description']
])
model = genai.GenerativeModel("gemini-2.5-pro")
response = model.generate_content(f"""
以下の写真メタデータから生活パターンを分析してください:
{photos_summary}
分析観点:
1. よく行く場所・活動のパターン
2. 社交的な活動のパターン
3. 食事・ライフスタイルの傾向
4. 特筆すべき出来事やマイルストーン
""")
return response.textプライバシーファーストなアーキテクチャ
Personal Intelligence を扱うとき、プライバシーの設計は最も重要な問題です。私が実践しているプリンシプルを共有します。
データは端末内で処理する: できる限り、個人データをサードパーティのサーバーに送信しない設計にします。データの加工・フィルタリングはローカルで行い、AIに渡す情報を最小化します。
不可逆的な匿名化を行う: メールアドレス、電話番号、固有名詞は送信前にハッシュ化または匿名化します。
import hashlib
import re
def anonymize_email_for_ai(email_text: str) -> str:
"""メールのPII(個人識別情報)を匿名化する"""
# メールアドレスをハッシュ化
def hash_email(match):
email = match.group(0)
return f"[USER_{hashlib.md5(email.encode()).hexdigest()[:8]}]"
email_pattern = r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"
anonymized = re.sub(email_pattern, hash_email, email_text)
# 電話番号をマスク
phone_pattern = r"\d{3}[-.]?\d{4}[-.]?\d{4}"
anonymized = re.sub(phone_pattern, "[PHONE_REDACTED]", anonymized)
return anonymized最小限のスコープ: 実際に使う機能に必要なスコープだけを要求します。Calendarを使わないなら、Calendarのスコープは要求しないでください。
ユーザーへの透明性: どのデータをいつ使ったか、ユーザーが確認できるログを提供します。
パーソナルAIエージェントの実装
これらの連携をまとめて、自律的に動くパーソナルAIエージェントを構築できます。
class PersonalAIAgent:
"""個人の行動パターンを学習して自律的に動くAIエージェント"""
def __init__(self, creds):
self.creds = creds
self.context_cache = {}
def refresh_context(self):
"""最新のパーソナルコンテキストを収集する"""
emails = get_recent_emails(self.creds, days=3)
email_summary = self._summarize_emails(emails)
self.context_cache = {
"email_summary": email_summary,
"last_updated": datetime.now().isoformat()
}
def _summarize_emails(self, emails):
"""メールを簡潔にサマリーする"""
if not emails:
return "最近のメールはありません"
items = [
f"• {e['subject']} (from: {e['from'][:30]})"
for e in emails[:5]
]
return "\n".join(items)
def ask(self, question: str) -> str:
"""パーソナルコンテキストを活かして質問に答える"""
if not self.context_cache:
self.refresh_context()
context = f"""
最近のメール:
{self.context_cache.get('email_summary', '情報なし')}
"""
model = genai.GenerativeModel(
"gemini-2.5-flash",
system_instruction=f"あなたはパーソナルAIアシスタントです。以下のコンテキストを踏まえて回答してください:\n{context}"
)
response = model.generate_content(question)
return response.text
def run_daily_briefing(self) -> str:
"""毎朝の定期ブリーフィングを生成する"""
self.refresh_context()
briefing_prompt = """
今日のパーソナルブリーフィングを作成してください。
含む内容:
1. 今日対応が必要なメール(優先度付き)
2. 今日のカレンダー確認事項
3. 昨日から継続しているタスクのリマインダー
4. 一つの「今日のヒント」(仕事効率化・健康など)
簡潔に、読みやすい形式でお願いします。
"""
return self.ask(briefing_prompt)
# 使用例
creds = get_credentials()
agent = PersonalAIAgent(creds)
# 毎朝実行するブリーフィング
print(agent.run_daily_briefing())
# 任意の質問
print(agent.ask("先週誰かから重要なメールが来ていましたか?"))はじめの一歩
Personal Intelligence の世界に入るとき、最初は「Gmailだけ」から始めることをお勧めします。全てのAPIを一度に統合しようとすると、認証フローのデバッグだけで数日かかることがあります。Gmailの文脈だけでも、日常のAI体験は大きく変わります。
プライバシーの観点からも、最初は「読み取りのみ」のスコープで始めて、ユーザー(または自分自身)がシステムを信頼してから書き込み権限を追加するというアプローチが健全です。
パーソナルコンテキストを持つAIは、汎用的なAIとは質的に異なる体験を提供できます。その可能性を、ぜひ自分のユースケースで試してみてください。