MetaとConstellationによる原子力エネルギー契約の意義

AI時代の電力需要急増とMetaの戦略的転換

近年、AI技術の飛躍的な進展により、データセンターを運営するハイパースケーラー企業の電力需要が著しく増大しています。特にMeta(旧Facebook)は、AI推論や学習に「膨大な電力を必要としており、再生可能エネルギーだけでは賄いきれない状況に直面」していました。このような背景のもと、2025年に発表されたMetaと米国大手電力会社Constellation Energy(以下、Constellation)との20年間にわたる核エネルギー供給契約は、AIインフラ維持における重要な転換点として注目されています。

過去最大級のバーチャルPPA

  • 契約規模: MetaはConstellationから「1,121メガワット(MW)の核エネルギーを、20年間にわたって購入する契約」を締結しました。これは、過去にMicrosoftとConstellationが締結した契約を「約35%上回る規模」であり、「この取引は、Microsoftとの契約よりも35%大きい規模です」とBloombergのアナリストが指摘しています。
  • 対象施設: この電力は、Constellationがイリノイ州に保有するクリントン原子力発電所(Clinton Clean Energy Center)の「全出力を引き取る」形となります。契約は2027年6月から開始されます。
  • 「バーチャル」契約の意義: この契約は、Metaが原発隣接地にデータセンターを設置するのではなく、電力網を介して供給を受ける「バーチャル取引」です。「データセンターを原子力発電所のそばに建設しなくても、必要な電力はバーチャルで調達できます。」この方式は、インフラ整備の手間を省きつつ、大容量かつ安定した電力を長期にわたり確保できるという大きなメリットがあります。
  • 既存発電所の延命と拡張: このPPAは、州が出資するゼロエミッションクレジット(ZEC)プログラムの終了後、「20年間にわたり同施設の再ライセンシングと運営をサポート」します。さらに、「アップレートにより、発電所の出力をさらに30MW拡大」し、合計で1.121GWに増加させる予定です。ConstellationのCEOであるJoe Dominguezは、「既存発電所の再ライセンシングと拡張を支援することは、新しいエネルギー源を見つけることと同じくらいインパクトがあります。前進する上で最も重要なことは、後退することをやめることです」と述べています。

AIインフラにおける電力需要と環境目標への影響

  • AI推論による電力負荷: これまでAIの電力需要は訓練段階に焦点が当てられがちでしたが、実際には「訓練よりも推論が、はるかに多くの電力を必要としています」とマンディープ・シン氏が指摘するように、継続的な推論処理こそが膨大な電力を消費します。Metaは月間30億人以上のユーザーを抱え、生成AIサービスの導入を進めており、その「CPUやGPUの稼働率を100%に維持するには、安定した電力供給が不可欠」と認識しています。
  • 環境目標と原子力発電: 多くのテック企業が「2030年までにネットゼロ(実質カーボンゼロ)」を目指していますが、AIの電力需要急増により「昨年、AIの急増で電力需要が跳ね上がり、ガスや石炭に依存せざるを得ない状況が生まれました。これは彼らのカーボンフリー目標に真っ向から反する」という問題が生じていました。原子力発電は稼働時にCO₂をほとんど排出しないため、Metaのように「クリーンエネルギー目標を達成しつつ、大量の電力を安定的に確保したい」企業にとって理想的な選択肢となります。また、核燃料コストを長期固定契約することで、発電コストの安定化も図れます。

Constellationの役割と原子力発電の再興

  • 既存ライセンスの活用: Constellationはイリノイ州に複数の原子力発電所を運営しており、今回の契約対象プラントは既に追加反応炉ユニットの許認可を取得済みです。これにより、「新規原発を一から建設するよりも、拡張や運営継続によるコストやリスクを抑えられ」ます。
  • 新規建設への期待: 米国では、過去のジョージア州の事例のように「最後に大規模原発が建設されたのはジョージア州ですが、完成には7年遅延し、予算も数十億ドル上振れしました。この経験が、多くの企業を二の足を踏ませてきたのです」という課題がありました。しかし、MetaやMicrosoftといった「アンカー」となるハイパースケーラー企業が大量の電力を長期契約する意向を示すことで、Constellation側には「大口顧客を確保できれば、新規反応炉ユニット建設への自信につながる」という期待が生まれています。これにより、資金調達の見通しが立ち、ライセンス取得済みサイトの活用、そして市場への信頼醸成へと繋がります。
  • Constellation株価の高騰: Metaの契約発表後、Constellationの株価は5%以上急騰し、5ヶ月ぶりの高値となる1株あたり340ドルを記録、時価総額は1,000億ドルを超えました。ConstellationはOpenAIのChatGPTリリース以降、S&P 500の期間中51%のリターンを大きく上回る230%以上のリターンを投資家にもたらしており、「AIが企業アメリカを再構築したことで、ウォール街で最大の勝者の1つ」となっています。
  • 政治的後押し: ドナルド・トランプ大統領は5月23日に、2050年までに米国の原子力エネルギー容量を4倍にするという大統領令に署名しており、この動きは原子力発電の再興をさらに後押しする可能性があります。「原子力エネルギーは、かつて見捨てられた存在でしたが、AIの飽くなきエネルギー需要と、太陽光や風力発電の間欠性を補うために追加のエネルギー源が必要であるという認識の高まりによって、復活を遂げています」とYardeni Researchの創設者Ed Yardeniは述べています。

エネルギーインフラのボトルネックとソリューション

  • 送電網の制約: 原子力発電所からの電力供給契約が結ばれても、データセンターへの電力輸送には送電網の容量とリードタイムが大きな課題です。「送電線は、2~3年のバックログがあるため、設備の建設は進んでも、最後に送電線がつながらず完成できないケースが散見されます。」
  • スタートアップによる革新: この課題に対応するため、エネルギー領域では以下のスタートアップが注目されています。
  • Heron(旧Tesla幹部創業): シリコンバレー発のgrid-scale用ソリッドステートトランスフォーマーを開発し、送電網の小型化・効率化を目指しています。
  • NIRA Energy: AIを活用したソフトウェアで、ガス、風力、太陽光など複数の発電リソースを統合管理し、グリッドオペレーターに最適な送電指示を提供します。「送電インフラは、巨大なルービックキューブのように複雑に絡み合っており、それを解くためには効率的なデータ管理と先進的な電力機器が必要です。」 これらの企業は、AIデータセンター向けの電力需要を見据えたマイクログリッド構築や高度な制御技術で、エネルギーインフラの課題解決を試みています。

長期的な展望と社会への波及効果

  • 小規模ビジネスへの影響: Metaが確保する安定した大量電力は、同社が提供するAI関連サービスを通じて、小規模ビジネスのマーケティングや業務効率化に好影響をもたらす可能性があります。「小規模ビジネスは、わずかなコストでAIを使ってビデオ広告やキャンペーン素材を生成できる時代が来るでしょう。」
  • 産業・社会への影響: Metaの20年にわたる核エネルギー固定価格契約は、以下の長期的なインパクトをもたらします。
  • データセンター運営コストの安定化: 電力価格の長期固定により、コスト変動リスクを抑え、収益見通しが明確化されます。
  • 原子力発電再興への機運醸成: 大手テック企業の契約は、「原子力発電はリスクが高い」という負のイメージを払拭し、新規建設や既存炉のライフ延長投資を活性化させる可能性があります。
  • クリーンエネルギーへの道筋: 他のハイパースケーラーや大企業も同様の長期契約に動くことで、「総発電量に占める脱炭素電源の比率が一気に高まる」可能性があります。 「私たちはまだAI普及の入り口に立っているに過ぎません。今後の数十年で、産業・社会全体がこのAI・エネルギーの交差点で変革を遂げるでしょう。」
  • 「エネルギー戦略がビジネス戦略と直結する時代」: Metaの契約は、単なる電力調達に留まらず、AI時代におけるエネルギー戦略のモデルケースとなり得るものです。今後10年、20年というスパンで見たとき、AIの推論負荷は増大し続けると予想され、企業が「エネルギー供給を誰と、どのように確保するか」は、AI競争の鍵を握る要素となるでしょう。私たちは現在、その大きな「転換点」を目撃していると言えます。

まとめ

AI技術の急速な発展により、特に推論処理を中心に電力消費が大幅に増加しています。これに伴い、再生可能エネルギーだけでは賄いきれない場面も多くなり、化石燃料への依存が再び強まる懸念があります。そのため、AIの持続的な発展には、原子力などの低炭素エネルギーの活用を含めた電力源の見直しと、環境負荷を抑える戦略的なエネルギー選択が不可欠です。

AIの仮面をかぶった人力サービス:Builder.aiの「Natasha」が暴いたAIウォッシングの実態

Builder.aiは、Microsoftの支援を受けた革新的なAIスタートアップとして注目されていましたが、実際にはAIではなく、700人のインド人エンジニアによる人力サービスであったことが判明し、破産に追い込まれました。

同社は「Natasha」というAIアシスタントがソフトウェアアプリケーションを組み立てると宣伝していましたが、実際には顧客のリクエストはインドのオフィスに送られ、エンジニアが手作業でコードを書いていたとのことです。

この詐欺により、Builder.aiは8年間で4億4500万ドル(約640億円)の投資をMicrosoftを含む大手IT企業から集めましたが、アプリケーションは頻繁に不具合を起こし、コードは判読不能で、機能は動作しないなどの問題が発生しました。

破綻の始まりは、2023年にBuilder.aiに5000万ドル(約70億円)を融資したViola Creditという資産管理会社が、Builder.aiの債務不履行を受けて差し押さえを行ったことでした。この措置により、Builder.aiは事業運営能力と従業員への給料支払い能力を喪失し、破産手続きに入りました。

また、Builder.aiとインドのコンテンツ発信プラットフォーム・VerSe Innovationとの間で、架空の取引をして売上高を水増しする「循環取引」の疑いも報じられています。VerSeはこれを否定しています。

現在、Builder.aiはイギリスで正式な破産手続きを開始しており、裁判所が任命した管財人が資産の回収または事業の一部の救済方法を検討しています。同社は「初期の失敗により回復不可能な状況」になったことを認めています。

この事件は、AI技術の実態と企業の透明性に対する警鐘となっています。

コントのような話しだが

自動販売機の中で人が飲み物を提供している、といったシチュエーションはコントで時折見かけますが、現実にあったサービスでした。しかも(悪い意味で)AIが作ったようなできばえだったようです。

現在ではとても需要があるとは思えませんが、AIサービスは日々どんどん出てくる一方で、玉石混交といった状況も否めません。性能面でのパワーバランスが変わるという点もそうですが、見てくれやデモ、サービス内容は非常に優れているように見えていても、実際にはハリボテのように中身はボロボロといったものもある可能性を考慮に入れて検討や検証することが重要になります。

メタ、AIを活用した広告完全自動化を計画、早ければ年内にも

概要

Meta(Facebook、Instagram、WhatsAppの親会社)は、2026年末までに広告主がAIツールを使用して広告キャンペーンを完全に作成し、ターゲティングできるようになる計画を発表しました。この動きは、伝統的な広告業界に大きな影響を与える可能性があり、特に広告代理店やメディア代理店に対して脅威をもたらすと見られています。Metaのマーク・ザッカーバーグCEOは、この開発を「広告というカテゴリーの再定義」と位置づけており、広告収入のさらなる拡大を目指しています。

主要テーマと重要な事実

  1. AIによる広告作成とターゲティングの完全自動化:
  • Metaは、広告主が商品画像とマーケティング予算を提供することで、AIが画像、動画、テキストを含む広告全体を生成し、最適なユーザーへのターゲティングを決定するツールを開発中です。
  • 既存のAIツールが既存広告の微調整に留まっていたのに対し、新しいツールは「広告コンセプトをゼロから完全に開発する」ことを可能にします。
  • 「地理位置情報」などのターゲティング機能を活用し、ユーザーの関心のある可能性のある目的地に特化した旅行会社の広告をカスタマイズする例が挙げられています。
  • Metaのプラットフォームは現在、年間1600億ドル(約18兆円)を広告から生み出しており、このAI導入によりその収益を大幅に増加させる可能性があります。
  1. 伝統的な広告業界への影響:
  • この動きは「伝統的なマーケティング業界に衝撃波を送った」と報じられています。
  • AIツールは、広告代理店が担ってきた伝統的な広告作成、計画、購入の役割を「中間排除」する可能性があります。
  • ニュースを受け、世界の主要なマーケティングサービス会社の株価は下落しました(WPPは3%減、Publicis Groupeは3.9%減、Havasは3%減)。
  • Metaの最高マーケティング責任者兼分析担当副社長であるアレックス・シュルツ氏は、「私たちは代理店の未来を信じている」と述べつつも、AIツールが「中小企業の競争条件を平準化する」と強調しています。
  1. 中小企業(SMBs)へのメリットと課題:
  • 新しいAIツールは、特に「小規模から中規模の企業(SMBs)にとって恩恵となる可能性」があります。これらの企業は「多くの場合、広範な広告作成活動のためのリソースを欠いている」ためです。
  • AIが「クリエイティブやターゲティングについて考える時間がない、または経済的規模が小さい中小企業」を支援し、「競争の場を平準化する」と期待されています。
  • 一方で、一部の「大手小売ブランド」は、AI生成コンテンツが「人間の手によるキャンペーンの品質や特定の美的感覚を常に達成できるわけではない」ことや、「歪んだビジュアル」を生み出す可能性について懸念を表明しています。
  1. Metaの戦略的投資とAI分野での競争:
  • Metaは2025年に640億ドルから720億ドルを資本支出に投資する計画を更新しており、これには「AIインフラストラクチャの構築費用」が含まれています。
  • AI部門の再編成が行われ、チームがAI製品と基盤となるAI技術の2つのグループに分割されました。これは「業務を合理化し、責任を明確にする」ことを目的としています。
  • AIを活用したコンテンツ作成は競争が激しく、Googleも動画生成ツールのVeoなどをリリースしています。多くのブランドは、Metaのプラットフォームを含むデジタルプラットフォーム全体で広告コンテンツを作成するために、MidjourneyやOpenAIのDALL-Eのようなサードパーティツールを使用しており、Metaはこれらの「サードパーティの機能を自社プラットフォームに統合する方法を模索している」と報じられています。
  • Metaは「トップのAI人材」を引き付けるのに苦労しており、Mistralなどの競合他社に研究者を失っているという課題にも直面しています。

MetaのAI広告作成は、広告業界にどのような影響と機会をもたらすのか?

MetaのAI広告作成ツールは、広告業界に大きな影響と機会をもたらすとされています。

広告業界への影響(脅威)

  • 伝統的な広告代理店への脅威: FacebookとInstagramの親会社であるMetaは、ブランドのマーケティング予算を直接ターゲットにすることを目指しており、これはクライアントのキャンペーンや予算を扱う広告およびメディア代理店にとって脅威となります。AIツールは、従来の広告作成、プランニング、および購入の役割を担う代理店の介在を不要にする(disintermediate)可能性があります。
  • 株価への影響: MetaのAI導入計画のニュースが報じられた際、世界最大のマーケティングサービス会社の株価はすぐに下落しました。例えば、WPPの株価は3%、フランスのPublicis GroupeとHavasはそれぞれ3.9%と3%下落しました。これは、伝統的なメディア業界に大きな衝撃を与えたと報じられています。
  • AI生成コンテンツの品質懸念: 大規模な小売ブランドの中には、AI生成コンテンツが人間が作成したキャンペーンの品質や特定の美的感覚を一貫して達成できない可能性を懸念し、Metaにより多くのコントロールを譲ることに慎重な姿勢を示しているところもあります。AIツールは、修正が必要な歪んだビジュアルを生成することもあります。

広告業界への機会(メリット)

  • 中小企業(SMBs)への恩恵: Metaの新しいAIツールは、広告主の大部分を占める中小企業にとって潜在的に有益です。これらの企業は、大規模な広告作成に多くのリソースを割くことができないことが多いからです。Metaの最高マーケティング責任者兼分析担当副社長であるAlex Schultz氏は、AIツールが時間や財政的規模の制約により代理店と契約できない中小企業にとって「競争の場を平準化する」のに役立つと述べています。
  • 広告作成の自動化と効率化: Metaが開発しているAIツールは、ブランドが製品画像と計画されたマーケティング予算を提供することで、広告全体(画像、動画、テキストを含む)を作成し、さらにクライアントの予算に合わせてユーザーにターゲティングすることを可能にします。これにより、広告主は目標を設定し、予算を割り当てるだけでプラットフォームが処理するワンストップサービスが構築されることを目指しています。
  • パーソナライゼーションの強化: AIを活用したパーソナライゼーションにより、ユーザーの興味関心に基づき、同じ広告の異なるバージョンをリアルタイムで表示できるようになります。例えば、旅行会社の広告が、ユーザーの興味があると思われる目的地に特化した取引を提供するように調整されることが可能になります。
  • 代理店の役割の変化と進化: Metaは、AI機能の強化が伝統的な代理店を排除する動きではないと明言しています。MetaのAlex Schultz氏は、「私たちは代理店の未来を信じている」と述べ、AIが代理店や広告主が貴重な時間とリソースを「重要な創造性」に集中させることを可能にすると考えています。代理店の役割は、プラットフォームを横断したプランニング、実行、測定能力を通じて、これまで以上に重要になると予測されています。

MetaはAI広告に大規模な投資を行っており、2025年にはAIインフラ構築の費用を含め、640億ドルから720億ドルを投資する計画を更新しています。これは、AIを活用した広告を推進するというMetaのMark Zuckerberg CEOの強い焦点を示しています。彼は、これらの新しいツールの開発を「広告のカテゴリの再定義」と呼んでいます。Metaは、2026年末までにAIによる広告作成とターゲティングを全面的に可能にすることを目指しています。

中小企業は、MetaのAI広告ツールをどのように活用して成長できるのか?

中小企業(SMBs)は、MetaのAI広告作成ツールを以下のように活用して成長することができます。

  • 競争の場の平準化: Metaの新しいAIツールは、広告主の大部分を占める中小企業にとって特に有益です。これらの企業は、大規模な広告作成に多くのリソースを割くことができないことが多いためです。Metaの最高マーケティング責任者兼分析担当副社長であるAlex Schultz氏は、AIツールが時間や財政的な規模の制約により広告代理店と契約できない中小企業にとって「競争の場を平準化する」のに役立つと述べています。
  • 広告作成の自動化と効率化:
    • AIツールは、ブランドが製品画像と計画されたマーケティング予算を提供するだけで、広告全体(画像、動画、テキストを含む)を自動的に作成することを可能にします。これにより、中小企業はこれまで大規模なリソースを必要としていた広告コンテンツ制作の負担を大幅に軽減できます。
    • 広告主が目標を設定し、予算を割り当てれば、プラットフォームが広告プロセス全体を処理する「ワンストップサービス」の構築を目指しています。
  • 効率的なターゲット設定:
    • AIは、クライアントの予算に合わせてユーザーに広告を自動的にターゲティングします。
    • 例えば、ジオロケーション(位置情報)などのターゲティングにより、旅行会社の広告が、ユーザーの興味があると思われる特定の目的地に特化した取引を提供するように調整されることが可能になります。これにより、中小企業はターゲット顧客に効果的にリーチできるようになります。
  • パーソナライゼーションの強化: AIを活用したパーソナライゼーションにより、ユーザーの興味関心やその他の要因(例えば、ジオロケーション)に基づいて、同じ広告の異なるバージョンをリアルタイムで表示できるようになります。これにより、個々のユーザーにとってより関連性の高い広告体験を提供し、エンゲージメントを高めることができます。
  • 時間とリソースの節約: 中小企業は、広告のクリエイティブやターゲティングについて考える時間がないことが多いため、AIツールがこのギャップを埋めるのに役立ちます。AIによる自動化は、中小企業が「重要な創造性」に集中するための貴重な時間とリソースを確保することにもつながります。

Metaは、2026年末までにAIによる広告作成とターゲティングを全面的に可能にすることを目指しており、これらのツールは中小企業がMetaプラットフォーム上で効率的かつ効果的に広告を運用し、ビジネスを成長させる大きな機会をもたらすと考えられています。

広告を見る人たちにとってどのような影響をもたらすか?

MetaのAI広告作成ツールは、広告を見る人たち(ユーザー)に対して、主に以下のような影響をもたらすとされています。

  • 広告のパーソナライゼーションと関連性の向上:
    • AIを活用したパーソナライゼーションにより、ユーザーは自身の興味関心や位置情報(ジオロケーション)などの要因に基づいて、同じ広告の異なるバージョンをリアルタイムで見ることができるようになります。
    • 例えば、旅行会社の広告が、ユーザーが興味を持つ可能性のある目的地に特化した情報や取引を提供するように調整されることが可能になります。
    • これにより、広告は個々のユーザーにとってより関連性の高い、パーソナライズされた体験となり、エンゲージメントを高めることが期待されます。広告主はAIを活用して、広告をそれぞれの個人に合わせられるようにする計画を立てています。
  • 広告コンテンツの品質に関する懸念:
    • 一方で、一部の大規模な小売ブランドは、Metaにさらなるコントロールを委ねることに対して懸念を示しています。これは、AIが生成するコンテンツが、人間が作成したキャンペーンの品質や特定の美的感覚を常に達成できない可能性があるためです。
    • AIツールが歪んだビジュアルを生成し、修正が必要になる場合もあると指摘されています。したがって、ユーザーはAIによって生成された広告の一部で、品質のばらつきや不自然な画像を目にする可能性も考えられます。

まとめ

メタ社による広告完全自動化は、伝統的な広告代理店にとっての脅威となる一方で、効率化という新たなメリットをもたらす可能性があります。一方、中小企業が広告代理店を介さずに広告を打ち出せるという時間的コスト的メリットもあります。

一方で、広告を見る立場からすると、パーソナライゼーションが進むというメリットはあるものの、低品質な広告があふれるという問題もあります。少なくとも、ユーザーにとって時間をかけて見る価値のある面白い広告を生み出せるレベルにないことは現在の生成AI技術からも明らかなため、これがどのような結果を生み出すのかは注目していきたいところです。

参考文献

dentsu JapanとOpenAIがマーケティング領域での研究開発をスタートしたと発表

画像の出典:dentsu Japanのプレスリリースより

電通グループの国内事業を統括・支援する dentsu Japanは、OpenAI社の最新の生成AI技術を活用したマーケティング領域における先進的なAIエージェントの研究開発を開始しました。OpenAI社は2024年4月に日本法人を設立し、日本市場での生成AIの普及・展開を牽引しています。

この取り組みは、急速に進化する生成AI技術、特に人と対話したり作業を自律的にこなしたりするAIエージェントが世界的に注目されている中で行われています。AIエージェントは、単純な質問応答だけでなく、業務効率化、マーケティングの高度化、新たなビジネス価値の創出など、多岐にわたる領域での活用が期待されています。

dentsu Japanは、この研究開発を通じて、独自のAI等級制度における「主席AIマスター」が率いる約150名のAIイノベーターを中心に活動しています。彼らは、OpenAI社が提供するデータセキュリティに配慮された「ChatGPT Enterprise」や最新の生成AI技術を活用し、先進的なAIエージェントの開発とその国内外におけるマーケティング領域での導入を推進しています。

顧客のマーケティング課題解決を支援する画期的なAIエージェントのプロトタイプは、2025年7月に開発が完了する予定です。

この研究開発は、dentsu Japanが掲げる独自のAI戦略「AI For Growth」を加速させるものです。「AI For Growth」は、「人間の知」と「AIの知」を掛け合わせることで、顧客や社会の成長に貢献していくことを目指しています。今回のAIエージェント開発により、全マーケティング工程におけるAI活用を通じたトランスフォーメーション(高度化・高速化・効率化・内製化)を加速し、「AIネイティブ化」の実現を推進していく考えです。dentsu Japanは、独自の視点と先進的なアプローチを強みに、「人間の知」と「AIの知」を掛け合わせることで、顧客の事業成長と社会の持続的な発展に貢献していくことを目指しています。

この協業の戦略的意義

電通グループの国内事業を統括・支援する dentsu Japan と OpenAI 社がマーケティング領域における AI エージェントの研究開発を開始したことは、双方にとって重要な戦略的意義を持っています。

dentsu Japanにとっての戦略的意義

  • 最新の生成AI技術の活用とAIエージェントの開発推進: dentsu Japan は、OpenAI 社の最新の生成 AI 技術、特にデータセキュリティーに配慮された「ChatGPT Enterprise」を活用することで、マーケティング領域における先進的な AI エージェントの開発を進めています。これは、急速に進化する生成 AI 技術、特に自律的に作業をこなす AI エージェントが世界的に注目されている状況に対応するものです。
  • 独自のAI戦略「AI For Growth」の加速: この研究開発は、dentsu Japan が掲げる「AI For Growth」戦略を加速させる中核となります。この戦略は、「人間の知」と「AI の知」を掛け合わせることで、顧客や社会の成長に貢献することを目指しています。
  • マーケティング全工程の「AIネイティブ化」実現: AI エージェントの開発・導入を通じて、全マーケティング工程におけるトランスフォーメーション(高度化・高速化・効率化・内製化)を加速し、「AIネイティブ化」の実現を推進していく考えです。AIエージェントがマーケティングの全工程をサポートするイメージが示されています。
  • 顧客課題解決への貢献と新たなビジネス価値創出: 顧客のマーケティング課題の解決を支援する画期的な AI エージェントのプロトタイプ開発を2025年7月に完了する予定であり、これは顧客事業成長への貢献を目指すものです。AIエージェントは、業務効率化やマーケティングの高度化に加え、新たなビジネス価値の創出も期待されています。
  • 社内AI人材の活用と育成: 独自の AI 等級制度における「主席 AI マスター」が率いる約 150 名の AI イノベーターがこの取り組みの中心となっています。これは、社内の専門人材とAI技術を融合させる「AIモデル」の深化にもつながります。

OpenAIにとっての戦略的意義

  • 日本市場におけるプレゼンス強化: OpenAI 社は2024年4月に日本法人を設立しており、日本市場での生成 AI の普及・展開を牽引しています。dentsu Japan のような日本の大手企業との連携は、日本市場での事業基盤を強化し、影響力を拡大する上で重要です。
  • エンタープライズ領域での技術適用と検証: dentsu Japan はデータセキュリティーに配慮された「ChatGPT Enterprise」や最新技術を活用して開発を進めており、これは OpenAI のエンタープライズ向けソリューションが実際のビジネス環境、特に複雑なマーケティング領域でどのように活用され、どのような成果をもたらすかを検証する機会となります。
  • AIエージェント技術の応用事例創出: AI エージェントは世界的に注目されており、業務効率化や新たなビジネス価値創出が期待される領域です。dentsu Japan との共同開発 は、OpenAI の基盤技術がマーケティングという特定のドメインでどのように高度な AI エージェントとして応用可能かを示す具体的な事例となります。
  • 有力パートナーとの協業による知見獲得: dentsu Japan の約 150 名の AI イノベーター が OpenAI の技術を活用することで、マーケティングの専門知識と AI 技術を組み合わせた新たな知見が生まれ、OpenAI の技術開発や企業向けソリューションの改善にフィードバックされる可能性があります。

総じて、この研究開発は、dentsu Japan にとっては先端技術を取り込み、自社のマーケティングサービスと組織を根底から変革し、顧客成長への貢献を加速させるための戦略的な一歩であり、OpenAI にとっては日本の重要市場において、先進的な企業パートナーと共に自社技術のエンタープライズ領域での適用を深め、AIエージェントを含む技術の可能性を探る機会となります。

マーケティング領域にAIを活用した事例

これまでに研究・実現されているマーケティング分野におけるAIの活用は多岐にわたり、その効率性と効果の高さから注目されています。AIを活用することで、マーケターにとって負担となっていた大量のデータ収集・分析を自動化し迅速化することが可能になります。また、顧客のニーズや購買行動を深く理解し、よりパーソナライズされたアプローチを実現する能力も持っています。

具体的なAIの活用事例としては、以下のようなものが挙げられます。

  1. データ分析の自動化・効率化:
    • 膨大な顧客データ(Webサイト閲覧履歴、SNS行動、メール開封率、購買履歴など)をリアルタイムで処理・分析し、傾向を読み取り、次のアクションを導く高度な意思決定支援を実現します。
    • これにより、従来時間と費用がかかっていたデータ分析作業が効率化され、マーケターの負担を軽減します。
    • 例えば、ホテルレビューの分析による競合差別化やユーザー特性の把握、ビッグデータ分析によるトレンド把握と新商品・サービス開発アイデアへの活用 が行われています。
    • SNS運用においても、リアルタイムデータ分析によりトレンドの変化や異常な行動を素早く捉え、即座に対応することが可能です。
  2. ターゲット層・顧客ニーズの深掘りとセグメンテーション:
    • AIは顧客の過去の購買履歴やオンラインでの行動データをリアルタイムに解析し、それに基づいた消費者インサイトを提供します。
    • 多様なデータをマルチアングルで処理し、顧客セグメンテーションをさらに精密化することが可能です。
    • これにより、ターゲット層ごとに適したマーケティング施策が実現し、より高い成果が得られます。
    • 企業は、ビッグデータ分析により顧客のニーズやライフスタイル、行動特性を詳細に把握し、販売促進や集客などのマーケティング施策の効率化に繋げています。
  3. パーソナライゼーション:
    • AIはデータ分析に基づき、リアルタイムで顧客の行動や傾向を把握し、個別のニーズに合ったマーケティングアプローチを実現します。
    • 顧客ごとの購買履歴や行動パターンに基づいたパーソナライズされた商品提案が可能になり、顧客満足度やブランドへのロイヤルティ向上に貢献します。
    • ECサイトでのレコメンドエンジン や、顧客の肌質・好みに基づくパーソナライズ化粧品提案(資生堂の事例) などがあります。
    • ユーザーの行動変化を察知し、リアルタイムで施策を最適化することで、「学習し続けるマーケティング」を実現します。
  4. コンテンツ生成とクリエイティブ制作:
    • 生成AIを活用することで、広告コピーや記事の自動生成、クリエイティブな提案を効率的に実現できます。
    • ターゲット顧客層に特化した広告文やデザインを作成することが可能になります。
    • これにより、作業効率の向上やコスト削減が可能になり、効果的かつ魅力的なマーケティングコンテンツを素早く投入できます。AIを活用することで、大量の高品質なコンテンツを迅速に作成することも可能です。
    • DAM(Digital Asset Management)システムにAIを搭載し、コンテンツの自動整理・分類(自動タグ付け、類似素材提案、使用傾向学習など)を行い、マーケティングチームのコンテンツ活用を効率化する事例もあります。
  5. 広告効果の最適化:
    • AIは広告のパフォーマンスデータを分析し、より高い反応率を得るための改善点を提案します。
    • ターゲットの購買履歴や行動データに基づき、関連性の高い商品・サービスを推奨したり、デモグラフィック情報や関心事に合わせた最適なメッセージやクリエイティブを表示したりすることで、広告のクリック率やコンバージョン率の向上が期待できます。
    • LINE株式会社では、AIによるパーソナライズ広告により、広告のクリック率とエンゲージメントを向上させています。
    • ニトリでは、AIを用いたマーケティングキャンペーンの最適化により、最適なタイミングとチャネルでの実施、効果測定と費用対効果の向上を実現しています。
  6. チャットボットとカスタマーサポート:
    • AIチャットボットは、顧客からの問い合わせに迅速かつ適切に対応し、満足度を高めます。
    • よくある質問に24時間365日対応することができ、顧客サポートの効率を大幅に改善し、コスト削減にも繋がります。
    • ECサイトでの問い合わせ対応効率化(もつ鍍専門店「肉の寺師」の事例) や、トヨタ自動車、パナソニック での導入事例があります。
    • ユーザーからの質問の意味をかみ砕いて回答できる点がAIチャットボットの特徴です。
    • チャットボットにパターン化されたやり取りを代行させることで、担当者はAIでは対応が難しいより複雑な案件に集中できます。
  7. マーケティングオートメーション:
    • AIエージェントが企業のマーケティング活動を効率化し、成果を最大化するための重要な手段となります。
    • 顧客の行動データや購買履歴を分析し、個別のニーズに応じたパーソナライズされた顧客体験を提供したり、AIが顧客データを分析し最適なタイミングで広告やメールを配信したりします。
    • 見込み顧客へのナーチャリング(商品やサービスの認知から購入に至るまでのプロセス最適化)にAIが活用されています。
  8. 需要予測と在庫管理:
    • AI技術を用いて商品の需要を正確に予測し、在庫管理を最適化することで、過剰在庫や品切れのリスクを軽減し、在庫コスト削減や顧客満足度向上、リピーター獲得に繋がります。
    • ユニクロでは、過去の販売データや市場トレンドなどを分析し、AIを活用して需要予測と在庫管理の最適化を行っています。
    • ホームセンター事業を営む企業では、AIを活用した需要予測システム導入により、ムダな在庫削減と売上増加を実現しました。
  9. その他の活用事例
    • サブスクリプション型サービスの解約リスク軽減のため、解約可能性の高いユーザーを事前に予測し、適切なタイミングでフォローアップを行う仕組み。
    • 見込み顧客の購入意向をAIが読み取り、効果が見込める顧客にのみインセンティブを付与することで購入者数をアップさせた事例。
    • 顧客データを分析し、最適な金融商品を提案することで顧客満足度向上とクロスセル促進を実現した楽天銀行の事例。
    • AIが商品購入ページ内に関連商品ページへ遷移するためのキーワード集を用意し、偶然的な出会いを担保したピーチ・ジョンの事例。
    • 日本航空(JAL)では、AIによる顧客データ分析で、ターゲットに最適なマーケティング戦略を策定し、顧客ロイヤルティとリピート率の向上を実現しています。

これらの個別のAI活用に加え、近年注目されているのが、環境を観察し目標達成のために自律的に行動するAIエージェントの台頭です。AIエージェントは、マーケティング業務全体の自動化を可能にする可能性を秘めています。

まとめ

全プロセスでないにせよ、マーケティングとAIは親和性は高く、業務の一部をAIエージェントに置き換えたり、AIによってプロセスの一部を自動化することが期待されます。直接の対話において、AIに任せられる領域は少なからずあると考えられます。

Nvidia規制で加速する中国のAI半導体自前化戦略

経緯

2018年以降、米中間の貿易摩擦が激化する中、米国は中国に対して先端半導体技術の輸出規制を段階的に強化してきました 。特に、AI用途で世界市場をリードするNvidiaのGPU(Graphics Processing Unit)への輸出を制限する措置が注目されます。  

2022年9月、米国政府はNvidia製の「A100」や「H100」などハイエンドGPUを対象に、中国企業や研究機関向けの輸出許可を厳格化すると発表し、これは同年10月に施行されました 。これにより、AI学習や推論のために高性能GPUを必要とする中国のクラウド事業者や研究機関は、従来どおりの供給ルートから調達できなくなりました。  

2022年10月には、米国商務省がさらに踏み込み、Nvidiaの「A100」や「H100」などを含むAI向け先端チップを対象とした輸出規制を施行しました 。これにより、Nvidiaの正規ルートでの対中国輸出は大幅に制限されることとなりました。  

2022年初頭、トランプ政権下で打ち出された一連の規制は、バイデン政権でも解除されることなく引き継がれました 。特に「米国製ソフトウェア(CUDAを含む)とライセンスを組み合わせたGPUボード」も対象に含まれたため、中国企業はNvidia製GPUを活用することが困難となりました。  

こうした環境下で、中国の主要テック企業は「既存のGPUプラットフォームに依存し続けることのリスク」を強く認識するに至りました。

2023年、Alibaba(阿里巴巴)、Tencent(騰訊)、Baidu(百度)などは、それまでNvidiaのGPUを用いて自社データセンターでAI研究やクラウドサービスを提供してきましたが、在庫が逼迫し始めたことで「国内メーカー製チップへの切り替え計画」を正式に策定しました 。  

同年末から2024年にかけて、Huawei(華為技術)が開発する「Ascend」シリーズをはじめ、Cambricon(寒武紀)、T-Head(兆芯)など複数の国産AIチップメーカーが、データセンター向けのサーバーデザインおよび大量製造のパートナーシップ構築を表明しました 。  

2024年春、NvidiaのBlackwell(次世代アーキテクチャ)搭載サーバーが米国国内で先行投入されたものの、対中国向けには「高帯域メモリ(HBM)を除外したセーフティバージョン」のみが許可される見込みと報じられました 。これに伴い、中国テック企業は「学習用途には残存分の旧世代Nvidia GPUを、推論用途には国産チップを併用」というハイブリッド戦略を取らざるを得ない状況となりました。  

2024年末から2025年初頭にかけて、Alibaba傘下のAI研究機関「DAMO Academy」はAI関連チップ(RISC-V CPUやFPGAなど)の開発を進め、その成果の一部(例:サーバーグレードCPU C930の2025年3月納入開始予定など)を公表しました 。これに続き、Tencent傘下のクラウド部門も国産チップを搭載したAIサーバーを試験導入しました。さらに、Baiduは「AI推論専用クリスタルボード」の量産に向けたラインを立ち上げ、中国政府系VCから数十億円規模の出資を取り付けました。  

同時に、北京、上海、深圳などには「AIチップ開発特区」が設置され、税制優遇や補助金支給を通じてスタートアップや既存大手企業の競争を促進しています 。2024年までに、多数の国内企業が「7nm以下のプロセス技術を用いたAIチップ」の製造を目指すプロジェクトを公表し、2025年には一部製品のサンプル出荷を目指しています 。代表例は、Iluvatar CoreX(天罡100シリーズ)、MetaX(GPGPU製品)、Biren Technology(BR100)、Black Sesame Technologies(ADAS・自動運転向けAIチップ)などです 。

背景

中国政府は2015年に「中国製造2025」を正式発表し 、その中で「半導体自給率向上」を国家戦略の重要課題の一つと位置づけました。以降、国家資金や地方政府の補助金を投入しつつ、国内企業の研究開発投資を強化してきました。  

一方、2022年以降の米国による輸出規制強化は、中国にとって「外部からの技術流入を遮断しようとする動き」として受け止められました。特に2022年10月のNvidia製先端GPUに対する輸出規制強化は、中国企業のAI開発ロードマップに大きな影響を及ぼしました 。  

中国には豊富な電力インフラが整備されています。2023年にハイテク産業向け電力消費は前年比11.2%増(一部資料では11.3% )となり 、再エネ・火力を合わせた発電能力が急速に拡大していることから、「演算性能あたりの消費電力がやや高い国産チップを複数並列稼働させても電力面で吸収可能」との見方が広がっています。  

また、マイニング用途でかつて大量に投入されたGPUが電力逼迫や環境面の課題を引き起こした一方、現在はAI用途向けにより効率的な専用チップを開発するほうが有益と判断されています 。こうした経緯もあり、「マイニング規制で獲得したデータセンター運用ノウハウをAIチップ開発に転用しやすい」というアドバンテージも存在すると言われています 。  

さらに、中国国内の大規模ユーザー(インターネット企業、金融機関、製造業など)が急速にAI需要を拡大していることから、国内市場だけで十分な需要が見込める点も、企業各社の自前化を後押ししています。「中国製造2025」では、2025年までに半導体自給率を70%に引き上げるという目標が掲げられていました 。政府は引き続き半導体の国内生産能力向上を目指しており、この目標達成に向けた官民連携が加速しています。  

今後の影響予測

技術的自立の進展と国際競争

国産AIチップがある程度の性能を有し、Nvidia製GPUとのギャップを埋められれば、グローバルにおける選択肢が拡大し、中国製チップが他国のデータセンターやAIプロバイダーにも採用される可能性があります 。特に、価格競争力のあるチップが登場した場合、北米・欧州との間で技術競争が激化し、NvidiaやAMD、Intelといった従来のプレイヤーはさらなる研究開発投資を迫られるでしょう 。  

サプライチェーンの再構築

2025年以降、中国は国産素材と製造装置の内製化を加速し、製造装置メーカー(EUVリソグラフィ装置など)への投資を強化する動きが予測されます 。将来的には、「製造から設計までの垂直統合型エコシステム」を構築し、外部リスク(米国の追加規制など)に耐えうる自律的な供給網を確立する可能性が高いです 。また、日本やオランダなどの先端装置メーカーも、対中ビジネスの在り方を見直し、「協業か取引制限か」の選択を迫られることになるでしょう 。  

国内AIエコシステムへの影響

中国国内のAIプラットフォームは、国産チップの普及によってコスト構造が変化し、AIサービスの価格低下と導入企業の拡大が進むと考えられます 。これにより、医療画像診断や自動運転、スマートシティなどの分野でAI導入が加速し、「産業全体のデジタルトランスフォーメーション」が一気に進展する可能性があります 。加えて、AI関連スタートアップも国産ハードウェアを活用しやすくなることで、開発のハードルが下がり、イノベーションの創出速度が向上するでしょう 。  

地政学的リスクと世界経済への波及

中国製チップが世界市場で一定のシェアを獲得すれば、米中両国間の技術覇権争いはさらなる激化を迎えます 。米国は追加の制裁や輸出規制を打ち出す一方、中国は対抗策として関税引き下げや輸出奨励を行う可能性が高いです 。この結果、「技術ブロック化」(Tech Bloc)の傾向が強まり、世界のサプライチェーンはさらに分断されるリスクがあります 。特に半導体素材や製造装置の二極化が進むと、日本や韓国、欧州諸国は両陣営の間で揺れる立場を余儀なくされるでしょう 。  

国内雇用と産業育成

国産AIチップの量産化が進めば、中国国内では「設計エンジニア」「プロセス開発技術者」「データセンター運用エンジニア」などの需要が急増し、人材育成ニーズが拡大します 。これに呼応して、大学や研究機関は半導体設計・製造分野のカリキュラムを強化し、国内の技術者供給を担保する動きが活発化するでしょう 。その結果、ハイテク産業の雇用創出効果が高まり、中国経済の高度化をさらに加速させる要因となります

まとめ

米国のエヌビディアGPU輸出規制に端を発した中国のAI半導体自前化戦略は、「国家安全保障上の必要性」と「膨大な国内市場の存在」という二つの要因に後押しされています。Nvidia規制前は高性能GPUを輸入に依存していた中国企業が、2023年以降は自社・国内メーカー製のAIチップにシフトし、既存のデータセンターアーキテクチャを改変して対応することを余儀なくされました 。政府の補助金や税制優遇措置、設計・製造拠点の集約化などを通じて、国内ベンダーは短期間で「7nmプロセスAIチップ」のプロトタイプ開発を達成しました 。2025年には一部企業が量産体制の構築を目指し、中国製AIチップの実運用が現実味を帯び始めています。  

今後、中国製チップの国際競争力が高まれば、世界のAIハードウェア市場は二極化傾向を強める可能性があります。技術ブロック化の懸念が高まる中、日本や欧州などのサプライチェーンは新たな調整を迫られるでしょう。国内ではAIサービスの普及と産業のデジタル化が加速し、ハイテク人材需要の高まりを背景に経済成長への寄与が期待できます。一方、米中間での技術覇権争いが激化すれば、半導体素材・製造装置の流通が一層限定され、各国は自国の供給網を強化せざるを得ない状況に陥るでしょう。

以上のように、「エヌビディア規制で加速する中国のAI半導体自前化戦略」は、単なる技術的トレンドにとどまらず、地政学的・経済的に重大なインパクトを伴う大きな潮流と言えます。

参考リンク

PostgreSQLでLIMIT句を使ったサーバーサイドページネーションは実現できるか

きっかけ

REST API でサーバーサイドページネーションを実現したいと考えたのですが、指定したページのデータをデータベースから効率よく検索できないのであれば、一回ですべてを取得した方が結果的に効率的になります。

クライアントのスペックをそれなりに見込むことができれば、クライアントサイドページネーションの方が効率的ですが、ヒットする件数が膨大だったり、1レコードのデータ量が多い場合はそれも難しくなるため、何らかの形でサーバーサイドページネーションを検討する必要がでてきます。

ChatGPT に REST API でのサーバーサイドページネーションの実現方法について訊いたところ、以下の3つの方式を提案されました。

オフセットベースページネーション

GET /items?offset=20&limit=10

特徴

  • 利点:実装が簡単。UI側でも扱いやすい。
  • 欠点:大量のデータでページ数が大きいと、パフォーマンスが低下(インデックスが効かなくなる可能性)。

もっともよく見かけるパターンだと思います。どこから取得するか(offset)と最大何件取得するか(limit)で指定する方法になります。そもそも一度に取得する件数に200件とかの上限があって、201件目以降を取得したい場合はoffiset付きで取得してください、といった使われ方をするのが多いのではないでしょうか。

単純増加かつ昇順で検索する場合はデータの重複や抜けが起きにくいですが、単純増加かつ降順の場合や途中にデータが差し込まれる場合は前回取得した位置がズレるので、データの抜けや重複が発生する場合があります。

ページベースページネーション

GET /items?page=3&size=10

特徴

  • 利点:ユーザー視点ではページ単位が直感的。
  • 欠点:内部的にはoffset/limitと同じ課題(大きなページ数で遅くなる)。

オフセットベースと基本的に同じ発想ですが、指定方法が具体的な件数ではなくページという単位にすることで指定しやすくした方式でです。多くのサービスでは1ページあたりのサイズ(size)は指定せず、ページのみでアクセスさせるのではないかと思います。サービス側で設定しているページサイズをもとにデータを区切って何ページ目を取得するか、という形で指定することになります。

指定方法が異なるだけで、基本的な性質はオフセットベースと同じです。

カーソルベースページネーション

GET /items?after=eyJpZCI6MTIzfQ==&limit=10

特徴

  • 利点:安定して高速(インデックスが効く)。データが更新されても影響を受けにくい。
  • 欠点:実装がやや複雑。前のページに戻るのが難しい。

前述のオフセットベースとページベースでは、単純増加のキーで保存されているデータを降順で取得するとデータの抜けの心配があります。多少前後で同じデータが表示されたり、抜けがあってもそれほど問題にならない場合は、オフセットベースやページベースが簡単だと思いますが、特に抜けを許容できない場合はカーソルベースページネーションが有効な手立てとなります。

条件として検索キーが単純増加かつ途中に差し込まれることがないテーブルに対して指定した値(after)よりも前や後のデータをヒットさせるようにすることで重複や抜けがないようにデータを取得することができます。

いずれのパターンにおいても、テーブル設計やインデックス設計が重要となることに加え、取得されたデータの重複や抜けをどこまで対策するか許容するかの要件によって選択肢が変わってきます。

後述の検証では、カーソルベースページネーションをPostgreSQLのLIMIT句を使って実現できるかを検証してきます。

PostgreSQLのLIMIT句の挙動について

PostgreSQLのLIMIT句を使ってカーソルベースページネーションが有効に働くかを訊いたところ、以下のように回答がありました。

質問

以下のようなSQLを発行したときに、インデックスを使って条件に合致する10件のみをフェッチできますか?

SELECT * FROM histories
WHERE create_user_id = ? AND id < ?
ORDER BY id DESC
LIMIT 10;

前提条件

  • id:PK(= 自動で昇順インデックスがある)+ id DESC の降順インデックスも明示的に付与されている
  • create_user_id:昇順インデックスあり(例:CREATE INDEX ON histories (create_user_id))

回答


PostgreSQLは 複合インデックス がある場合に、以下のような最適化を実現できます:

CREATE INDEX idx_histories_userid_id_desc
ON histories (create_user_id, id DESC);

どうやら、個別のインデックスではダメで、WHERE句とLIMIT句の両方を満たす1つのインデックスがあれば、インデックスを効率的に使用して条件に合致する10件のみをフェッチできるようです。

ChatGPT からは PostgreSQL をデータベースとして使用している場合に、 LIMIT句を使った方法が可能であると回答をもらいました。ただし、生成AIは必ずしも正しい回答をするわけではないので、実際に試して検証することにします。

カーソルベースページネーションの検証

Docker composeでPostgreSQLを構築する

手早くPostgreSQLの環境を構築するために、Docker composeで作成しました。

services:
  db:
    image: postgres:17
    container_name: postgres17
    restart: unless-stopped
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: postgres
    ports:
      - "5432:5432"
    volumes:
      - ./initdb:/docker-entrypoint-initdb.d:ro

すでに同じcontainer_nameを起動している場合は他の名前を指定してください。とりあえず起動確認だけしておきます。

$ docker compose up -d
[+] Running 2/2
 ✔ Network pagination-demo_default  Created
 ✔ Container postgres17             Started
$ psql -h localhost -U postgres -d postgres
Password for user postgres:
psql (17.4, server 17.2 (Debian 17.2-1.pgdg120+1))
Type "help" for help.

postgres=# \dt
Did not find any relations.
postgres=#
postgres-# \q

とりあえず問題なさそうです。

検証用のテーブルを作成する

今回は以下の要件を満たす、download_historiesテーブルを作成します。

  • PKはレコードの登録順でインクリメントされ、必ず時系列順になる(途中で割り込まれることがない)
  • ユーザーIDをもち、ユーザーIDで対象レコードを絞り込むことができる

以下のようなテーブルにしましたが、今回検証で使用するのはid列とuser_id列です。

CREATE TABLE download_histories (
  id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  user_id INTEGER        NOT NULL,
  created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);

こちらも念のため動作確認しておきます。

$ docker compose down -v
[+] Running 2/2
 ✔ Network pagination-demo_default  Created
 ✔ Container postgres17             Started
$ psql -h localhost -U postgres -d postgres
Password for user postgres:
psql (17.4, server 17.2 (Debian 17.2-1.pgdg120+1))
Type "help" for help.

postgres=# \dt
               List of relations
 Schema |        Name        | Type  |  Owner
--------+--------------------+-------+----------
 public | download_histories | table | postgres
(1 row)

postgres=# \d download_histories
                              Table "public.download_histories"
   Column   |           Type           | Collation | Nullable |           Default
------------+--------------------------+-----------+----------+------------------------------
 id         | bigint                   |           | not null | generated always as identity
 user_id    | integer                  |           | not null |
 created_at | timestamp with time zone |           | not null | now()
Indexes:
    "download_histories_pkey" PRIMARY KEY, btree (id)

postgres=# \q

問題なくテーブルが作成されていることを確認できました。

ページネーションに必要なインデックスを設定する

ページネーションを実現するための要件は以下のとおりです。

  • データはid列の降順(=created_at列の降順)で取得する
  • 指定したuser_idと一致すレコードを取得する

id列は単純増加のため、降順でid=100まで取得していれば次のデータは必ず100未満になることが保証されています。(取得するデータは最新のデータから過去の向けって取得する)

動作を検証するために以下の2種類のインデックスを試します。

  • PKに加え、id列の降順インデックスとuser_id列の昇順インデックスをそれぞれ追加する
  • user_id列の昇順+id列の降順の複合インデックスを追加する
-- 1. id の降順インデックス
CREATE INDEX idx_download_histories_id_desc
  ON download_histories (id DESC);

-- 2. user_id の昇順インデックス
CREATE INDEX idx_download_histories_user_id_asc
  ON download_histories (user_id ASC);

-- 3. user_id 昇順 + id 降順 の複合インデックス
CREATE INDEX idx_download_histories_user_id_id_desc
  ON download_histories (user_id ASC, id DESC);

これは必要になったタイミングで設定するようにします。

テストデータを用意するSQLを作成する

インデックスが十分に効いているかを検証したいので、それなりにデータ量が必要となります。

今回は以下の条件を満たすレコードを生成することにしました。

  • user_id1から100までの100名とする
  • 1つのuser_idに対して100,000件のレコードを登録する

登録するレコード数は10,000,000件になるため、1行ずつ登録するのは非効率なため、以下のSQLでまとめて登録するようにしています。

INSERT INTO download_histories (user_id)
SELECT gs_users.user_id
FROM generate_series(1, 100)   AS gs_users(user_id)
CROSS JOIN generate_series(1, 100000) AS gs_seq(seq);

これをinitdb配下に配置した初期データ投入用のSQLファイルに以下のように定義してコンテナを再起動します。

CREATE TABLE download_histories (
  id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  user_id INTEGER        NOT NULL,
  created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);

INSERT INTO download_histories (user_id)
SELECT gs_users.user_id
FROM generate_series(1, 100)   AS gs_users(user_id)
CROSS JOIN generate_series(1, 100000) AS gs_seq(seq);

ページネーションで発行する想定のSQLをexplain付きで実行すると、以下のようになりました。

postgres=# explain select * from download_histories where user_id = 56 and id < 12345 order by id desc limit 10;
                                                        QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.43..201.87 rows=10 width=20)
   ->  Index Scan Backward using download_histories_pkey on download_histories  (cost=0.43..363532.10 rows=18047 width=20)
         Index Cond: (id < 12345)
         Filter: (user_id = 56)
(4 rows)

体感では非常に高速でしたが、実行計画を見るとcostが高いことがわかります。少ない件数で試すとコストが下がっているので、唯一存在するPKによるインデックススキャンは使用しつつも登録されているデータ件数に依存したコストがかかっていることがわかります。

これでひととおりの準備が整いました。次に前述のインデックスを当てた時に上記のSQLのコストがどう変わるのかを確認していきたいと思います。

検証1:user_id列とid列に個別のインデックスを設定する

ChatGPT の回答では十分な効果が得られないと言われていた個別のインデックスを設定する方法を試してみます。具体的には、以下のINDEXを追加して前述のSELECT文の実行計画を確認します。

-- 1. id の降順インデックス
CREATE INDEX idx_download_histories_id_desc
  ON download_histories (id DESC);

-- 2. user_id の昇順インデックス
CREATE INDEX idx_download_histories_user_id_asc
  ON download_histories (user_id ASC);

使用する初期データ投入用のSQLファイルの全体は、以下になります。

CREATE TABLE download_histories (
  id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  user_id INTEGER        NOT NULL,
  created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_download_histories_id_desc
  ON download_histories (id DESC);

CREATE INDEX idx_download_histories_user_id_asc
  ON download_histories (user_id ASC);

INSERT INTO download_histories (user_id)
SELECT gs_users.user_id
FROM generate_series(1, 100)   AS gs_users(user_id)
CROSS JOIN generate_series(1, 100000) AS gs_seq(seq);

同じクエリを実行したところ以下のようになり、追加したインデックスは使用していないことがわかります。

postgres=# explain select * from download_histories where user_id = 56 and id < 12345 order by id desc limit 10;
                                                        QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.43..201.87 rows=10 width=20)
   ->  Index Scan Backward using download_histories_pkey on download_histories  (cost=0.43..363532.10 rows=18047 width=20)
         Index Cond: (id < 12345)
         Filter: (user_id = 56)
(4 rows)

データの件数が少なくてPKのインデックスを逆順で使えば十分と判断された可能性もありますが、とりあえずそのまま検証を続けていきます。

検証2:user_id列とid列の複合インデックスを設定する

続いて、user_id列とid列の複合インデックスを使って同じクエリを試してみます。使用する初期データ投入用のSQLファイルの全体は以下のようになります。

CREATE TABLE download_histories (
  id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  user_id INTEGER        NOT NULL,
  created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_download_histories_user_id_id_desc
  ON download_histories (user_id ASC, id DESC);

INSERT INTO download_histories (user_id)
SELECT gs_users.user_id
FROM generate_series(1, 100)   AS gs_users(user_id)
CROSS JOIN generate_series(1, 100000) AS gs_seq(seq);

同じクエリを実行したところ以下のようになり、追加した複合インデックスが使われていることがわかります。

postgres=# explain select * from download_histories where user_id = 56 and id < 12345 order by id desc limit 10;
                                                         QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.56..18.87 rows=10 width=20)
   ->  Index Scan using idx_download_histories_user_id_id_desc on download_histories  (cost=0.56..189.12 rows=103 width=20)
         Index Cond: ((user_id = 56) AND (id < 12345))
(3 rows)

コストが格段に下がっており、インデックスを使用したときのフェッチ件数も18047から103に下がっていることがわかります。

追加検証:データのバランスを変更したどうなるか?

検証1で追加したインデックスが使われなかった点についてもう少しだけ検証してみます。データ量を少し増やしみて、それでも追加したインデックスは使われないのかを検証します。

以下のようにデータ量を増やして再度検証してみます。

  • ユーザー数:100 → 1,000
  • 1ユーザーあたりのデータ件数:100,000 → 10, 000

ダウンロード履歴テーブルなので、1ユーザーのダウンロード回数を抑えつつ、利用者数を増やす形にしています。

INSERT INTO download_histories (user_id)
SELECT gs_users.user_id
FROM generate_series(1, 1000)   AS gs_users(user_id)
CROSS JOIN generate_series(1, 10000) AS gs_seq(seq);

実行するクエリはデータのバランスが変更されたことに合わせて、以下のようにしました。

explain select * from download_histories where user_id = 1234 and id < 12345 order by id desc limit 100;

上記の条件で、各パターンで実行計画を取得すると以下のようになりました。

追加インデックスなし

postgres=# explain select * from download_histories where user_id = 1234 and id < 12345 order by id desc limit 100;
                                                     QUERY PLAN
---------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.43..492.30 rows=13 width=20)
   ->  Index Scan Backward using download_histories_pkey on download_histories  (cost=0.43..492.30 rows=13 width=20)
         Index Cond: (id < 12345)
         Filter: (user_id = 1234)
(4 rows)

個別インデックスあり

postgres=# explain select * from download_histories where user_id = 1234 and id < 12345 order by id desc limit 100;
                                                        QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.43..2014.80 rows=100 width=20)
   ->  Index Scan Backward using download_histories_pkey on download_histories  (cost=0.43..363532.10 rows=18047 width=20)
         Index Cond: (id < 12345)
         Filter: (user_id = 1234)
(4 rows)

複合インデックスあり

postgres=# explain select * from download_histories where user_id = 1234 and id < 12345 order by id desc limit 100;
                                                           QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.56..355.46 rows=100 width=20)
   ->  Index Scan using idx_download_histories_user_id_id_desc on download_histories  (cost=0.56..64049.50 rows=18047 width=20)
         Index Cond: ((user_id = 1234) AND (id < 12345))
(3 rows)

サーバーサイドページネーションは必ずしも必要ないかもしれない

2回目の検証でも1ユーザーあたり10,000回のダウンロード履歴を想定しています。何をダウンロードするかにもよりますが、営業日に平均1日1回ダウンロードするとしても年間240回、10,000回ダウンロードするには40年以上かかる計算になります。

となると、サーバーサイドページネーションが必要となるかどうかは、データの増加量とレスポンスサイズによると考えられます。

適当な状況を想定して計算してみましょう。

システムによって異なりますが、一般的にはレスポンスボディのサイズが10MB以下に設定するとします。ヘッダーの計算はちょっと面倒なので、2MBバイトだとしてレスポンスボディのサイズは8MB以下になるようにするとしましょう。

1件のデータが仮に1KBだとすると、8,192行のデータがレスポンスとして返せる計算になります。通常の利用範囲でシステムの耐用年数使い続けてもこの行数を超えないのであれば、そもそもサーバーサイドページネーションは不要ということになります。毎日平均10行増えるとしても1年間3,650行増えるので、2年ちょっとの間はこのサーバーサイドページネーションが必要ないと言えます。

ダウンロードを行った履歴となるとダウンロードしたファイル名やダウンロード日時などを含むだけなので、多めに見積もって512バイトだとして、月多くても10回ほどしかダウンロードしないとすると、年間120行増えるだけなので、レスポンスボディの上限に到達するには136年もかかることになるため、コストをかけてまでサーバーサイドページネーションを実装する必要はない、という結論になります。

このことから、かなりのペースでデータが増加したり、ヒットするデータ量が膨大になるなどの前提がある場合はサーバーサイドページネーションを検討する価値がありますが、ユーザー自身の操作でデータが増えるだけだとサーバーサイドページネーションがなくてもシステム的には問題ないという場合もある点は重要な学びです。

まとめ

最初はChatGPTの回答を検証することが目的でしたが、最終的にはサーバーサイドページネーションが必要かどうかはデータ量の見積もりによって決まるという話になりました。

最初の疑問に立ち返ると、ChatGPTの回答どおりにWHERE句とLIMIT句の条件を組み合わせた複合インデックスを追加することで、性能が向上することは確認できました。ただし、圧倒的に優れているかと言われるとデータのバランス次第という感じだったので、実際に検索するテーブルに想定されるバランスのテストデータを登録して実際に実行されるクエリを使って検証することが重要だと思います。

Microsoftが発表したWindowsおよび周辺アプリの変更について利用者が注意すべきポイント

以下では、Microsoftの公式情報にもとづき、Windows 11 24H2の強制アップデートに関する発表と既知の不具合、BitLocker(ストレージ暗号化)の自動有効化によるデータ喪失リスク、そしてMicrosoft Authenticatorのパスワード管理機能廃止について解説します。いずれも利用者に影響し得る重要トピックです。それぞれ明確な見出しのもとに詳細をまとめます。

Windows 11 24H2の強制アップデート

Windows 11 24H2への大型アップデートは順次すべての適格デバイスに提供され、自動適用が進められています。利用者にとっては、不安定な更新が強制されるリスクに注意が必要です。

MicrosoftはWindows 11 バージョン24H2(通称「Windows 11 2024 Update」)の一般提供を開始し、段階的ロールアウトの最終フェーズに入ったと述べています。特に、Windows Update経由での自動更新について「Windows 11 バージョン23H2/22H2/21H2を実行しているHomeおよびProエディションのデバイス(かつIT部門に管理されていないもの)は、バージョン24H2への更新プログラムが自動的に配信される」ことが公式にアナウンスされています。ユーザーは再起動のタイミングを選択したり、短期間(通常1週間程度)であれば延期も可能ですが、基本的には管理されていない一般ユーザーPCには強制的に24H2へのアップデートが適用される流れです。企業の管理下にない端末(例えば自宅利用のPCや小規模事業のPC)が対象となるため、企業ユーザーであってもこうした端末を業務利用している場合は注意が必要です。一方、社内でWindows Update for BusinessやIntune、グループポリシーなどにより更新管理されているデバイスはこの自動適用の対象外ですが、遅かれ早かれ24H2へのアップグレード計画を立てる必要があります。

こうした強制アップデートに対し、利用者からは「十分に検証されていない不安定なアップデートが強制されるのではないか」という懸念が出ています。アップデート中はPCの再起動が繰り返され長時間かかる可能性があり、業務に支障をきたすおそれがあります。また、アップデート適用後にシステム不具合(最悪の場合Blue Screen of Death、いわゆるSTOPエラー)が発生すると業務停止につながりかねません。実際、Windows 11 24H2にはいくつかの既知の不具合が公式に報告されています。企業環境ではWSUSや更新ポリシーでアップデートのタイミングを制御できますが、最新バージョンへの追随そのものは避けられないため、以下のような問題点を把握した上で慎重に展開することが重要です。

未だ不具合が報告されている状況にある24H2ですが、強制アップデートによる影響を軽減させるためにバックアップなどの対策を行いつつ、アップデートに伴う業務停止時間を最小限にするように計画を立てておく必要が

Windows 11 24H2のストレージ暗号化自動化(BitLocker)とデータ喪失リスク

Windows 11 24H2ではデバイスのストレージ暗号化(BitLocker)が初期設定で有効になるケースが増えています。暗号化自体はセキュリティ強化策ですが、万一に備えて回復キーの管理に注意しないと、ユーザーが自分のデータにアクセスできなくなるリスクがあります。

MicrosoftはWindows 11のセキュリティ強化の一環として、「モダンなシステムのほとんどでBitLockerをデフォルト有効化した」と述べています。従来、BitLockerによるドライブ暗号化は主にPro以上のエディションや企業向けに重視されていましたが、Windows 11 24H2では要件緩和によりHomeエディションを含む幅広いシステムで自動的にデバイス暗号化(BitLocker相当)が有効となるよう変更されています。例えばモダンスタンバイ対応のPCだけでなく、TPMを備えた一般的なPCでも条件を満たせばセットアップ時に暗号化がオンになります。これは盗難・紛失時のデータ保護には有効であり、Microsoftも「チップからクラウドまでWindows 11は既定でより安全になった」とアピールしています。

BitLocker自動化の仕組み

初期セットアップや24H2へのアップグレード時に、ユーザーが明示的に操作しなくてもバックグラウンドでドライブ暗号化が開始される場合があります。この際、回復キー(Recovery Key)のバックアップが自動で行われるのが通常です。具体的には、個人のMicrosoftアカウントでWindowsにサインインしている場合、BitLockerの48桁の回復キーはそのアカウントにひも付けられオンラインで取得可能な状態で保存されます。一方、職場や学校の管理下にあるデバイスでは、回復キーはAzure ADやActive Directoryに自動バックアップされ、組織のIT部門が管理します。このように、ユーザー自身が意識しなくとも「回復キーの保管」自体は行われる設計です。ただしMicrosoftも強調しているように、「このバックアップが確実に存在しアクセス可能かを検証すること、必要に応じて自前の追加バックアップを作成すること」が極めて重要です。万一クラウドへのキー保存がされていなかったり、ユーザーが誤ってキー情報を削除してしまっていると、暗号化ドライブにアクセスできなくなった際に復旧手段がなくなるためです。

データ喪失のリスクと注意点

BitLocker暗号化が自動有効になることで懸念されているのが、ユーザーが回復キーを把握していない場合のデータ喪失リスクです。実際、「Windowsのアップデートや設定変更後に突如BitLockerによってロックがかかり、自分のデータにアクセスできなくなった」という報告が増えていると指摘する声もあります。例えばあるユーザーは、「MicrosoftはMicrosoftアカウントでサインインすると自動的にBitLockerを有効化するようになった。もしそのMSアカウントへのアクセス権を失えばデータも永遠に失う。【警告も再チャンスもなく、BitLockerに初めてロックアウトされたときにその存在を知る人が多い】」と述べ、一般ユーザーにとってはデータ機密性よりも可用性(アクセスできること)の方が重要であるケースが多いのに、バックアップの周知不足により「悲劇的な失敗(致命的なデータ損失)」が起きかねないと批判しています。これは決して大げさな懸念ではありません。企業から貸与されたPCや共有端末の場合、利用者自身が回復キーを知らされていなかったり、管理者もキーを紛失してしまうと、そのPC上のローカルデータには誰もアクセスできなくなります。特にリモートワークで従業員が各自セットアップしたPCを使っているような場合、本人が暗号化の存在を認識しておらずキーのバックアップを怠っていると、ちょっとしたハードウェア変更やファームウェア更新が引き金でBitLockerリカバリを求められ、業務データが人質に取られるような事態も起こりえます。

このようなリスクへの対策として、Microsoftは公式ガイドでBitLocker回復キーの確認・バックアップ方法を公開しています。企業環境では、可能であればAzure ADやMBAM(Microsoft BitLocker Administration and Monitoring)等で全端末の回復キーを一元管理する運用が望まれます。また、24H2への更新ポリシー適用時に自動暗号化を無効化するレジストリ設定([DisableDeviceEncryptionキーの利用など】)も技術的には可能です。しかしセキュリティ強化とのトレードオフになるため、基本方針としては暗号化は有効にした上で、キー管理を徹底することが推奨されます。具体的には以下の点に注意してください:

  • キーの所在確認: Microsoftアカウント利用時は「デバイスの一覧」ページから回復キーを確認できます。同僚や部下のPCについても、組織管理下であればAzure ADポータル等からキーを取得可能です。万一に備え、全デバイスのキー情報が揃っているか今一度チェックしましょう。
  • ユーザー周知: IT部門からエンドユーザーへ、「BitLocker暗号化が有効になっている」ことと「回復キーの重要性」について周知徹底してください。鍵を紛失するとデータ復旧不能になる旨を伝え、可能ならユーザー自身にもキーのバックアップ(印刷保管や安全なクラウド保管)を促します。
  • シナリオテスト: ハードディスク交換やBIOSパスワード変更など、BitLockerがリカバリキー入力を要求する典型的なシナリオをテストしてみましょう。キーを正しく入力できるか、手順に不備がないかを事前に確認しておくことで、実際のトラブル時に落ち着いて対応できます。

以上を踏まえ、Windows 11 24H2環境では「暗号化されていることを前提に運用を組み立てる」ことが不可欠です。セキュリティは強化されますが、その裏で鍵管理がおろそかになると本末転倒です。企業としてはデータ漏えいとデータ消失の双方のリスクを考慮し、ポリシーと教育を整備する必要があります。

Microsoft Authenticatorのパスワード管理機能廃止

Microsoft Authenticatorアプリのパスワード保存・自動入力機能が2025年中に段階的終了します。モバイルでAuthenticatorをパスワード管理に使っていたユーザーは、Edgeブラウザーへの移行やエクスポートを求められており、通知を見逃すとパスワードを失う可能性があるため注意が必要です。

Microsoftは「Authenticatorアプリ内のオートフィル(パスワード管理)機能を廃止し、今後はMicrosoft Edgeに統合する」ことを発表しました。これは2025年に入ってから公開されたサポート文書で明らかにされたもので、ユーザーにとって有用だったAuthenticatorのパスワード保存機能を停止する代わりに、より多くのユーザーをEdgeブラウザへ誘導する意図があるとされています。公式には「複数デバイス間でパスワードを容易に使えるようオートフィル体験を整理統合するため」と説明されており、実質的にモバイルにおけるパスワードのオートフィル管理はEdgeに一本化される流れです。

段階的廃止のスケジュール

廃止は一夜にして行われるわけではなく、以下の段階を追って実施されます。

  • 2025年6月 – Authenticatorアプリ上で新しいパスワードを保存する機能が無効化されます。これ以降、Authenticator内には新規のログイン情報を追加登録できなくなります。
  • 2025年7月 – Authenticatorによるパスワード自動入力(オートフィル)機能が停止します。同時に、Authenticatorに保存されていたクレジットカードなどの支払い情報はデバイス上から削除されます(これら支払い情報は他デバイスと同期されない設計のため、このタイミングで消去されると公式に説明されています)。
  • 2025年8月 – Authenticatorアプリに保存されていたパスワードが全て利用不能になります。8月1日をもってサーバー上からも関連データが消去され、以降Authenticatorアプリを開いても既存パスワードは表示されなくなります。

このスケジュールに沿い、最終的にはAuthenticatorアプリからパスワード機能そのものが完全に撤去されます。ただし、アプリ自体は今後も二要素認証コードの生成やパスキーの保存用途で引き続き利用可能です。あくまで削除されるのは「パスワードの保存・入力機能」の部分だけですが、ユーザー体験としては「Authenticatorが大幅に機能縮小される」ことになるため注意が必要です。

利用者への影響と注意点

この変更で最も懸念されるのは、「通知を見逃したユーザーが突然パスワードを失ってしまう」リスクです。MicrosoftはAuthenticatorユーザーに対し、Edgeへの移行またはサードパーティ製パスワードマネージャーへのエクスポートを推奨しています。公式メッセージでは「2025年8月1日より後はAuthenticator内のパスワードおよび情報は自動的に削除されるため、それまでにデータをエクスポートしておくように」と案内しています。しかし、この情報は主にウェブのサポート記事や一部報道を通じて伝えられているもので、アプリ内通知を見落としていたり、そもそも変更自体を知らないユーザーも存在するでしょう。例えば個人でAuthenticatorを使っていた従業員がこの事実を知らない場合、8月になってからアプリを開いて初めて「保存していた多数のサイトのパスワードが消えている」ことに気付き、業務ログインに支障が出るかもしれません。

企業のIT担当者は、従業員がAuthenticatorのパスワード機能を利用しているか把握し、必要に応じてサポートすることが求められます。具体的には:

  • 周知徹底: 会社から「Microsoft Authenticatorでパスワードを保存・自動入力している場合、近日中に使用できなくなる」旨を告知し、各自でEdgeブラウザーの機能に移行するか、データをエクスポートして別のパスワード管理ツールにインポートするよう促しましょう。
  • データエクスポート支援: AuthenticatorアプリにはパスワードデータをCSV形式でエクスポートする機能があります。IT部門として手順を案内したり、必要ならエクスポート作業を支援してください。またエクスポートしたファイルの安全な取扱い(暗号化保管・早期削除)についてもアドバイスすべきです。
  • 代替ソリューションの提示: Microsoftが推奨するようにEdgeブラウザの組み込み機能を使う方法以外にも、企業ポリシーで許可された信頼性の高いパスワード管理ソフト(例: 1PasswordやLastPass、Keeperなど)への移行を検討しても良いでしょう。重要なのは、ユーザーがパスワード管理難民にならないよう事前に受け皿を用意することです。

今回のAuthenticator機能廃止は、Microsoftアカウントを取り巻くパスワードレス戦略の一環とも言われています。実際、同時期にMicrosoftアカウントのパスワードレス認証(パスキーなど)の拡充も発表されています。しかし現実には多くのWebサービスが未だパスワードで保護されており、ユーザー側でパスワードを管理しなければならない状況は当面続きます。企業においても、従業員が誤ってAuthenticator任せにしていたパスワードを失わないよう、そして安全なパスワード管理方法へ円滑に移行できるよう、期限(2025年8月)までに対応を完了させることが望まれます。

まとめ

以上、Windows 11 24H2の強制アップデートと不具合、BitLocker自動暗号化の留意点、Microsoft Authenticatorのパスワード機能廃止について解説しました。いずれのトピックも「セキュリティ強化」や「最新環境への移行」という大きな流れの中で起きている変化ですが、その過程で一時的にユーザーや管理者の負担・リスクが増す側面があります。企業のIT管理者としては公式情報を注視し、適切なタイミングで社内システムやポリシーを調整することが重要です。幸いMicrosoftからは定期的に詳細な発表やドキュメントが提供されていますので、信頼性の高い一次情報をもとに迅速かつ的確な対応を心がけましょう。本記事の情報が、皆様の環境をアップデートしつつ安全に維持する一助になれば幸いです。

target=”_blank”を使うときはrel=”noreferrer”を指定しよう

ウェブサイトを運営する際、外部リンクを新しいタブやウィンドウで開くために、リンクにtarget="_blank"を指定することがあります。しかし、この指定だけではセキュリティ上のリスクが生じる可能性があります。そこで、rel属性にnoopenernoreferrerを追加することが推奨されています。この記事では、noopenernoreferrerの違い、サポートブラウザの違い、両方を併用する理由、そしてそれぞれの使い分けについて解説します。

noopenerとは?

<a href="..." target="_blank" rel="noopener">リンク</a>

noopenerは、リンク先のページが元のページ(リンク元)への参照を持たないようにするための値です。具体的には、target="_blank"を指定したリンクをクリックすると、新しいタブやウィンドウでリンク先が開かれますが、その際、リンク先のページからwindow.openerプロパティを介してリンク元のページにアクセスできてしまいます。これにより、リンク先のページがリンク元のページを操作するリスクが生じます。rel="noopener"を指定することで、window.openerプロパティがnullとなり、リンク先からリンク元へのアクセスを防ぐことができます。

noreferrerとは?

<a href="..." target="_blank" rel="noreferrer">リンク</a>

noreferrerは、noopenerの機能に加えて、リンク元のURL情報(リファラー)をリンク先に送信しないようにするための値です。通常、リンクをクリックすると、リンク元のURLがリファラーとしてリンク先に送信されますが、rel="noreferrer"を指定することで、これを防ぐことができます。これにより、プライバシーの保護や、リンク元の情報漏洩を防ぐことが可能となります。

サポートブラウザの違い

noopenernoreferrerのサポート状況はブラウザによって異なります。主要なブラウザの対応状況は以下の通りです。

noopenerをサポートするブラウザ

noopenerは比較的新しい仕様で、対応しているブラウザは後述のnoreferrerと比べると狭くなります。

rel=noopener – HTML: ハイパーテキストマークアップ言語 | MDN

noreferrerをサポートするブラウザ

前述のnoopenerと比べると対応しているブラウザの範囲は広くなります。

rel=noreferrer – HTML: ハイパーテキストマークアップ言語 | MDN

両方を同時に指定することが推奨されていたのは何故か?

<a href="..." target="_blank" rel="noopener noreferrer">リンク</a>

ここまで見ると、noreferrerはカバーしている機能もサポートブラウザもnoopenerよりも広いため同時に指定する理由はないように見えます。

では何故同時に推奨されていた時期があったのでしょうか?

この点について理解するためにnoopenernoreferrerに関する議論をいくつか調べました。

同時に指定することを推奨されていた理由

過去の話であるため、どこまで信憑性があるかは不明ですが、次のような理由でnoopenernoreferrerを両方指定することが推奨されていた時期があったようです。

  • 仕様に準拠していないレガシーブラウザに対応するため
  • Firefox 33-35で発生していた不具合に対する対策

非準拠ブラウザに対する対策

仕様に準拠していないブラウザでnoreferrerを指定してもwindow.openernullにならないことに対する対策として、noopenerを同時に指定していた、そういうブラウザが存在する可能性を想定して同時に指定していたようです。

@seancrater I don’t; the spec is often aspirational, and doesn’t describe historical (noncompliant) engines.

In general, if any version of any browser ever required both, then we should use both for the foreseeable future.

確かに、過去ChromeとFirefoxで動作が異なったり、一部のブラウザで問題が起きるといったことはありました。以下の記事では、EdgeでYahoo! Japanを表示したときに正しく表示されないという問題について問い合わせています。

今後もこのように特定のブラウザの特定のバージョンでのみ不具合が起きる可能性を考慮し、同時に指定することに対して、若干バンドルサイズが大きくなることしかデメリットがないことを考えると両方を指定しておくことは心理的安心という面からも適切な判断だと考えられます。

Firefox 33-35で発生してた不具合に対する対策

もう一つの理由はFirefox 33-35で発生していた、noreferrerを指定すると別タブで開けなくなる不具合に対する対策で、ESLintのIssueでこの点について議論されています。

Actually, I found a counter-example: Firefox 33–35 removes opener with rel="noreferrer" but doesn’t with rel="noreferrer noopener" (probably because it encounters an unsupported rel value). If you have a Browserstack account, you can verify it by opening http://noreferrer.hypnosphi.de (source) in FF 33–35 and clicking the links there.

Firefox側のIssueを見ると、noreferrerをつけていてもリファラーを送っているとありますが、これがwindow.openernullになっていないことと同じことなのかは今ひとつわかりませんでした。

If you open a link with the rel=”noreferrer” attribute in a new tab (eg. over middle click) it will send a referrer anyway.

ESLintではnoopenernoreferrerを両方指定するようにチェックしていた時期がありましたが、現在ではnoreferrerがついていることをチェックし、noopenerもついているかどうかはチェックしないようになっています。

WordPressでrel=”noopener”が自動付与される理由

WordPressでは、バージョンによって、target="_blank"を持つリンクにrel="noopener"が自動付与されるのか、rel="noopener noreferrer"が付与されるのかが変わっていたようです。

WorkPress 4.7.4からセキュリティ対策のためにrel="noopener noreferrer"が自動的に付与されるようになりました。しかし、WordPress 4.8では、rel="noopener"だけが自動付与されるように変更されています。

WordPress 5.0では新しいエディタ「Gutenberg」が導入され、rel="noopener noreferrer"が自動付与されるようになった一方で、クラシックエディタを使用している場合にはrel="noopener"だけが自動付与されるようになっていました。

WordPress 5.6ではrel="noopener"だけが自動付与されるようになり、以降はrel="noopener"だけが自動付与される仕様に落ち着いているようです。

WordPressが、rel="noreferrer"ではなくrel="noopener"を付与しているのは、セキュリティ対策をしつつアフィリエイトリンクなどのためにリファラーを送りたい(参照元を知らせたい)という点にあります。認証が必要なページと違って、ページのURLを知ってもらう機会を少しでも減らさないためにも、noreferrerではなくnoopenerが求められます。

パフォーマンス対策としてのnoopener

仕様には記載がなく、実装依存の話としてnoopenerを指定する効果のひとつにパフォーマンス対策を挙げている記事を見かけます。しかし、この主張は必ずしも正しいというわけではなく、ブラウザの実装依存であるという点は理解しておく必要があります。

window.openernullでない場合、元ページを開いているタブとtarget="_blank"で開いたページのタブは同じプロセス・スレッドで動作することになり、開いたページで重いスクリプトを実行すると、元ページのパフォーマンスにも影響を与えるというものです。

実際のブラウザのコードを見たわけではありませんが、最近のバージョンではここら辺は対策済みになっているのではないかと思います。タブの数だけスレッドが作成されるわけでもありませんし、特のタブが応答しなくても他のタブは問題なく操作できているので、主要ブラウザではこの点はあまり気にする必要がないと思います。

結局、どれを付与すればよいのか?

noopenernoreferrerのどちらを付与すればよいかについてまとめます。

「どちらも付与しない」は非推奨

タブブラウザが登場する以前ならまだしも、現在のブラウザではtarget="_blank"を指定した場合はnoopenernoreferrerのいずれかを指定すべきです。特に外部サイトのページをtarget="_blank"で開く場合はrel属性を付与することは必須であるといっても差し支えないと思います。

同一サイト内であっても、モードレスダイアログのようなユーザー体験を実現したければ、別タブで操作させるのではなく、同一タブ内にモードレスダイアログをHTML/CSS/JSを使って実現すれば済むので、そういった意味でもwindow.openerを使うことはもうないのではないかと思います。

認証が必要なページから外部ページを開くときはnoreferrerを指定する

認証されたユーザーのみが表示できるページで外部ページを開くときはそのページのURLを知られないようにするという意味でもnoreferrerを指定することが強く推奨されます。

もう少し簡単に言ってしまえば、リファラーを送りたいケース以外はnoreferrerを指定するのがよいと思います。noreferrerの方がサポートされているブラウザの範囲が広いため、セキュリティ対策を考えるとnoreferrerを使う方が安全なためです。

リファラーを送信する必要がある場合のみnoopenerを指定する

ブログやアフィリエイトサイトなど、target="_blank"で表示したサイトに元ページのURLを伝えたい、流入元がどこかを伝えたいというケースにおいてはnoopenerを指定するのがよいでしょう。

WordPressがnoreferrerを自動付与せずnoopenerを自動付与しているのはこれが理由だと考えられます。アフィリエイトの種類にもよりますが、リファラーがないとアフィリエイト報酬に計算されない場合もnoreferrerではなくnoopenerを使う必要があるので、アフィリエイトサイトの仕様を事前に確認しておくことが重要です。

rel属性が設定されていることをチェックしよう

基本的にはESLintなどの静的解析ツールでチェックするのが望ましいですが、アプリケーション開発ではURL部分が変数になることがあり、この場合は静的解析ツールではチェックしきれないという問題があります。

そのため、静的解析だけを頼りにするのではなく、他の手段も組み合わせて多層的にチェックするのがよいでしょう。

静的解析ツールでチェックする

チェック漏れを防ぐという点ではESLintなどの静的解析ツールを導入し、エディタの拡張機能でチェックしたり、CIでチェックすることは非常に重要です。しかし、すべてのケースをチェックしきれなかったり、必要ない場合でもエラーになるなどの弊害もあるため、導入できるかどうかはチームで慎重に検討することが望ましいです。

ESLintでチェックする場合、

npm install --save-dev eslint @html-eslint/parser @html-eslint/eslint-plugin

でHTMLファイルをチェックするためのプラグインも導入します。

設定ファイルでは、

import html from "@html-eslint/eslint-plugin";
import htmlParser from "@html-eslint/parser";
...

export default defineConfig([
  ...
  {
    files: ["**/*.html"],
    plugins: {
      "@html-eslint": html,
    },
    languageOptions: { parser: htmlParser },
    rules: {
      "@html-eslint/no-target-blank": "error",
    },
  },
]);

HTMLファイルを処理するルールを追加することで、HTMLファイルに対してLintingできるようになります。

aタグにtarget="_blank"があり、href属性が相対パスでない場合に、rel="noreferrer"がないと

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <a target="_blank" href="http://example.com/">Home</a>
  </body>
</html>

以下のようにエラーが出るようになります。

> test1@1.0.0 lint
> eslint *.html


/Users/user/test/index.html
  9:8  error  Missing `rel="noreferrer"` attribute in a tag  @html-eslint/no-target-blank

相対パスの場合はチェックが行われない点に注意が必要です。(あくまでも外部サイトを表示するためのセキュリティ対策にフォーカスされている)

また、先ほど参照したESLintのIssueでも触れられていますが、noopenerの有無はチェックしないようになっているので、rel="noreferrer"rel="noopener noreferrer"(順不同)のいずれかの場合にパスするようになっているため、noopenerがあることをチェックできない点にも注意してください。

CopilotなどのAIエージェントにチェックしてもらう

Copilotなどソースコードを参照できるAIエージェントにチェックしてもらうというのも手です。ワークスペース全体をチェックできる場合は網羅的にチェックしてもらえるので、非常に効率的です。

レビューの観点に加える

修正箇所に限定するのであれば、プルリクなどのレビューの観点としてリンク使用時にrel属性を付与しているかをチェックするのもよいでしょう。ただし、チェック漏れのリスクもあるため、前述のようなツールでのチェックを併用したり、チェックリストでのチェックを行うなどの対策を併用することも検討すべきです。

まとめ

noopenernoreferrerを指定することでどういった効果があるのか、これらのrel属性に対して過去にどのような経緯があったのかについて確認しました。

また、現在においてはどのように指定すればいいのか、どうやってrel属性の付与漏れを防ぐのがよいかについてもまとめました。

動作確認という点では、rel属性の有無にかかわらず問題なく動いてしまうので、発見しにくい問題ではありますが、セキュリティに関する重要な対策の1つであるため、ツールなども活用しながら付与漏れがないようにしていくことが重要です。

昨今ではCopilotなどでワークスペース全体をチェックすることも可能になってきているので、今一度点検をしてみてもよいかもしれません。

まずはこれだけ!GitHub Copilotの使い方

GitHub Copilot を最大限活かせるように基本的な使い方を学びましょう。

本記事では、 Visual Studio Code での操作を中心に説明していますが、ショートカットについてはIntelliJ IDEA や PyCharm などのJetGBrains 系のIDEについても掲載しています。

回答する言語を指定する

英語で回答してほしいときは特に設定変更する必要はありませんが、日本語で回答してほしいときに、毎回「日本語で回答してください」などと書くのは面倒です。GitHub Copilot では、回答する言語を指定することが可能です。

Visual Studio Code の場合は Settings > Extensions > GitHub Copilot で、Github > Copilot > Chat: Locale Overridesの設定を変更することで、指定した言語で回答を求めることができます。

デフォルトはautoになっていると思いますので、日本語で回答してほしければja に変更してください。

IntelliJ IDEA や PyCharm などでは、 Settings > Languages & Frameworks > GitHub Copilot で、Chat欄のNatural Languageを日本語に変更することで、日本語で回答を求めることができます。

3つのツールを状況に応じて使い分ける

ここでは、以下の3つのツールの使い分けについて説明します。

  1. インラインチャット
  2. チャットパネル
  3. ChatGPT などの対話型生成AIサービス

インラインチャット

チャットパネルを起動してもよいのですが、インラインチャットを使うことでより素早くコードを生成したり、改善したりできます。

Visual Studio Code で、インラインチャットを起動するには、Cmd+IWin+I)のショートカットキーを使用します。

IntelliJ IDEA や PyCharm では、Ctrl+Shift+ICtrl+Shift+G)で同様の操作ができます。

チャットパネル

チャットパネルを使用すると、ワークスペースに関する質問ができるため、説明を求めたい場合にはこちらを使用します。後述のChatGPTなどの対話型生成AIサービスでもソースコードを添付すれば似たようなことができますが、手間なくできる点ではこちらを使用するのがよいでしょう。

チャットパネルは、Cmd+Shift+ICtrl+Shift+I)で開閉できます。会話後、コードに復帰したいときはチャットパネルを閉じることですぐにコーディングに戻れます。

IntelliJ IDEA や PyCharm では、Ctrl+Shift+C(Windowsも同様)で、チャットパネルの開閉ができます。

ChatGPTなどの対話型生成AIサービス

一方、ワークスペースに依らない問題の解決方法を質問したいとかであれば GitHub Copilot Chat ではなく、 ChatGPT などを使う方が効率的です。これは GitHub Copilot Chat ではコーディングに関する内容にのみ答えてくれるという点が影響しており、会話の途中で答えてくれなくなることはストレスになるので、使い分けをした方がよいのではないかと思います。

現時点ではアプリ版かWeb版を使うことになるかと思います。ChatGPT 以外にもツールはたくさんありますので、使いやすいものを選択してください。

コードを生成する

インラインチャットを含めたコード生成のパターンを考えます。

適切な名称をつけてコードを生成してもらう

もっとも基本的な生成の仕方になります。関数を生成する場合、適切な関数名をつけることでその関数名に沿ったコードを生成してくれます。

たとえば、JavaScriptで2つの数を加算する関数を作成する場合、addTwoNumbersという名前をつけることで2つの引数と加算をするコードが生成されます。

function addTwoNumbers と入力すると、候補が表示されます。TABキーでこれを確定すると関数が完成します。

コメントをつけて生成してもらう

実現したいことをコメントで書いて、その内容にあったコードを生成させます。

コメントを書いてから改行すると、そのコメントにあったコードが生成されます。

生成された内容が問題なければ、TABキーで確定させます。

候補が表示されているとき、マウスカーソルをカーソルをホバーすると、生成するコードの他の候補に切り替えられます。

これを表示しなくても、Option+[Alt+[)とOption+]Alt+])で前の候補と次の候補を行き来でき、生成したい候補でTABキーで確定できます。最初に生成されたコードが期待したコードでなくても別の候補が期待したコードである可能性があるので、切り替えて確認するとよいでしょう。

コードを書きながらコードを生成してもらう

これがもっともよく使われている方法かもしれません。コードを書きながらその次のコードを生成してもらう方法です。

同じようなコードを生成する場合や常套句のようなコードを生成する場合には高い精度のコードを生成してくれますが、意図が正しく伝わっていないと期待したコードを生成してくれないので、後述のインラインチャットでコード生成を指示するのがよいと思います。

インラインチャットでコード生成を指示する

適切な関数名が思いつかなくてもコメントを書かなくてもインラインチャットを使うことでコードの生成を指示できます。

ENTERRETURN)キーで生成してくれます。

Visual Studio Code では、再生成したければCmd+RWin+R)、受け入れるならCmd+ENTERWin+RETURN)を押下します。IntelliJ IDEA や PyCharm ではショートカットは用意されていないようで、マウス操作で再生成し、

受け入れるなら、同様にマウス操作で

エディタに反映します。

インラインチャットでコードを書き換えてもらう

書き換えてほしいコードを選択し、インラインチャットで書き換えてほしい内容を入力することでコードの改善ができます。とりあえず書いたコードにバグがあったり、非効率なコードだったりするときに改善してもらうことができるので便利です。

修正してほしいコードを範囲選択し、インラインチャットを起動、修正後どうなってほしいかを伝えます。

候補が表示されるので、

問題なければCmd+ENTERWin+RETURN)で確定します。

文章による説明を求める必要がなく、さっさと修正したい場合はチャットパネルではなくインラインチャットを使う方が効率よくコーディングを進められます。

何をするかを指定する

文章で書かなくてもコマンドを使ってやってほしいことを指定することができます。

/generate

実際には文章で書いても手間ではなく、先にコメントを書いておけば生成してくれるので、使う機会はほぼないかもしれませんが、Visual Studio Code ではコード生成をするコマンドがあります。

/generateを使って作成してほしいコードの仕様を伝えると、

以下のようにコードを生成してくれます。

IntelliJ IDEA や PyCharm ではこのコマンドはないようですので、ご注意ください。

/fix

修正についても文章で書いてもそれほど手間ではないので使う機会は多くないですが、/fixコマンドを使うことで修正を指示することができます。

/fixコマンドに続いて修正してほしいことを記述することで、

修正結果を表示してくれます。

このコマンドは IntelliJ IDEA や PyCharm でも使用可能です。

/explain

コードやワークスペースが何を行っているのかを説明・要約してもらうことで、コードを一から読むよりも理解が早くなります。たとえば、業務で自分が関わったことのない古いコードがある場合、そのコードについて説明をしてもらってからコードを読んだ方が理解しやすいと思います。

説明はインラインチャットではなくチャットパネルで聞いた方がわかりやすいです。

チャットパネルを開くと、現在エディタで表示しているファイルが選択済みなので、このまま/explainコマンドを指定します。

説明の中で不明な点や深掘りしたい点があれば、チャットで追加質問してください。

このコマンドは IntelliJ IDEA や PyCharm でも使用可能です。

/doc

これまではクラスやメソッドのコメントを書くこともメンテナンスすることも非常にコストの高い作業だったと思います。生成AIの登場でこのような問題は過去のものとなりつつあります。

関数の先頭で以下のように/docコマンドを使用すると、

以下のようにドキュメントテーションコメントを生成してくれます。

コメントが古くて最新化したい場合でも/docコマンドが使用できます。以下のようにドキュメンテーションコメントが適切にメンテナンスされていない場合でも、コメントと関数を範囲指定して/docコマンドを使うと、

以下のようにコメントを生成し直してくれます。

このコマンドは IntelliJ IDEA や PyCharm でも使用可能です。

/tests

主にGitHub Copilot Chatで使用しますが、テスト対象を選択してテストコードを生成することができます。ただし、注意したいのは、テストの準備にプロジェクト固有の特殊が必要な場合にはうまく生成されないことがあります。

基本的には、最初の1つはコード補完を使いながら自身で作成し、その派生形で記述できる他のバリエーションを指示しながら作成するのがよいでしょう。テストで使用している値についても細かく指示するよりは一旦生成させて自身で修正した方が早い場合があります。

その他のコマンド

上記以外にもいくつかのコマンドがあります。

Visual Studio Code では、コード編集を行うための /edit コマンドが用意されています。

IntelliJ IDEA や PyCharm ではコードをシンプルにするための/simplyfy コマンドが用意されていますが、冗長なコードという点であれば、IDE自体の機能で修正できる場合もありますので、それほど使用頻度は高くないと思います。

何を参照するかを指定する

何を参照するのかを明示的に指定することで、精度の高い回答を得ることができます。これらはVisual Studio Code のみで使用可能ですが、ファイルだけはIntelliJ IDEA や PyCharm でもマウス操作で追加することができます。

@workspace

ワークスペース内のソースコードをすべて参照し、関連性の高いファイルをピックアップしてコードや回答を生成します。説明上、この記事中ではワークスペースという表現に統一していますが、ワークスペースでもプロジェクトでも伝わりますので、特に気にする必要はありません。

@vscode

Visual Studio Code 限定の機能になりますが、Visual Studio Codeの機能に着目した回答をしてくれます。設定やショートカットキーに関する質問をしたい場合は、@vscodeをつけるようにしてください。会話の中で設定に遷移するボタンも出力してくれるので、こちらも活用してみてください。

Show in Settings Editorをクリックすると、

設定が表示されます。

@terminal

コードの話ではなく、コマンドに関する質問をしたい場合は、ターミナルに着目した回答をしてくれる@terminalを使うのがよいでしょう。

#file

参照してほしいファイルを指定します。基本的にはアイコンをクリックしてファイルを選ぶのがよいでしょう。基本的に単独で使用可能ですが、もし効かないようであれば@workspaceと併用してください。

#editor

エディタの表示領域を含めるには#editorを使用します。ただし、現在エディタで表示しているファイルはデフォルトで参照していることがほとんどなので、あまり使う機会はないかもしれません。

#selection

エディタの選択箇所を参照します。IntelliJ IDEA や

#terminalLastCommand

ターミナルで最後に実行したコマンドとその実行結果を参照します。非常に便利な機能ですが、

#terminalSelection

ターミナルの選択箇所を参照します。コマンドを実行していてエラーが出たときに対処方法を聞くときは#terminalLastCommandで構いませんが、もう少しピンポイントで聞きたいときは#terminalSelectionを使うとよいでしょう。

目的別プロンプト集

いくつか、よく使いそうなプロンプト例をまとめてみました。これらはGitHub Copilot Chatで使用します。

ワークスペース全体を説明してもらう

/explainコマンドと@workspaceを組み合わせることで、ワークスペース全体について説明してもらうことができます。

@workspace /explain

新しく参画したメンバーが担当するワークスペースの構造を把握する際にとても有用だと思います。オンボーディング中やオンボーディング後の自習時間に使ってみてはいかがでしょうか。

ワークスペースのディレクトリ構造を明らかにする

ワークスペースのディレクトリ構造に可視化したいときは、以下のように聞くとよいです。

@workspace /explain ワークスペースのディレクトリ構造を教えて

こちらも、どこにどんなファイルがあるのかをディレクトリ構造を把握したい場合に有効な方法です。

コードレビューをしてもらう

作成したコードに対してコードレビューを行ってもらうのも有効な使い方のひとつです。

コードレビューを行う場合は、包括的なレビューをするのか、特定の何かについてレビューをするのかを明確にすることが重要です。

包括的なレビューを行ってほしい場合

たとえば、改善すべて点はありますかと質問するとよりよくするためのアドバイスを回答してもらうことができます。この方法は、最初のレビューや最終的なレビューとして使うとよいでしょう。

特定の観点に基づいてレビューを行ってほしい場合

特定の観点についてレビューをしてもらうことで、改善すべき点をより明確にすることができます。

具体的には、コード品質(命名規則、冗長なコード、可読性)、セキュリティ、パフォーマンスなどの問題を指摘してもらうのがよいと思います。

  • 命名は適切ですか
  • 冗長なコードや簡潔に書けるコードはありますか
  • エラーハンドリングは適切ですか
  • 実装漏れやデバッグコードなどは残っていませんか
  • 脆弱性はありますか
  • パフォーマンスの問題はありますか
  • 不足しているテスト観点はありますか

これ以外にも、プロジェクト固有の観点(特定の機能が実装されているか、など)を確認するのもよいでしょう。

また、レビューア側でも目視によるレビューと併用するのもよいと思います。

まとめ

当然といえば当然ですが、 GitHub Copilotの機能はVisual Studio Codeがもっとも充実しています。ただ、EclipseやIntellJ IDEA など他のIDEでもまったく使えないわけではないため、もし使っているのであれば積極的に活用していくことが重要です。

GitHub Copilotを活用にするには、基本的なショートカットやコマンドなどを理解することももちろんですが、やってほしいことを明確に指示することが大切です。これはインラインチャットで指示するだけでなく、コメントを書いてからコードを書き始めるということも含みます。

Copilot や AI Agent 関連はかなり活発に進化しています。この記事で紹介した機能以外もありますし、今後もっとよいやり方が出てくることも容易に想像できます。コーディングの生産性を高めるため、定期的にキャッチアップが必要だと思います。

macOSでもクリップボード履歴を使用できるようにする(Clipy)

WindowsではWin+Vでクリップボード履歴が使用できます。macOSでもこれと同じような機能が使えるClipyというアプリがあります。

インストール

公式サイトにダウンロードボタンがありますので、そこからdmgファイルをダウンロードし、インストールしてください。インストールして起動すると、アクセシビリティなどの設定を求められますので、設定を行ってください。

インストールが終わるとメニューバーにClipyのアイコンが表示されるので、これでインストールは完了です。

環境設定

メニューバーのClipyアイコンをクリックして表示されるメニューから環境設定を選択すると、環境設定ダイアログが表示されます。そのままでもよいですが使いやすいようにカスタマイズするとよいでしょう。

私の設定

私は連続してコピーしたのちに、それを連続で貼り付けたいだけなので、以下のようにカスタマイズしました。

記録する履歴の数を10に制限し、履歴のソート順を作成日にしました。よく貼り付けるクリップボードはClipyが提供するスニペットを使えばいいと思ったのと、貼り付ける度に順番が変わるとどこまで貼り付けたかわからなくなるので作成日を指定しています。

一般で履歴の数を10にして、インライン表示する項目の数を10にしたことで、すべてインラインで表示し、選択の手間をひとつ減らしました。一度にコピーする数と想定される件数にしておくとよいでしょう。

使い方

コピーはいつもどおりで、貼り付けにCmd+Vの代わりにCmd+Shift+Vを使用します。ショートカットを使うと、

コンテキストメニューが表示されるので、十字キーで貼り付けたいクリップボードを選択し、RETURNキーを押下します。

ショートカットキーは変更できますので、ご使用のキーボードのキー配置に合わせてカスタマイズすることも検討してください。

IntelliJ IDEAで次の出現箇所を選択する

Visual Studio Codeでの❖+D/⌘+Dのような現在選択しているテキストと同じテキストが出現する次の箇所を選択するショートカットは、IntelliJ IDEAにも存在します。

ただ、WindowsとmacOSでショートカットが異なるので両方を使用している方は注意が必要です。

Windowsの場合

WindowsのIntelliJ IDEAでは、Alt+Jで現在選択しているテキストと同じテキストが次に出現する箇所を選択することができます。

macOSの場合

macOSのIntelliJ IDEAでは、^+Gで現在選択しているテキストと同じテキストが次に出現する箇所を選択することができます。

Linuxの場合

最近では開発用マシンとして使用している人もいるので、ちょっと調べてみました。Ubuntu 24.04 ARM64で動作確認を行っていますが、他のディストロやCPUでも変わらないかと思います。

結論からいうと、Windowsと同じAlt+Jで同様の操作ができました。macOSだけが異なるショートカットになっているため、こちらについても意識しておいた方がよいでしょう。

まとめ

Visual Studio Codeとは異なり、IntelliJ IDEAをはじめとするJetBrainsの製品はWindowおよびLinuxとmacOSでショートカットが異なります。これはCtrlキーとcommandキーの違いというような差異ではなく、使用するアルファベット自体が異なっている(まったくの別ショートカットとなっている)点に注意が必要です。

特に、私のようにプライベートと仕事で使用OSが異なる人は混乱しやすいと思いますので、OSを揃えるようにするなど何かしらの対策をしておいた方がよいかもしれません。

Amazon API Gateway REST APIにIP制限をかける

API Gateway REST APIに対してIP制限をかける必要があったので手順を確認しました。

動作確認用のAPI Gateway REST APIを作成する

まずはAPI GatewayでAPIを作成します。以下の手順に従って作成していきます。

手順

API Gatewayコンソールhttps://console.aws.amazon.com/apigatewayにアクセスします。

選択肢の中から、REST APIの構築ボタンをクリックします。

API Gatewayを作成することは今回の主眼とは関係ないため、サンプルAPIを選択して作成します。

REST APIPetStoreが作成されました。

これは必須ではありませんが、デプロイする前にテストをして動作確認をしておきます。/ > /pets > POSTをクリックして、「テスト」を選択します。

手順に従って、{"type": "dog","price": 249.99}というテキストをリクエスト本部に貼り付け、テストボタンをクリックします。

ステータスが200になっていればテスト成功です。

動作確認ができたらAPIをデプロイボタンをクリックしてデプロイします。

今回はテスト用なので手順と同じくtestというステージを作成します。

デプロイはすぐに完了します。

動作確認のためにURLを呼び出すボタンをクリックしてのURLをコピーし、実際に使用可能なことを確認します。

自端末のターミナルからcurlコマンドで実行してみます。

$ curl https://dy1o7l2qa9.execute-api.us-east-1.amazonaws.com/test
<html>
    <head>
        <style>
        body {
            color: #333;
            font-family: Sans-serif;
            max-width: 800px;
            margin: auto;
        }
        </style>
    </head>
    <body>
        <h1>Welcome to your Pet Store API</h1>
        <p>
            You have successfully deployed your first API. You are seeing this HTML page because the <code>GET</code> method to the root resource of your API returns this content as a Mock integration.
        </p>
        <p>
            The Pet Store API contains the <code>/pets</code> and <code>/pets/{petId}</code> resources. By making a <a href="/test/pets/" target="_blank"><code>GET</code> request</a> to <code>/pets</code> you can retrieve a list of Pets in your API. If you are looking for a specific pet, for example the pet with ID 1, you can make a <a href="/test/pets/1" target="_blank"><code>GET</code> request</a> to <code>/pets/1</code>.
        </p>
        <p>
            You can use a REST client such as <a href="https://www.getpostman.com/" target="_blank">Postman</a> to test the <code>POST</code> methods in your API to create a new pet. Use the sample body below to send the <code>POST</code> request:
        </p>
        <pre>
{
    "type" : "cat",
    "price" : 123.11
}
        </pre>
    </body>
</html>%

大丈夫そうですね。

リソースポリシーで特定のIPのみがアクセスできるように制限する

次にリソースポリシーで特定のIP(今回は自端末のIP)のみアクセスできるように制限をかけてみます。

手順は以下の「特定の IP アドレスのみが API Gateway REST API にアクセスすることを許可するリソースポリシーを作成およびアタッチする」に従って行っていきます。

手順

API Gatewayコンソールhttps://console.aws.amazon.com/apigatewayにアクセスします。

リソースから先ほど作成したPetStoreAPIを選択します。

左のナビゲーションペインでリソースポリシーを選択すると、以下のような画面が表示されます。

デプロイ直後はリソースポリシーは設定されていないため、ポリシーを作成ボタンをクリックし、ポシリーの詳細下のドロップダウンリストからIP範囲拒否リストを選択すると、以下のようなポリシーが表示されます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "execute-api:/{{stageNameOrWildcard}}/{{httpVerbOrWildcard}}/{{resourcePathOrWildcard}}",
            "Condition" : {
                "IpAddress": {
                    "aws:SourceIp": [ "{{sourceIpOrCIDRBlock}}", "{{sourceIpOrCIDRBlock}}" ]
                }
            }
        },
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "execute-api:/{{stageNameOrWildcard}}/{{httpVerbOrWildcard}}/{{resourcePathOrWildcard}}"
        }
    ]
}

色々試してみたのですが、許可のみ記載したポリシーだと指定したIPまたはCIDRブロックのみを許可できるようです。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "execute-api:/*",
            "Condition" : {
                "IpAddress": {
                    "aws:SourceIp": [ "{{sourceIpOrCIDRBlock}}" ]
                }
            }

        }
    ]
}

このポリシー中の{{sourceIpOrCIDRBlock}}を自身のグローバルIPに置き換えてください。

ポリシーが作成できたら、右下の変更を保存ボタンをクリックします。リソースポリシーを変更したら、それを反映させるために左のナビゲーションペインでリソースを選択し、APIをデプロイボタンをクリックしします。

先ほど作成したステージを選択してデプロイします。

デプロイが完了したことを確認します。

動作確認

設定が完了したので、動作確認をします。まずは自端末から変わらずアクセスできることを確認します。

$ curl https://dy1o7l2qa9.execute-api.us-east-1.amazonaws.com/test
<html>
    <head>
        <style>
        body {
            color: #333;
            font-family: Sans-serif;
            max-width: 800px;
            margin: auto;
        }
        </style>
    </head>
    <body>
        <h1>Welcome to your Pet Store API</h1>
        <p>
            You have successfully deployed your first API. You are seeing this HTML page because the <code>GET</code> method to the root resource of your API returns this content as a Mock integration.
        </p>
        <p>
            The Pet Store API contains the <code>/pets</code> and <code>/pets/{petId}</code> resources. By making a <a href="/test/pets/" target="_blank"><code>GET</code> request</a> to <code>/pets</code> you can retrieve a list of Pets in your API. If you are looking for a specific pet, for example the pet with ID 1, you can make a <a href="/test/pets/1" target="_blank"><code>GET</code> request</a> to <code>/pets/1</code>.
        </p>
        <p>
            You can use a REST client such as <a href="https://www.getpostman.com/" target="_blank">Postman</a> to test the <code>POST</code> methods in your API to create a new pet. Use the sample body below to send the <code>POST</code> request:
        </p>
        <pre>
{
    "type" : "cat",
    "price" : 123.11
}
        </pre>
    </body>
</html>%

問題なくアクセスできています。

次に異なるグローバルIPを持つ端末からアクセスしてみてください。例えば、PCからアクセスしている場合はスマートフォンのWiFiをOFFにして、ブラウザで同じアドレスにアクセスしてみてください。

{"Message":"User: anonymous is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:us-east-1:********0149:dy1o7l2qa9/test/GET/"}

IP制限が効いていると、上記のようなメッセージが返ってきます。

まとめ

IP制限や経路制限を変える方法はいくつかあります。

  • HTTP APIで作成し、VPCリンクで制限する
  • REST APIプライベートで作成し、リソースポリシーで許可するVPCを制限

今回はAPI Gatewayを作成し直す訳にはいかない事情があったので、このような対応にしました。

モバイルバージョンを終了