<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>さくらインターネット研究所</title>
        <link>https://research.sakura.ad.jp</link>
        <description>さくらインターネット研究所のウェブサイトです。</description>
        <lastBuildDate>Tue, 09 Jun 2026 01:43:42 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>Feed</generator>
        <copyright>2026 さくらインターネット研究所</copyright>
        <item>
            <title><![CDATA[MLSys 2026でAI/HPCクラスタ「さくらONE」の設計・性能評価・運用データ分析を発表]]></title>
            <link>https://research.sakura.ad.jp/blog/mlsys2026-report</link>
            <guid isPermaLink="false">https://research.sakura.ad.jp/blog/mlsys2026-report</guid>
            <pubDate>Thu, 04 Jun 2026 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<link rel="preload" as="image" href="/images/block-37397d4e-f442-8029-81c6-c620eab5b1ad-c605ffea45c70146754462e42473f566e143bdf6.webp"/><link rel="preload" as="image" href="/images/block-37397d4e-f442-804f-a997-cc7716339fd1-4cafc1304b1563e15ca6d15db95bb0099dd62483.webp"/><link rel="preload" as="image" href="/images/block-37397d4e-f442-8043-a6be-d17b3a29c499-4ffa2289c006c7a519993b499abee4ffb39f8b8c.webp"/><link rel="preload" as="image" href="/images/block-37397d4e-f442-806e-9080-f19d1cd0180c-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp"/><link rel="preload" as="image" href="/images/block-37397d4e-f442-8027-b32f-c80da5916734-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp"/><link rel="preload" as="image" href="/images/block-37397d4e-f442-80de-ad0f-f30c086c824a-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp"/><link rel="preload" as="image" href="/images/block-37397d4e-f442-8098-83ce-d85d9a6bd699-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp"/><link rel="preload" as="image" href="/images/block-37497d4e-f442-804a-b372-c522de603c55-3096042602144931b3cf430ce4fd32def4807483.webp"/><link rel="preload" as="image" href="/images/block-37397d4e-f442-8058-a7a2-cb6064c82bf1-eb89320561a29726820d7b2ec1098c6360246aac.webp"/><link rel="preload" as="image" href="/images/block-37397d4e-f442-80ca-828f-e9904d39d42f-337e72f6cd98a9fe5409f8acbc8e56bf84e39e1c.webp"/><div class="rotion-blocks"><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">さくらインターネット研究所の鶴田（</span><a class="rotion-richtext-link" href="https://twitter.com/tsurubee3" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">@tsurubee3</span></a><span class="rotion-richtext-annot rotion-richtext-default">）です。2026年5月、米国ワシントン州ベルビューにて、機械学習とシステムの交差領域における国際会議「Machine Learning and Systems（MLSys）2026」が開催されました。同会議のIndustry Trackに、当研究所が開発・運用する、AIモデル開発向けのHPC（High Performance Computing）クラスタ「さくらONE」に関する論文が採択され、共著者3名で現地に赴いて発表しました。本記事では、MLSys 2026のIndustry Trackの概要、採択論文の概要、現地でのオーラル発表・ポスター発表の様子について報告します。</span></p></div><div><h2 class="rotion-text rotion-text-h1" id="e7a07e9f"><span class="rotion-richtext-annot rotion-richtext-default">MLSys 2026 Industry Trackについて</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">MLSysは、機械学習とシステムという2つの研究コミュニティが知見を共有し、新たな接点を生み出すことを目的に設立された国際会議です。2018年に「SysML」として第1回が開催されて以来、現在の名称に改称後も毎年開催されており、機械学習の効率化・大規模化を支えるシステム技術から実応用に向けた取り組みまで幅広いテーマが扱われています。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">Opening Remarksで発表された数字によると、近年はMLSysへの投稿数が大きく伸びています。MLSys 2025の271件から、MLSys 2026では504件と前年比86%増加しており、機械学習システム分野への関心の高まりがうかがえます。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-37397d4e-f442-8029-81c6-c620eab5b1ad-c605ffea45c70146754462e42473f566e143bdf6.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">MLSys 2026では、従来のResearch Trackに加えてIndustry Trackが新設され、注目を集めました。Industry Trackには初年度ながら87本の投稿が集まりました。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-37397d4e-f442-804f-a997-cc7716339fd1-4cafc1304b1563e15ca6d15db95bb0099dd62483.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">Research Trackと比較したIndustry Trackの主な特徴は2点あります。1点目は、評価のフォーカスが「本番運用システムの設計・評価から得られた知見・教訓」に置かれていることです。研究の新規性そのものよりも、実世界での影響、技術的品質、システム構築から得られた経験が重視されます。2点目は、Research Trackのように完全な匿名化は求められないことです。投稿時には、著者名は匿名化しますが、製品名等の識別情報を本文に含めることが認められています。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">MLSys 2026全体では504本の投稿のうち135本の論文が採択され、内訳はResearch Track 107本、Industry Track 28本となっています。全体の採択率は26%、Research Track単体では25%、Industry Track単体では32%でした。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-37397d4e-f442-8043-a6be-d17b3a29c499-4ffa2289c006c7a519993b499abee4ffb39f8b8c.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><h2 class="rotion-text rotion-text-h1" id="3c60c826"><span class="rotion-richtext-annot rotion-richtext-default">採択論文の概要</span></h2></div><div><ul class="rotion-listblocks rotion-list-ul"><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">タイトル</span><span class="rotion-richtext-annot rotion-richtext-default">: SAKURAONE: An Open Ethernet-Based AI HPC System and Its Observed Workload Dynamics in a Single-Tenant LLM Development Environment</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">著者</span><span class="rotion-richtext-annot rotion-richtext-default">: 小西史一、坪内佑樹、鶴田博文（さくらインターネット株式会社）</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">論文</span><span class="rotion-richtext-annot rotion-richtext-default">: </span><a class="rotion-richtext-link" href="https://arxiv.org/abs/2604.13600" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">https://arxiv.org/abs/2604.13600</span></a></li></ul></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">採択された論文は、「さくらONE」の設計と、TOP-500およびMLPerfに基づく性能評価、その上での大規模言語モデル（LLM）開発における実運用知見を報告したものです。さくらONEは、NVIDIA H100 GPUを800基（100ノード×8基）搭載したAI/HPCクラスタです。高帯域・低レイテンシが求められるAI向けAI/HPCクラスタでは、従来、特定ベンダーに依存した専用の相互接続ネットワーク（InfiniBandなど）が主流でした。これに対しさくらONEは、800ギガビットイーサネット（800 GbE）とネットワークOSのSONiC（Software for Open Networking in the Cloud）を組み合わせたオープンEthernetネットワークを基盤として採用している点が特徴です。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">本論文では、以下の2点を中心に報告しています。</span></p></div><div><ol class="rotion-listblocks rotion-list-ol"><li class="rotion-numbered-list"><span class="rotion-richtext-annot rotion-richtext-default">ベンダーに依存しないオープンEthernetネットワークを基盤とするAI向けHPCシステムのアーキテクチャ設計・実装と性能評価</span></li><li class="rotion-numbered-list"><span class="rotion-richtext-annot rotion-richtext-default">単一プロジェクト・単一テナント環境におけるLLM開発の実運用データに基づくワークロード特性の観測と分析</span></li></ol></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">これらの取り組みは、オープンでコスト効率の高いAI/HPCクラスタの実現可能性を実証するとともに、実運用に基づくワークロード分析を通じて、次世代AIインフラの設計指針として産業界・学術界の双方に有用な知見を提供するものです。具体的な性能評価の結果やワークロード分析の知見については、後述のオーラル発表・ポスター発表のセクションで紹介します。</span></p></div><div><h2 class="rotion-text rotion-text-h1" id="f49b0291"><span class="rotion-richtext-annot rotion-richtext-default">オーラル発表</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">オーラル発表は坪内（</span><a class="rotion-richtext-link" href="https://x.com/yuuk1t" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">@yuukit</span></a><span class="rotion-richtext-annot rotion-richtext-default">）が担当しました。発表スライドは以下で公開しています。</span></p></div><div><div class="rotion-embed"><div class="rotion-embed-speakerdeck"><div class="rotion-embed-html"><iframe id="talk_frame_1546833" class="speakerdeck-iframe" src="https://speakerdeck.com/player/b80526ab8bdb4bbda6443fab1503764c" width="710" height="399" style="aspect-ratio:710/399; border:0; padding:0; margin:0; background:transparent;" frameborder="0" allowtransparency="true" allowfullscreen="allowfullscreen"></iframe> </div><div class="rotion-embed-caption"></div></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">発表の前半では、さくらONEのシステム設計を中心に説明しました。LLM開発においてピークFLOPSだけでなく、長期間にわたって継続的に利用できる計算資源、GPU間通信のための予測可能なネットワーク経路、そしてベンダーに依存しすぎないオープンな運用性を我々は重視しています。そこで、さくらONEでは100ノード・800基のNVIDIA H100 GPU、SONiC/RoCEv2 EthernetによるGPU間相互接続、GPU通信とストレージI/Oの分離、GPU-NIC affinityとrail-optimized topologyを組み合わせた設計を採用していることを説明しました。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-37397d4e-f442-806e-9080-f19d1cd0180c-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">続いて、HPL、HPL-MxP、HPCG、IO500、MLPerf-style benchmarkの結果を示し、オープンEthernetを基盤とする構成でも、HPC・AI学習・ストレージを横断して競争力のある性能を示せることを説明しました。さくらONEがスーパーコンピュータの国際ランキングTOP-500 HPLベンチマークにて、49位を獲得したことは、当社の</span><a class="rotion-richtext-link" href="https://www.sakura.ad.jp/corporate/information/newsreleases/2025/06/11/1968219771" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">ニュースリリース</span></a><span class="rotion-richtext-annot rotion-richtext-default">でも公開しています。 </span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">GPT-3 175Bを対象としたMLPerf-style benchmarkでは、32、64、96ノードでの実行結果を示し、公開されているNVIDIA Eosの参照値と比較して、同規模のノード数でおおむね9〜17%程度の差に収まることを紹介しました。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-37397d4e-f442-8027-b32f-c80da5916734-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">さらに、MLPerf GPT-3 175Bベンチマークテスト実行時のPytorch Profilerによるプロファイリング結果についても説明しました。この実行では、pipeline parallelismを16、virtual pipeline parallelismを6に設定しており、多数のpipeline microbatchが発生します。PyTorch profilerで確認したところ、NCCL時間の大部分はpipeline stage間のSendRecv操作で占められており、32ノードおよび64ノードの実行ではSendRecvがNCCL時間の約90%を占めていました。また、32ノードから64ノードへ拡大すると、通信時間の比率は16.4%から19.3%へ増加し、通信と計算のoverlapは72.3%から67.2%へ低下しました。64ノード実行は2つのpodにまたがる配置となるため、cross-pod placementも性能差に影響した可能性があります。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-37397d4e-f442-80de-ad0f-f30c086c824a-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">発表の後半では、単一LLM開発プロジェクトの運用トレースから得られた知見を紹介しました。特に強調したのは、ジョブ件数とGPU占有時間がまったく異なる傾向を示す点です。1ノードジョブはジョブ件数の76.9%を占める一方で、GPU占有時間では1.8%にとどまります。逆に、17ノード以上の大規模ジョブはジョブ件数では3.3%にすぎませんが、GPU占有時間では73.3%を占めていました。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-37397d4e-f442-8098-83ce-d85d9a6bd699-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">また、CANCELLED状態で終了したジョブがGPU占有時間の73.5%を占めるという結果についても紹介しました。これは単なる失敗や無駄な計算時間ではなく、ユーザーが学習曲線や検証結果を見ながら学習ジョブを途中で止める、LLM開発に特有のfeedback-drivenな運用の一部として解釈できるものです。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">オーラル発表は12分という限られた時間での発表だったため、詳細なジョブ分類、GPU利用率、障害分析、RoCEv2のチューニングなどは論文本文で補足する構成としました。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">発表後のQ&Aでは、さくらONEにおける他のLLM Trainingベンチマーク結果があるかどうかの確認や、ジョブのキャンセル数が多い傾向への興味をもらってもらったことが伺える質問がありました。Q&A時間は3分ほどの短い時間でしたので、ポスター発表にて詳細に議論する形になりました。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-portrait" src="/images/block-37497d4e-f442-804a-b372-c522de603c55-3096042602144931b3cf430ce4fd32def4807483.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><p class="rotion-text rotion-text-p"></p></div><div><h2 class="rotion-text rotion-text-h1" id="a02c4bae"><span class="rotion-richtext-annot rotion-richtext-default">ポスター発表</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">ポスター発表は鶴田（</span><a class="rotion-richtext-link" href="https://twitter.com/tsurubee3" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">@tsurubee3</span></a><span class="rotion-richtext-annot rotion-richtext-default">）が担当しました。セッションでは、以下のポスターを用いて研究内容の説明を行いました。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-37397d4e-f442-8058-a7a2-cb6064c82bf1-eb89320561a29726820d7b2ec1098c6360246aac.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">ポスターセッションは2時間で、その間に多くの参加者に立ち寄っていただき、研究内容について議論を交わしました。特に多く寄せられた質問は、LLM開発のワークロード特性に関するものでした。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">「オーラル発表」で紹介したワークロード分析の結果は直感に反すると感じる方が多かったようで、聴講者からは「なぜこのようなことが起きるのか」という質問を多く受け、非常に興味深く受け止められている様子が伝わってきました。これに対しては、LLM開発ではデータセット構築やモデル評価など小規模ジョブも多く実行される一方で、今回のプロジェクトでは継続事前学習など1週間以上連続で回る大規模ジョブも存在したこと、また、LLM開発ではリソース利用の効率化のためにジョブの進捗を継続的にモニタリングし、有望でないジョブを積極的にキャンセルする運用が一般的であることなどを説明しました。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">LLM開発では、ユーザーが学習過程に介入してジョブをキャンセルする運用や、開発フェーズごとに異なるジョブパターンへの遷移など、人とシステムが密接に連携する独特のダイナミクスが現れます。こうした実運用から得られた知見が学術コミュニティでも関心を集め、新鮮な視点を提供できることを実感できたのは、今後の研究開発を進めるうえでの大きな励みとなりました。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-37397d4e-f442-80ca-828f-e9904d39d42f-337e72f6cd98a9fe5409f8acbc8e56bf84e39e1c.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><h2 class="rotion-text rotion-text-h1" id="3ac504f5"><span class="rotion-richtext-annot rotion-richtext-default">おわりに</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">MLSys 2026のIndustry Track新設は、本番環境での開発・運用知見を学術コミュニティに還元する重要な動きと言えます。私たちの発表も、当初は日本の一企業の実システムの事例ということもあり、どの程度関心を持ってもらえるか不安な面もありました。しかし、現地での活発な議論や質疑応答を通じて、産業界からの実運用知見が学術コミュニティで広く関心を持たれ、産業界と学術界をつなぐ場としてのIndustry Trackの意義を実感しました。今後さらに、機械学習システム研究と産業界の運用実践がより密接に結びつき、新たな研究テーマや実装上の知見が次々と生まれる場へと発展していくことが期待されます。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">さくらインターネット研究所では引き続き、日本のAI研究・産業競争力を支える大規模AIインフラの研究開発に取り組んでまいります。本会議で得られた議論やフィードバックも、今後のさくらONEの発展と新たな研究課題の探索に活かしていきたいと考えています。</span></p></div></div>]]></content:encoded>
            <author>さくらインターネット研究所</author>
        </item>
        <item>
            <title><![CDATA[StalwartにおけるJMAP over WebSocketを用いたメールクライアントとメールサーバー間のデータ同期]]></title>
            <link>https://research.sakura.ad.jp/blog/jmap-over-websocket</link>
            <guid isPermaLink="false">https://research.sakura.ad.jp/blog/jmap-over-websocket</guid>
            <pubDate>Tue, 28 Apr 2026 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<link rel="preload" as="image" href="/images/html-icon-dc0d0bca5376e6b990a6c1f7ee70d6e6d2d83350-2ba3a0d7878316de5aaa6eed7faed9e4ba4e9f09.svg"/><link rel="preload" as="image" href="/images/html-image-1fa79bd9f47d73a47762a6c13c7e147ca8223855.webp"/><div class="rotion-blocks"><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">こんにちは！研究開発エンジニアの森田(</span><a class="rotion-richtext-link" href="https://x.com/tascript" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">@tascript</span></a><span class="rotion-richtext-annot rotion-richtext-default">)です。健康づくりの一環として、1か月に1回ほど歯科健診に行っています。歯がきれいだと気持ちも明るくなりますし、そろそろ最強の歯磨きセットを見つけたいなと思っています！</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">さて、</span><a class="rotion-richtext-link" href="https://research.sakura.ad.jp/blog/frontend-parallel-testing" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">前回のブログ</span></a><span class="rotion-richtext-annot rotion-richtext-default">でも</span><span class="rotion-richtext-annot rotion-richtext-default">お伝えした</span><span class="rotion-richtext-annot rotion-richtext-default">とおり、さくらインターネット研究所では</span><a class="rotion-richtext-link" href="https://research.sakura.ad.jp/blog/rc-activity-policy-2025" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">プロダクト開発グループ</span></a><span class="rotion-richtext-annot rotion-richtext-default">を設けており、現在メールに関する研究およびWebメールを開発しています。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">Webメールは、ユーザーがメールの状態を正確かつ迅速に認識できるようメールサーバーとメールクライアント間のデータ同期が重要です。例えば、新着メッセージをメールサーバーが受け取ったら、即座にメールクライアントに反映することで、ユーザーは新着メッセージが届いたことを認識できます。メールサーバーとメールクライアント間のデータ同期を実現するプロトコルとして</span><a class="rotion-richtext-link" href="https://datatracker.ietf.org/doc/html/rfc8621" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">JMAP(Json Meta Application Protocol)</span></a><span class="rotion-richtext-annot rotion-richtext-default">を使用しており、メールサーバーにはJMAPをサポートしている</span><a class="rotion-richtext-link" href="https://stalw.art/" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Stalwart</span></a><span class="rotion-richtext-annot rotion-richtext-default">を採用しました。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">Stalwartはメールサーバーにおける</span><span class="rotion-richtext-annot rotion-richtext-default">状態変更</span><span class="rotion-richtext-annot rotion-richtext-default">をメールクライアントに通知する方法として、</span><a class="rotion-richtext-link" href="https://www.rfc-editor.org/rfc/rfc8887.html" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">JMAP over WebSocket</span></a><span class="rotion-richtext-annot rotion-richtext-default">による双方向通信、</span><a class="rotion-richtext-link" href="https://stalw.art/docs/http/jmap/push" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Push Subscriptionsおよび</span></a><a class="rotion-richtext-link" href="https://stalw.art/docs/http/jmap/push" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Server Sent Event</span></a><span class="rotion-richtext-annot rotion-richtext-default">によるプッシュ通知を提供しています。私たちのプロジェクトは通知だけではなく、メールクライアントとメールサーバー間のデータ同期がオールインワンで可能なJMAP over WebSocketを採用しましたが、</span><a class="rotion-richtext-link" href="https://stalw.art/docs/http/jmap/websockets/#jmap-over-websocket" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Stalwartのドキュメント</span></a><span class="rotion-richtext-annot rotion-richtext-default">には接続方法およびデータ同期方法に関する記載がありません。</span><span class="rotion-richtext-annot rotion-richtext-default">そこで今回は、JMAP関連のRFCを調査しつつ、</span><span class="rotion-richtext-annot rotion-richtext-default">JMAP over WebSocketを利用したメールクライアントとメールサーバー間のデータ同期</span><span class="rotion-richtext-annot rotion-richtext-default">する機能を実装しましたので、その実装方法について紹介します。</span></p></div><div><h2 class="rotion-text rotion-text-h1" id="1735cee3"><span class="rotion-richtext-annot rotion-richtext-default">JMAP</span><span class="rotion-richtext-annot rotion-richtext-default">とは</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">JMAPは</span><a class="rotion-richtext-link" href="https://datatracker.ietf.org/doc/html/rfc8620" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">RFC8620</span></a><span class="rotion-richtext-annot rotion-richtext-default">にて定義されているクライアントとサーバー間でメール、カレンダー、連絡先などを同期するための汎用プロトコルです。JMAPを利用した電子メールデータの同期に必要なデータモデル(JMAP for Mail)については</span><a class="rotion-richtext-link" href="https://datatracker.ietf.org/doc/html/rfc8621" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">RFC8621</span></a><span class="rotion-richtext-annot rotion-richtext-default">にて定義されており、メッセージ、スレッドおよびメールボックスなどをJSONオブジェクトとして体系化することができ、メールの検索、読み取り、整理および送信を可能にします。</span><a class="rotion-richtext-link" href="https://datatracker.ietf.org/doc/rfc9051/" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">IMAP</span></a><span class="rotion-richtext-annot rotion-richtext-default">と比較すると、必要なデータをクライアント側で組み立てるのではなく、メールサーバー側で構造化データとして取り扱うことができるので、より高速かつ容易にデータフェッチが可能です。</span></p></div><div><h2 class="rotion-text rotion-text-h1" id="50da4eb9"><span class="rotion-richtext-annot rotion-richtext-default">JMAP over WebSocketとは</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">JMAP over WebSocketは</span><a class="rotion-richtext-link" href="https://datatracker.ietf.org/doc/html/rfc8887" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">RFC 8887</span></a><span class="rotion-richtext-annot rotion-richtext-default">にて定義されているWebSocketサブプロトコルであり、WebSocket上でJMAP APIへのリクエスト、レスポンスおよびプッシュ通知を実施します。JMAP over WebSocketを利用すれば、リアルタイムでのメールクライアントとメールサーバー間の同期が実現可能です。</span></p></div><div><h2 class="rotion-text rotion-text-h1" id="ba56e613"><span class="rotion-richtext-annot rotion-richtext-default">メールクライアントとメールサーバーの同期</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">この章では、JMAP over WebSocketを利用したメールクライアントとメールサーバーの同期を実現するために必要なフローおよび実装例について記載します。</span></p></div><div><h3 class="rotion-text rotion-text-h2" id="cfae6060"><span class="rotion-richtext-annot rotion-richtext-default">シーケンス図</span></h3></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">JMAP over WebSocketの接続からメールクライアントとメールサーバー間のデータ同期までのフローをシーケンス図にまとめます。</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="mermaid"><code>sequenceDiagram     participant Client as Mail Client     participant Proxy as Reverse Proxy     participant Server as Stalwart      Client-&gt;&gt;Proxy: WebSocket 接続 (/jmap/ws/)     Proxy-&gt;&gt;Server: Authorization Header + Sec-WebSocket-Protocol Header (/jmap/ws/)     Server-&gt;&gt;Client: WebSocket 接続完了      Note over Client,Server: 以降はJMAP over WebSocket      Client-&gt;&gt;Server: WebSocketPushEnable      Note right of Server: プッシュ通知の有効化      Client-&gt;&gt;Server: Email/get { ids: [] }     Server--&gt;&gt;Client: Email/get { state: &#x27;a&#x27; }      Client-&gt;&gt;Client: 現在のサーバーの状態を記憶(a)      Server-&gt;&gt;Server: 新着メールによる状態変更(b)      Server--&gt;&gt;Client: StateChange { Email: &#x27;b&#x27;, Mailbox, &#x27;b&#x27; }      Note left of Client: メールの変更を検知      Client-&gt;&gt;Server: Email/changes { sinceState: &#x27;a&#x27; }     Server--&gt;&gt;Client: Email/changes { created: [email-1] oldState: &#x27;a&#x27; newState: &#x27;b&#x27; }      Client-&gt;&gt;Client: 最新のサーバー状態を記憶(b)      Note over Client, Server: 「StateChange を受け取ったら Email/changes にリクエスト」を繰り返す</code></pre></div><div class="rotion-code-caption"></div></div></div><div><h3 class="rotion-text rotion-text-h2" id="c661f4e4"><span class="rotion-richtext-annot rotion-richtext-default">ハンドシェイク</span></h3></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">JMAP over WebSocketを実現するためにメールクライアントはHTTP上で接続ハンドシェイクを開始し、メールサーバーに対してWebSocketの接続を試みます。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">また、</span><a class="rotion-richtext-link" href="https://github.com/stalwartlabs/stalwart/blob/04b673587dfd21e541e3702a016e48addeb6308c/crates/registry/src/schema/structs.rs#L1931-L1932" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">StalwartはBasic認証とBearer認証の2つをサポート</span></a><span class="rotion-richtext-annot rotion-richtext-default">してい</span><span class="rotion-richtext-annot rotion-richtext-default">ます。しかし、ブラウザ上のWebSocketオブジェクトからはAuthorizaion Headerを設定することはできません。そのため、メールサーバーの前段にリバースプロキシを用意し、メールクライアントから送信された認証用トークンをAuthorizaion Headerに含める必要があります。認証用トークンの送信はURLクエリパラメータもしくは</span><a class="rotion-richtext-link" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Sec-WebSocket-Protocol" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Sec-WebSocket-Protocol Header</span></a><span class="rotion-richtext-annot rotion-richtext-default">に含める方法があります。URLクエリパラメータに含める場合は、リバースプロキシのアクセスログおよびブラウザの履歴等に記録されてしまうリスクがあります。よって、Sec-WebSocket-Protocol Headerからサブプロトコルと認証トークンを指定し、リバースプロキシで認証トークンをSec-WebSocket-Protocol Headerから取得後、Authorization Headerを作成してメールサーバーにリクエストします。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">ハンドシェイク用のリクエストは次のようなコードで実現します。</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-typescript"><code>const authToken = &#x27;....&#x27; const socket = new WebSocket(&#x27;wss://mail.test/jmap/ws/&#x27;, [&#x27;jmap&#x27;, `token.{$authToken}`])</code></pre></div><div class="rotion-code-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">メールサーバーの前段にリバースプロキシを設置し、Sec-WebSocket-Protocol Headerに含めたtokenを取得してAuthorization Headerを生成します。今回はリバースプロキシとして、</span><a class="rotion-richtext-link" href="https://caddyserver.com/" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Caddy</span></a><span class="rotion-richtext-annot rotion-richtext-default">を採用したので、以下のようなCaddyfileを用意します。</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-plain text"><code>https://mail.test {     tls &lt;cert_file&gt; &lt;key_file&gt;          @auth_token {         header_regexp token Sec-WebSocket-Protocol token.(.+)         path /jmap/ws/*     }          handle @auth_token {         reverse_proxy [対象のメールサーバー] {             header_up Authorization &quot;Bearer {re.token.1}&quot;             header_up Sec-WebSocket-Protocol &quot;jmap&quot;         }     } }</code></pre></div><div class="rotion-code-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">以上により、メールサーバーへのリクエストに対してSec-WebSocket-ProtocolにてサブプロトコルをJMAPに再設定し、Authorization HeaderにBearer Tokenを指定することができます。認証が成功すれば、通信はHTTPからWebSocketに切り替わります。なお、認証情報はWebSocketの接続期間中であれば再度認証を実施する必要はありません。</span></p></div><div><h3 class="rotion-text rotion-text-h2" id="c6d1d5c4"><span class="rotion-richtext-annot rotion-richtext-default">プッシュ通知の有効化</span></h3></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">WebSocket接続が完了後、クライアントがメールサーバーからのプッシュ通知を受け取るためには、</span><a class="rotion-richtext-link" href="https://www.rfc-editor.org/rfc/rfc8887.html#name-enabling-notifications" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">WebSocketPushEnableオブジェクト</span></a><span class="rotion-richtext-annot rotion-richtext-default">をメールサーバーに送信する必要があります。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">プッシュ通知有効化のリクエストは以下のようなコードで実現します。</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-typescript"><code>...  const webSocketPushEnableObject = {   &#x27;@type&#x27;: &#x27;WebSocketPushEnable&#x27;,    dataTypes: [&#x27;Mailbox&#x27;, &#x27;Email&#x27;] // プッシュ通知を受け取りたいデータ型一覧 }  // プッシュ通知有効化のリクエスト socket.send(JSON.stringify(webSocketPushEnableObject))</code></pre></div><div class="rotion-code-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><a class="rotion-richtext-link" href="https://developer.mozilla.org/ja/docs/Web/API/WebSocket/send" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">WebSocket.send()</span></a><span class="rotion-richtext-annot rotion-richtext-default">メソッドを利用してメールボックスとメールに関する変更をプッシュ通知できるようになります。</span></p></div><div><h3 class="rotion-text rotion-text-h2" id="e699def5"><span class="rotion-richtext-annot rotion-richtext-default">クライアントの現在の状態(sinceState)を取得</span></h3></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">JMAPではメールに関する状態をstateプロパティでバージョン管理システムのように管理します。stateプロパティはメールに関するJMAP APIのレスポンスから取得可能であり、不特定多数のメールクライアントからメールサーバーの状態を確認することが出来ます。つまりメールクライアントとメールサーバのデータ同期は、メールクライアントとメールサーバーでstateを共有することで達成します。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">プッシュ通知を有効化したことで、以降はメールサーバーで発生した変更を受け取ることができるようになりました。メールサーバーの変更は</span><a class="rotion-richtext-link" href="https://datatracker.ietf.org/doc/html/rfc8620#section-7.1" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">stateChangeオブジェクト</span></a><span class="rotion-richtext-annot rotion-richtext-default">をWebSocket上でクライアントが受け取ることで検知可能です。</span><span class="rotion-richtext-annot rotion-richtext-default">このとき、メールサーバーはクライアントがどの時点以降の変更を通知してほしいのかわかりません。</span><span class="rotion-richtext-annot rotion-richtext-default">そのため、メールクライアントは現時点と比較したメールサーバーにおける状態変更を通知してほしいことをメールサーバーにリクエストする必要があります。その際に必要なパラメータがsinceStateです。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">sinceStateは、stateChangeによって変更されたターゲットを確認する</span><a class="rotion-richtext-link" href="https://datatracker.ietf.org/doc/html/rfc8620#section-5.2" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">/changes</span></a><span class="rotion-richtext-annot rotion-richtext-default">メソッドで利用するプロパティであり、指定した状態以降の変化を受け取るために必要です。sinceStateは</span><a class="rotion-richtext-link" href="https://datatracker.ietf.org/doc/html/rfc8620#section-5.1" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">/get</span></a><span class="rotion-richtext-annot rotion-richtext-default">メソッドのレスポンスであるstateから取得することができるので、プッシュ通知の有効化されたら、</span><a class="rotion-richtext-link" href="https://datatracker.ietf.org/doc/html/rfc8621#section-4.2" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Email/getメソッド</span></a><span class="rotion-richtext-annot rotion-richtext-default">を実施し、stateを取得してsinceStateにバインドします。これにより、メールクライアントが持っているstateをメールサーバに共有することができます。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">また、Email/getメソッドはidsをnullで指定すると、メールサーバーに存在する全てのメールを取得しますが、これまでに一度もメールサーバーのデータをクライアントに同期してない場合に有効なので、sinceStateを取得する前に一度リクエストしておくとよいでしょう。全件のメールがメールクライアントに同期済みの場合かつsinceStateがない場合は、特定のメール情報を取得する必要がないので、Email/getメソッドに対してidsを空配列でリクエストします。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">Email/getメソッドへのリクエストは以下のようなコードで実現します。</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-typescript"><code>...  const pendingRequest = new MAP() let sinceState = &#x27;&#x27;  const sendRequest = (ws, name, params, callId) =&gt; {   return new Promise((resolve, reject) =&gt; {     pendingRequest.set(callId, {resolve, reject})          socket.send(JSON.stringify({       &#x27;@type&#x27;: &#x27;Request&#x27;,       using: [&#x27;urn:ietf:params:jmap:core&#x27;, &#x27;urn:ietf:params:jmap:mail&#x27;]       methodCalls: [name, params, callId]     })      setTimeoout(() =&gt; {       if (pendingRequest.has(callId)) {         pendingRequest.delete(callId)         reject(new Error(&#x27;JMAP Request timeout&#x27;))       }     }, 10000)   }) }  const handleResponse = (message) =&gt; {   for (const [name, data, callId] of message.methodResponses) {     const pr = pendingRequest.get(callId)     if (!pr) {       continue     }     const {resolve} = pr     pendingRequest.delete(callId)     resolve(response)   } }  socket.onmessage = (event) =&gt; {   const message = JSON.parse(event.data)    switch(message[&#x27;@type&#x27;]) {     case &#x27;Response&#x27;:       handleReponse(message)       break     ...   } }  // Email/getメソッドへのリクエスト const response = await sendRequest(socket, &#x27;Email/get&#x27;, {accountId: &#x27;test&#x27;, ids: []} &#x27;email-get-1&#x27;) sinceState = response.state</code></pre></div><div class="rotion-code-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">メールサーバーにEmail/getメソッドのリクエストを送る関数にて、</span><a class="rotion-richtext-link" href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise#%E5%BC%95%E6%95%B0" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">PromiseコンストラクターのresolveFunc</span></a><span class="rotion-richtext-annot rotion-richtext-default">を</span><a class="rotion-richtext-link" href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Map" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Mapオブジェクト</span></a><span class="rotion-richtext-annot rotion-richtext-default">に保存します。メールサーバーはリクエストに対してWebSocketを通じて、メールクライアントにレスポンスを返します。メールクライアントでは、</span><a class="rotion-richtext-link" href="https://developer.mozilla.org/ja/docs/Web/API/WebSocket#%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">WebSocketのmessageイベント</span></a><span class="rotion-richtext-annot rotion-richtext-default">にてメールサーバーからレスポンスを受け取り、resolveにラップして返すことで、Email/getメソッドの実行結果を取得します。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">また、Email/getメソッドのレスポンスは以下のようになります。</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-typescript"><code>[   &quot;Email/get&quot;,   {     &quot;accountId&quot;: &quot;test&quot;,     &quot;state&quot;: &quot;a&quot;,     &quot;list&quot;: [],     &quot;notFound&quot;: []   },   &quot;email-get-1&quot; ]</code></pre></div><div class="rotion-code-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><a class="rotion-richtext-link" href="https://datatracker.ietf.org/doc/html/rfc8620#section-5.1" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">stateプロパティ</span></a><span class="rotion-richtext-annot rotion-richtext-default">は現在のメールサーバーの状態を表現する文字列です。stateプロパティはメールサーバーにて対象データの変更があると変化します。これをsessionStateに保存し、メールサーバーの状態変更を確認する</span><a class="rotion-richtext-link" href="https://datatracker.ietf.org/doc/html/rfc8620#section-5.2" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">/changes</span></a><span class="rotion-richtext-annot rotion-richtext-default">メソッドのリクエストに含めることで、メールクライアントとメールサーバーの状態を同期します。</span></p></div><div><h3 class="rotion-text rotion-text-h2" id="9aba5270"><span class="rotion-richtext-annot rotion-richtext-default">メールサーバーの状態変更を検知する</span></h3></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">メールサーバーにて状態変更が発生すると、</span><a class="rotion-richtext-link" href="https://datatracker.ietf.org/doc/html/rfc8620#section-7.1" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">StateChnageオブジェクト</span></a><span class="rotion-richtext-annot rotion-richtext-default">をメールクライアントに送信します。メールクライアントでは、WebSocketのmessageイベントにてこれを受け取ります。例えば、メールサーバーにてメールを受信した際には以下のようなStateChangeオブジェクトをメールクライントに送信します。</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-typescript"><code>{   &quot;@type&quot;:&quot;StateChange&quot;,   &quot;changed&quot;: {     &quot;test&quot;: {       &quot;Mailbox&quot;: &quot;b&quot;,       &quot;Email&quot;: &quot;b&quot;     }   } }</code></pre></div><div class="rotion-code-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">アカウント単位で対象データにおける最新のstateプロパティを返しており、Email/getリクエストで取得した際の値と異なる(</span><span class="rotion-richtext-annot  rotion-richtext-code rotion-richtext-code-color">a</span><span class="rotion-richtext-annot rotion-richtext-default">から</span><span class="rotion-richtext-annot  rotion-richtext-code rotion-richtext-code-color">b</span><span class="rotion-richtext-annot rotion-richtext-default">に変化)ことから、メールボックスとメールに対する変更が確認できます。メールクライアントでは、StateChangeオブジェクトをWebSocketのmessageイベントにて受け取ることができますので、続けてメールクライアントから</span><a class="rotion-richtext-link" href="https://datatracker.ietf.org/doc/html/rfc8621#section-4.3" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Email/changes</span></a><span class="rotion-richtext-annot rotion-richtext-default">メソッドに対してリクエストを実施し、どのメールに対してどのような変更があったかを確認します。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">一連のフローは以下のようなコードで実現します。</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-typescript"><code>...  const handleStateChange = (message) =&gt; {   const response = await sendRequest(     socket,     &#x27;Email/changes&#x27;,     {       accountId: &#x27;test&#x27;,       sinceState // sinceStateは&#x27;a&#x27;     },     &#x27;email-changes-1&#x27;   )   ... }  socket.onmessage = (event) =&gt; {   const message = JSON.parse(event.data)    switch(message[&#x27;@type&#x27;]) {     case &#x27;Response&#x27;:       handleReponse(message)       break     case &#x27;StateChange&#x27;:       handleStateChange(message)       break     ...   } }</code></pre></div><div class="rotion-code-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">また、Email/changes APIは以下のようなレスポンスを返します。</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-typescript"><code>{   &quot;@type&quot;:&quot;Response&quot;,   &quot;methodResponses&quot;: [     [       &quot;Email/changes&quot;,       {         &quot;accountId&quot;: &quot;test&quot;,         &quot;oldState&quot;: &quot;a&quot;,         &quot;newState&quot;: &quot;b&quot;,         &quot;hasMoreChanges&quot;: false,         &quot;created&quot;: [&quot;email-1&quot;],         &quot;updated&quot;: [],         &quot;destroyed&quot;: []       },       &quot;email-changes-1&quot;     ]   ],   &quot;sessionState&quot;: &quot;session-state&quot; }</code></pre></div><div class="rotion-code-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><a class="rotion-richtext-link" href="https://datatracker.ietf.org/doc/html/rfc8620#section-5.2" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">oldStateとnewState</span></a><span class="rotion-richtext-annot rotion-richtext-default">の値がそれぞれEmail/getメソッドのレスポンスのstateプロパティ(</span><span class="rotion-richtext-annot  rotion-richtext-code rotion-richtext-code-color">a</span><span class="rotion-richtext-annot rotion-richtext-default">)とStateChangeオブジェクトにおける各データのstate(</span><span class="rotion-richtext-annot  rotion-richtext-code rotion-richtext-code-color">b</span><span class="rotion-richtext-annot rotion-richtext-default">)に一致していることから、メールに関して</span><span class="rotion-richtext-annot  rotion-richtext-code rotion-richtext-code-color">a</span><span class="rotion-richtext-annot rotion-richtext-default">から</span><span class="rotion-richtext-annot  rotion-richtext-code rotion-richtext-code-color">b</span><span class="rotion-richtext-annot rotion-richtext-default">までの状態変更を検知したことが確認できます。また、createdプロパティにメールのidが含まれていることから、idが</span><span class="rotion-richtext-annot  rotion-richtext-code rotion-richtext-code-color">email-1</span><span class="rotion-richtext-annot rotion-richtext-default">のメールを受信したことが確認できます。あとは必要に応じて、対象IDのメールをEmail/get APIから取得するなどしてメールクライアントとメールサーバー間でデータを同期します。</span></p></div><div><h2 class="rotion-text rotion-text-h1" id="205765a4"><span class="rotion-richtext-annot rotion-richtext-default">Stalwartが抱える</span><span class="rotion-richtext-annot rotion-richtext-default">課題</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">Stalwartの認証時、ブラウザ上のWebSocketオブジェクトでは、Authorization Headerを指定できないのでメールサーバーの前段にリバースプロキシを置いて対応しましたが、2026年1月にStalwartのdiscussionsにて対策が提案されています。</span></p></div><div><div class="rotion-bookmark"><div class="rotion-bookmark-area"><div class="rotion-bookmark-text"><div class="rotion-bookmark-title">JMAP WebSocket Ticket-Based Authentication for Browser Clients · stalwartlabs/stalwart · Discussion #2680 · GitHub</div><div class="rotion-bookmark-desc">Summary Browser-based JMAP clients cannot use WebSocket push notifications because browsers do not allow setting custom HTTP headers (like Authorization: Bearer) on WebSocket connections. This is a...</div><div class="rotion-bookmark-url"><img class="rotion-bookmark-favicon" src="/images/html-icon-dc0d0bca5376e6b990a6c1f7ee70d6e6d2d83350-2ba3a0d7878316de5aaa6eed7faed9e4ba4e9f09.svg" width="16px" alt=""/>https://github.com/stalwartlabs/stalwart/discussions/2680</div></div><div class="rotion-bookmark-image"><img class="rotion-bookmark-img" src="/images/html-image-1fa79bd9f47d73a47762a6c13c7e147ca8223855.webp" width="200px" height="auto" alt=""/></div></div><div class="rotion-bookmark-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">このdiscussionsでは先にAuthorizaion Header付きのHTTPリクエストで有効期限の短いチケットを受け取るエンドポイントを用意して、受け取ったチケットをWebSocketサーバーのURLにクエリパラメータとして含めて認証するという方法が提案されています。</span><a class="rotion-richtext-link" href="https://github.com/HMB-research/stalwart/blob/97d43edb949da7a1256a7ebcbdfdcb9221cf9419/crates/jmap-proto/src/request/capability.rs#L378-L388" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">フォークされたリポジトリには実装済み</span></a><span class="rotion-richtext-annot rotion-richtext-default">であり、この方法だとリバースプロキシは不要になるのでより便利になるかもしれません。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">JMAPは</span><a class="rotion-richtext-link" href="https://datatracker.ietf.org/doc/html/rfc8620#section-8.2" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">認証スキーム</span></a><span class="rotion-richtext-annot rotion-richtext-default">に関して、IANA公開されている</span><a class="rotion-richtext-link" href="https://www.iana.org/assignments/http-authschemes/http-authschemes.xhtml" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">HTTP Authentication Scheme Registry</span></a><span class="rotion-richtext-annot rotion-richtext-default">を参考にするよう明示しており、上記の認証方法は含まれていないのでStalwartの独自実装になることが望ましいと考えています。</span></p></div><div><h2 class="rotion-text rotion-text-h1" id="58838d19"><span class="rotion-richtext-annot rotion-richtext-default">最後に</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">JMAPはIMAPと比較してパフォーマンスの観点において非常に優れたプロトコルですが、2026年4月現在、JMAPに関する実装は充足しているとは言えません。よって基本はRFCを読みながら実装することになります。もちろんRFCを読むことは大事ですが、より多くの実装や知見を増やすことで技術は汎用的になっていくと考えています。今後もJMAPおよびメールに関する情報共有を進めていきますので、ご覧いただけますと幸いです。</span></p></div></div>]]></content:encoded>
            <author>さくらインターネット研究所</author>
        </item>
        <item>
            <title><![CDATA[AIは教育を変えるのか？ ―北欧・日本の教育変革から導かれる「文化・歴史的活動理論」という視点]]></title>
            <link>https://research.sakura.ad.jp/blog/ai-chat</link>
            <guid isPermaLink="false">https://research.sakura.ad.jp/blog/ai-chat</guid>
            <pubDate>Mon, 27 Apr 2026 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<link rel="preload" as="image" href="/images/html-icon-5813aa578db91524047bd62c87a636a212b2ada6-2ba3a0d7878316de5aaa6eed7faed9e4ba4e9f09.webp"/><link rel="preload" as="image" href="/images/html-image-a887d32bbc65d7e445d2b7fdc4d157cfbe32d8ad.webp"/><link rel="preload" as="image" href="/images/block-34c97d4e-f442-80ab-8b7f-c658ef00e272-23a1052fe1d94cab5ff284f64d3f6abd898cd2ad.webp"/><link rel="preload" as="image" href="/images/block-34c97d4e-f442-80ce-9572-cf45d6840304-1862a5eb1f1a0928fd02ec7094cf7fe6aa300da0.webp"/><link rel="preload" as="image" href="/images/block-34c97d4e-f442-8030-9a3a-fde332b4be48-0a6047a7e6508479bfb13d29f67c8164687cd36d.webp"/><link rel="preload" as="image" href="/images/block-34c97d4e-f442-806c-a8c5-f252cde1a3bd-f07daba4f7aab8953a97ecb5fd5726475092519d.webp"/><link rel="preload" as="image" href="/images/block-34c97d4e-f442-8030-a111-cfb085b6d7e0-50eb1bc21a9331cd9f9ef3ffc52589fbd86e42ba.webp"/><link rel="preload" as="image" href="/images/block-34c97d4e-f442-8056-bb67-db258a54a2e5-4de578fc18f7859edeb4abf85905cee00bc281b8.webp"/><link rel="preload" as="image" href="/images/block-34c97d4e-f442-80a4-8525-cdaa189e94c8-18abafde81fd7c2222bc6ee9eff53822028747e2.webp"/><div class="rotion-blocks"><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">2026年4月18日（土）、大阪国際会議場で「AI、教育と文化・歴史的活動理論（以下、CHAT）」に関する国際シンポジウムが開催され、スウェーデン、フィンランド、日本の研究者が集まり、AI時代の教育をどう捉えるべきかが議論された。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">本記事は拡張的学習理論及びCHATに関する専門的な知見をもとに構成されている。本記事での議論を含む拡張的学習理論、CHATに興味のある方には、ぜひInternational Society of Cultural-historical Activity Research（ISCAR）への参加を推奨したい。</span></p></div><div><div class="rotion-bookmark"><div class="rotion-bookmark-area"><div class="rotion-bookmark-text"><div class="rotion-bookmark-title">ISCAR: International Society for Cultural-historical Activity Research &amp;ndash; The International Society for Cultural-Historical Activity Research</div><div class="rotion-bookmark-desc">ISCAR is a scientific association that aims at: Developing multidisciplinary theoretical and empirical research on societal, cultural and historical dimensions of human practices Promoting mutual scientific communication and research cooperation among its members.</div><div class="rotion-bookmark-url"><img class="rotion-bookmark-favicon" src="/images/html-icon-5813aa578db91524047bd62c87a636a212b2ada6-2ba3a0d7878316de5aaa6eed7faed9e4ba4e9f09.webp" width="16px" alt=""/>https://iscar.org/</div></div><div class="rotion-bookmark-image"><img class="rotion-bookmark-img" src="/images/html-image-a887d32bbc65d7e445d2b7fdc4d157cfbe32d8ad.webp" width="200px" height="auto" alt=""/></div></div><div class="rotion-bookmark-caption"></div></div></div><div><h2 class="rotion-text rotion-text-h1" id="e1c28f7f"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">シンポジウム概要</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">International Symposium on AI, Education, and Cultural-Historical Activity Theory</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">シンポジウムテーマ：</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">Transforming Education through AI in Schools: International Collaborative Research on Activity-Theoretical Formative Interventions for Fairness and Inclusion</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">日時：</span><span class="rotion-richtext-annot rotion-richtext-default">2026年4月18日（土）15:00–18:30</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">場所：</span><span class="rotion-richtext-annot rotion-richtext-default">大阪国際会議場　1101会議室、オンライン</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">使用言語：</span><span class="rotion-richtext-annot rotion-richtext-default">英語</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">参加費：</span><span class="rotion-richtext-annot rotion-richtext-default">無料</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">主催：</span><span class="rotion-richtext-annot rotion-richtext-default">2022年度〜2026年度 科学研究費・基盤研究（Ａ）「拡張する学校を創る―変革的エージェンシーの形成へ―」（研究代表者：山住勝広、課題番号：22H00084）</span></p></div><div><h4 class="rotion-text rotion-text-h3" id="4741094f"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">プログラム</span></h4></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">Keynote Address</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">Johan Lundin</span><span class="rotion-richtext-annot rotion-richtext-default"> (University of Gothenburg, Sweden)<br />AI, school development and school leadership in Swedish municipalities<br />—acting strategically or dealing with the inevitable</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">Presentation</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">Norio Tokumaru</span><span class="rotion-richtext-annot rotion-richtext-default"> (Kansai University, Japan)<br />Innovation through creative tension: Capitalist logic and social needs in EdTech development in Finland and Japan</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">Presentation</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">Erik Winerö</span><span class="rotion-richtext-annot rotion-richtext-default"> (University of Gothenburg, Sweden)<br />Learning, knowledge, and assessment in the age of generative AI</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">Presentation</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">Marie Utterberg Modén</span><span class="rotion-richtext-annot rotion-richtext-default"> (University of Gothenburg, Sweden)<br />Using provotypes to explore how teachers value AI in education</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">Presentation</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">Sofia Serholt</span><span class="rotion-richtext-annot rotion-richtext-default"> (University of Gothenburg, Sweden)<br />Telepresence robots for remote classroom participation in the Swedish context</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">Presentation</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">Katsuhiro Yamazumi</span><span class="rotion-richtext-annot rotion-richtext-default"> (Kansai University, Japan)<br />Can AI in Japanese elementary schools serve as an instrument for expansive learning and transformative agency? An activity-theoretical case study</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">Discussant’s Comments</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">Yrjö Engeström</span><span class="rotion-richtext-annot rotion-richtext-default"> (University of Helsinki, Finland) [online]</span></p></div><div><h2 class="rotion-text rotion-text-h1" id="c129dd55"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">スウェーデンの教育における「アナログ回帰」は何を意味するのか</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">結論から言えば、このシンポジウムは「AIの教育利用の是非」や「AIをどう使うか」という話ではなかった。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">むしろ問いはこうだった。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">そもそも、教育とは何をする営みなのか？</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">そしてこの問いこそが、近年注目されている拡張的学習理論（Expansive Learning）や、CHATの核心にある。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">まず注目すべきは、スウェーデンの教育をめぐる状況である。最近日本では、スウェーデンの教育が「デジタル教育から紙へ回帰している」という報道が多く見られ、それがデジタル教育の失敗に結び付けられた論調が目立つ。しかし、今回の基調講演でスウェーデンヨーテボリ大学Johan Lundin教授が示したのは、それとは少し異なる風景だった。彼によれば、スウェーデンでは「AI国家戦略の推進」「教育のデジタル化の継続」の一方で「スクリーンタイム削減」の議論が</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">同時に存在している</span><span class="rotion-richtext-annot rotion-richtext-default">。つまりこれは単純な「デジタル失敗→紙回帰」ではなく、</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">社会全体の矛盾が教育現場に現れている状態</span><span class="rotion-richtext-annot rotion-richtext-default">だという。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">実際、自治体レベルの議論では、AIは単一のものとして理解されているわけではなかった。むしろ議論は、次のような異なる「関心の方向」に分かれていた。</span></p></div><div><ul class="rotion-listblocks rotion-list-ul"><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">効率化（業務削減）</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">法制度・安全性</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">データ分析</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">学習支援</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">民主主義・AIリテラシー</span></li></ul></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-34c97d4e-f442-80ab-8b7f-c658ef00e272-23a1052fe1d94cab5ff284f64d3f6abd898cd2ad.webp" alt=""/></div><div class="rotion-image-caption"><span class="rotion-richtext-annot rotion-richtext-default">AI, SCHOOL DEVELOPMENT AND SCHOOL LEADERSHIP IN SWEDISH MUNICIPALITIES<br />- ACTING STRATEGICALLY OR DEALING WITH THE INEVITABLE（2026, Lundin）</span></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">ここで重要なのは、これらはAIの機能分類などではなく、</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">AIをめぐる議論がどこに向かっているか（オリエンテーション）</span><span class="rotion-richtext-annot rotion-richtext-default">を示している点である。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-34c97d4e-f442-80ce-9572-cf45d6840304-1862a5eb1f1a0928fd02ec7094cf7fe6aa300da0.webp" alt=""/></div><div class="rotion-image-caption"><span class="rotion-richtext-annot rotion-richtext-default">AI, SCHOOL DEVELOPMENT AND SCHOOL LEADERSHIP IN SWEDISH MUNICIPALITIES<br />- ACTING STRATEGICALLY OR DEALING WITH THE INEVITABLE（2026, Lundin）</span></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">例えば、効率化はAIに業務を担わせる発想である一方、法制度や安全性はAIをどのように制御するかという人間側の課題である。さらに、民主主義やAIリテラシーは、AIそのものではなく、それを取り巻く社会のあり方に関わる問題である。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">つまり、AIは単なる技術ではなく、</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">労働・統治・教育・社会を横断する複合的な対象</span><span class="rotion-richtext-annot rotion-richtext-default">として扱われている。そして実際の議論では、これらの方向は必ずしも統合されることなく、むしろ互いに競合していた。結果として、効率化や安全性が優先され、教育や民主主義に関わる議論は後景に退きがちである。この「議論の分裂」そのものが、AIが教育にもたらしている最も重要な変化の一つなのかもしれない。</span></p></div><div><h2 class="rotion-text rotion-text-h1" id="730a0e2f"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">フィンランドの「デジタルと紙を対立させない」発想と政治経済学的視点</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">関西大学徳丸宜穂教授の発表は、この問題をさらに構造的に捉えるものだった。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">フィンランドでは、デジタル化は否定されていない。むしろ重要なのは「教育的に意味のある形でデジタルを使う」という原則である。その結果として、ある自治体では数学や外国語では紙教材に戻るがデジタル化自体は継続という判断がなされている。ここで重要なのは、「紙かデジタルか」という二択ではなく、</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">教育的に適切かどうか</span><span class="rotion-richtext-annot rotion-richtext-default">という基準で選択されている点だ。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">さらに興味深いのは、フィンランドでは</span></p></div><div><ul class="rotion-listblocks rotion-list-ul"><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">教師の裁量が大きい</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">自治体が調達をコントロール</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">研究者・学校・企業が連携</span></li></ul></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">という仕組みによって、企業主導ではなく</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">教育者側が技術を選ぶ構造</span><span class="rotion-richtext-annot rotion-richtext-default">が成立していることである。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-34c97d4e-f442-8030-9a3a-fde332b4be48-0a6047a7e6508479bfb13d29f67c8164687cd36d.webp" alt=""/></div><div class="rotion-image-caption"><span class="rotion-richtext-annot rotion-richtext-default">Innovation through creative tension: Capitalist logic and social needs in EdTech development in Finland and Japan<br />（2026, Tokumaru）</span></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">さらに興味深いのは、徳丸教授がこの問題を教育学ではなく、</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">政治経済学の視点から捉えている点</span><span class="rotion-richtext-annot rotion-richtext-default">である。彼の発表の出発点は、「デジタルか紙か」という教育論的な問いではない。むしろ、EdTechという領域を「資本主義の論理（企業の利益追求）と社会的ニーズ（教育）の緊張関係の中にあるもの」として位置づけるところから議論が始まる。この視点に立つと、フィンランドの特徴は単に「デジタルをうまく使っている」ということではなく、</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">市場と教育の関係が一方向ではないこと</span><span class="rotion-richtext-annot rotion-richtext-default">にある。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">徳丸教授はこれを、Karl Polanyiの「double movement」概念を用いて「資本主義の論理と社会的論理の“創造的緊張”」として説明する。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-34c97d4e-f442-806c-a8c5-f252cde1a3bd-f07daba4f7aab8953a97ecb5fd5726475092519d.webp" alt=""/></div><div class="rotion-image-caption"><span class="rotion-richtext-annot rotion-richtext-default">Innovation through creative tension: Capitalist logic and social needs in EdTech development in Finland and Japan<br />（2026, Tokumaru）</span></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">ここで重要なのは、この緊張関係が単に対立するのではなく、</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">むしろイノベーションの源泉になっている</span><span class="rotion-richtext-annot rotion-richtext-default">と捉えられている点である。したがって、フィンランドにおける「紙への回帰」も、デジタル化の否定ではなく、</span></p></div><div><ul class="rotion-listblocks rotion-list-ul"><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">教育の論理が市場の論理に対してブレーキをかける動き</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">あるいは両者のバランスを取り直す過程</span></li></ul></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">として理解されるべきものになる。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">このように見ると、「デジタルか紙か」という二項対立そのものが問題なのではなく、</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">どのような社会的力関係の中で技術が選ばれているのか</span><span class="rotion-richtext-annot rotion-richtext-default">が問われていることがわかる。</span></p></div><div><h2 class="rotion-text rotion-text-h1" id="6d2d6106"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">実証的研究から見えるAIの影響</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">今回のシンポジウムでは、AIと教育の関係を理論的・制度的に捉える議論と並行して、より現場に近いレベルでの実証的研究も報告された。</span></p></div><div><h4 class="rotion-text rotion-text-h3" id="d784efc5"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">視点①　評価をめぐる制度の問題</span></h4></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">Winerö氏は、生成AIの普及が</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">評価の仕組みそのものを揺るがしている</span><span class="rotion-richtext-annot rotion-richtext-default">ことを指摘する。従来の学校教育では、学習の成果物（レポートや作文など）が学習の達成度を測る基準となってきた。しかし生成AIによって、成果物が必ずしも学習者自身の理解を反映しなくなる。スライドでも、AI導入後には「学習」と「成果物（Product）」の関係が切り離され、従来の評価が成立しにくくなる構造が示されていた。</span></p></div><div><h4 class="rotion-text rotion-text-h3" id="0490b0a3"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">視点②　設計に埋め込まれる価値観の問題</span></h4></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">Modén氏は、AIをどのように設計するかという観点から、教師の関与の重要性を論じた。AIは中立的な道具ではなく、その設計には特定の価値観が埋め込まれる。にもかかわらず、現状では教育的価値、特に公平性や多様性といった観点が十分に反映されていない。そこで彼女は、教師がAI設計に参加し、その中にある矛盾（例えば「個別最適化」と「共同学習」の対立）を明示化する方法として「provotypes」という手法を提示した。これは、AIをより良くするための設計手法であると同時に、教育そのものを問い直すプロセスでもある。</span></p></div><div><h4 class="rotion-text rotion-text-h3" id="5edd360d"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">視点③　参加と社会関係の問題</span></h4></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">Serholt氏は、遠隔参加ロボット（AV1）を事例に、AIが学習環境における</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">参加やアイデンティティのあり方</span><span class="rotion-richtext-annot rotion-richtext-default">をどのように変えるかを検討した。このロボットは、病気や不登校の子どもが遠隔で授業に参加するための装置であり、スウェーデンではすでに多くの自治体で利用されている。 しかし彼女の関心は技術の有効性そのものではなく、それによって</span></p></div><div><ul class="rotion-listblocks rotion-list-ul"><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">子どもの「参加」はどのように変わるのか</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">人間としての関係性は維持されるのか</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">本当に学校への復帰につながるのか</span></li></ul></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">といった問いに向けられている。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">これら3つの発表に共通しているのは、AIを単なる「便利なツール」としてではなく、</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">教育実践の具体的な構造を変える存在として捉えている点</span><span class="rotion-richtext-annot rotion-richtext-default">である。そして興味深いのは、それぞれが扱うテーマ――評価、設計、参加――が、いずれも教育の中核に関わる領域であるにもかかわらず、それらが現在のAI導入の議論ではしばしば周縁化されていることである。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">この意味でこれらの研究は、シンポジウム全体の理論的議論を補完しつつ、</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">AIが現場にもたらしている変化を具体的に可視化する役割</span><span class="rotion-richtext-annot rotion-richtext-default">を果たしていたと言えるだろう。</span></p></div><div><h2 class="rotion-text rotion-text-h1" id="4b4ef766"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">AIは「活動」を変革する道具となり得るか？</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">ここまでの発表を受けて山住教授の発表で強調されていたのは、AIを活動システムの中にどのように位置づけるかという点である。文化・歴史的活動理論において、AIはあくまで「道具（instrument）」として理解される。実際、彼の分析でもAIは活動システムの中で主体と対象を媒介する存在として位置づけられている。しかしここで重要なのは、CHATにおける「道具」は単なる補助的な手段ではないということである。道具が変わると、それを用いた活動のあり方そのものが変化するということである。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">山住教授は研究協力先である大阪教育大学付属天王寺小学校へのチェンジラボラトリーによる介入研究により、小学生が利用するAIの役割を「知識の提供者」ではなく「探究を促す媒介」として再定義する試みであると位置づけた。天王寺小学校では学習用として単に質問者の指示により答えを出すツールではなく、あえて答えを出さず視点や問いを提示するように設計された生成AIを利用している。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-34c97d4e-f442-8030-a111-cfb085b6d7e0-50eb1bc21a9331cd9f9ef3ffc52589fbd86e42ba.webp" alt=""/></div><div class="rotion-image-caption"><span class="rotion-richtext-annot rotion-richtext-default">Can AI in Japanese elementary schools serve as an instrument for expansive learning and transformative agency?  An activity-theoretical case study（2026, Yamazumi）</span></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">実際、AIの導入によって変わるのは単なる作業の効率ではない。例えば、</span></p></div><div><ul class="rotion-listblocks rotion-list-ul"><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">学習の目的（答えを出すことから問いを探究することへ）</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">子どもとAIの役割分担</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">授業のルールや進め方</span></li></ul></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">といった、活動の基本的な構造が変わり始めている。具体的には、授業で用いられた生成AI（tomoLinks）は、</span></p></div><div><ul class="rotion-listblocks rotion-list-ul"><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">直接答えを出さない</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">代わりに複数の視点を提示する</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">調べるための方向や問いを示す</span></li></ul></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">といった形で応答するように設計されていた。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">例えば、生徒がある歴史的事象について質問した場合、AIはその答えを説明するのではなく、「どの立場から考えるか」「どのような資料を参照すべきか」といった形で思考の方向性を示す。つまり、答えを提示するのではなく、</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">探究のプロセスそのものを支援する役割</span><span class="rotion-richtext-annot rotion-richtext-default">を担っている。さらに教師自身も、このAIを「学習をナビゲートする存在」として捉えており、AIの役割は知識の提供ではなく、探究を支える媒介として再定義されている。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-34c97d4e-f442-8056-bb67-db258a54a2e5-4de578fc18f7859edeb4abf85905cee00bc281b8.webp" alt=""/></div><div class="rotion-image-caption"><span class="rotion-richtext-annot rotion-richtext-default">Can AI in Japanese elementary schools serve as an instrument for expansive learning and transformative agency?  An activity-theoretical case study（2026, Yamazumi）</span></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">さらに重要なのは、このようなAIの使い方によって、学習の目的そのものが変化している点である。従来の授業では、正しい答えに到達することが中心的な目標であったが、この実践では、問いを立て、視点を広げ、調べるプロセスそのものが学習の中心に据えられている。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">山住教授はこの変化を、単なるツールの違いではなく、活動システムの再構成として捉えている。AIは「知識の提供者」としてではなく、「探究を促す媒介」として再設計されることで、学習の対象（object）そのものを「正解の獲得」から「問いの探究」へと転換させているのである。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-34c97d4e-f442-80a4-8525-cdaa189e94c8-18abafde81fd7c2222bc6ee9eff53822028747e2.webp" alt=""/></div><div class="rotion-image-caption"><span class="rotion-richtext-annot rotion-richtext-default">Can AI in Japanese elementary schools serve as an instrument for expansive learning and transformative agency?  An activity-theoretical case study（2026, Yamazumi）</span></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">このように見ると、AIは確かに「道具」であるが、その影響は道具にとどまらない。AIは拡張的学習、変革的エージェンシーのための手段となり得る。AIが</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">活動の一部として組み込まれることで、活動そのものを再構成する存在</span><span class="rotion-richtext-annot rotion-richtext-default">になる。</span></p></div><div><h2 class="rotion-text rotion-text-h1" id="543431d4"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">学校は何を教えるのか</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">そして最後に、討論者のYrjö Engeström（フィンランド）が、最も根本的な問いを提示した。彼の指摘はシンプルだが重い。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">学校教育の対象とは何か</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">学校は通常公式の教科書を学校教育の対象、あるいは疑似的な対象として扱い、生徒は公式の知識内容を獲得し、内面化し、再現する。これが伝統的な学校教育の組織化の仕方である。また、それは試験によって完結し、評価につながる。これは、学校の教科書が世界を理解するための手段ではなく、それ自体が目的化していることを意味する。この構造が変わらない限り、デジタル化してもAIを導入しても本質的な問題は解決しない。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">学校はAIの登場によって生徒がアクセスできる教科書以外の知識や情報の源と競争しなければならなくなっている。AIやインターネット、ソーシャルメディアが与える情報や知識、娯楽が学習者の生活においてますます強力な存在感を示しているという事実によって緊張関係を悪化させている。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">そして彼は、次のような問いを投げかける。</span></p></div><div><ul class="rotion-listblocks rotion-list-ul"><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">AIは現実世界を対象とする学びを可能にするのか</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">それとも既存の教育を補強するだけなのか</span></li></ul></div><div><h2 class="rotion-text rotion-text-h1" id="861d1881"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">まとめ</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">本シンポジウムで特に印象的だったのは、AIをめぐる議論が単一の専門領域に収まるものではなく、教育、情報技術、経済、社会、さらには価値や民主主義といった多様な視点が交差する問題として立ち現れていたことである。こうした状況において重要になるのは、それぞれの分野を分断したまま扱うのではなく、相互の関係性（そこにある矛盾）の中で捉え直す枠組みである。Engeström教授が指摘するように、学校教育はしばしば「世界」ではなく「教科書」を対象としてきたが、AIの登場はこの前提そのものを問い直す契機となっている。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">CHATは異なる立場や実践を結びつけ、学習の対象（object）を再定義しながら学校という活動システム全体を変革していくための理論的基盤となり得る。AIは単なる技術ではなく、こうした横断的対話と再設計を促す媒介であり、</span><a class="rotion-richtext-link" href="https://iscar.org/" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">ISCAR</span></a><span class="rotion-richtext-annot rotion-richtext-default">はその国際的な議論を牽引する中心的な場として、今後ますます重要な役割を担うだろう。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">また、ISCARでは日本も参加する東アジア地域部会が新たにスタートすることが予定されている。拡張的学習理論やCHATを深く学び、日本の教育を幅広い視点から問い直していく機会として、ぜひ様々な領域の研究者や実践者に参画いただきたい。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">入会についての問い合わせは朝倉（</span><span class="rotion-richtext-annot rotion-richtext-default">m-asakura [at] sakura.ad.jp</span><span class="rotion-richtext-annot rotion-richtext-default">）まで。</span></p></div></div>]]></content:encoded>
            <author>さくらインターネット研究所</author>
        </item>
        <item>
            <title><![CDATA[東京大学工学部計数工学科での特別講義を実施しました]]></title>
            <link>https://research.sakura.ad.jp/blog/u-tokyo-keisuu</link>
            <guid isPermaLink="false">https://research.sakura.ad.jp/blog/u-tokyo-keisuu</guid>
            <pubDate>Tue, 21 Apr 2026 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<div class="rotion-blocks"><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">こんにちは、さくらインターネット研究所の菊地です。<br /><br />2026/4/14(火)に、東京大学の工学部計数工学科で、計数工学特別講義というものを担当させて頂く機会がありました。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default"><br />105分という比較的長丁場の時間でしたが、データセンター業界の状況とさくらインターネットの取り組み、またさくらインターネット研究所の研究テーマの紹介、また今旬のネタとして、ワットビット連携関連、エッジコンピューティング(フィジカルAI)、さくらのスーパーコンピュータ(さくらONE)などについてお話させていただきました。学生さんたちにとって興味深い話になったかな？</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">講義資料を公開いたします。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">さくらインターネット研究所ではこの様な出張講義なども可能な範囲で受け付けておりますので、ご要望があれば随時どうぞ。</span></p></div><div><div class="rotion-embed"><div class="rotion-embed-speakerdeck"><div class="rotion-embed-html"><iframe id="talk_frame_1531538" class="speakerdeck-iframe" src="https://speakerdeck.com/player/88b4bf8530ed48e29e098d97704ae038" width="710" height="502" style="aspect-ratio:710/502; border:0; padding:0; margin:0; background:transparent;" frameborder="0" allowtransparency="true" allowfullscreen="allowfullscreen"></iframe> </div><div class="rotion-embed-caption"></div></div></div></div><div><p class="rotion-text rotion-text-p"></p></div></div>]]></content:encoded>
            <author>さくらインターネット研究所</author>
        </item>
        <item>
            <title><![CDATA[スマートIoT推進フォーラム 第18回テストベッド分科会の発表資料の公開]]></title>
            <link>https://research.sakura.ad.jp/blog/testbed18-jgn</link>
            <guid isPermaLink="false">https://research.sakura.ad.jp/blog/testbed18-jgn</guid>
            <pubDate>Wed, 11 Mar 2026 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<div class="rotion-blocks"><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">こんにちは、さくらインターネット研究所の菊地です。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">2026年3月10日(火)に開催されました、スマートIoT推進フォーラム</span><a class="rotion-richtext-link" href="https://testbed.nict.go.jp/bunkakai/index3.html" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">第18回テストベッド分科会</span></a><span class="rotion-richtext-annot rotion-richtext-default">にて、「データセンター事業者を取り巻く近年の状況とその中での研究開発動向、テストベッドへの貢献の可能性」というタイトルで発表しました。</span></p></div><div><p class="rotion-text rotion-text-p"></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">発表資料を以下に公開いたします。<br />データセンター事業者としてのさくらインターネットの取り組み(AIに向けた取り組み、ワットビット対応)、研究所と研究テーマの紹介、JGNおよびテストベッドとのかかわりなどについて述べています。ご覧ください。</span></p></div><div><div class="rotion-embed"><div class="rotion-embed-speakerdeck"><div class="rotion-embed-html"><iframe id="talk_frame_1515448" class="speakerdeck-iframe" src="https://speakerdeck.com/player/ec6a859372c94f61bf2170881694e5b5" width="710" height="399" style="aspect-ratio:710/399; border:0; padding:0; margin:0; background:transparent;" frameborder="0" allowtransparency="true" allowfullscreen="allowfullscreen"></iframe> </div><div class="rotion-embed-caption"></div></div></div></div><div><p class="rotion-text rotion-text-p"></p></div></div>]]></content:encoded>
            <author>さくらインターネット研究所</author>
        </item>
        <item>
            <title><![CDATA[ACM/IFIP Middlewareの併設ワークショップMid4ccでWasmのチェックポイント・レストアについて発表しました]]></title>
            <link>https://research.sakura.ad.jp/blog/mid4cc</link>
            <guid isPermaLink="false">https://research.sakura.ad.jp/blog/mid4cc</guid>
            <pubDate>Thu, 25 Dec 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<link rel="preload" as="image" href="/images/block-2d397d4e-f442-80fd-8411-fbb60186f05f-c3865243587ae778480a3349a2d57cf69004a5ad.webp"/><link rel="preload" as="image" href="/images/block-2d397d4e-f442-80c6-98e9-db6d009a66f9-7e9d6195e7aecaf4ea36336b96282442645b6050.webp"/><div class="rotion-blocks"><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">研究所の中田 (</span><a class="rotion-richtext-link" href="https://x.com/chiku_wait" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">@chiku_wait</span></a><span class="rotion-richtext-annot rotion-richtext-default">)です。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">2025年12月15日から19日にかけて、アメリカのナッシュビルで開催された国際会議26th ACM/IFIP International Middleware Conference（Middleware）の併設ワークショップ、3rd International Workshop on Middleware for the Computing Continuum (Mid4CC 25)で自身の研究について発表しました。</span></p></div><div><p class="rotion-text rotion-text-p"></p></div><div><h3 class="rotion-text rotion-text-h2" id="d3ede63c"><span class="rotion-richtext-annot rotion-richtext-default">Middleware/mid4cc</span></h3></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">Middlewareは、クラウド・エッジ・分散システムのためのミドルウェアや、ミドルウェアの設計・プログラミング原則・フォールトトレランスなどを対象としたミドルウェアに関する国際会議です。学術系国際会議の格付けである</span><a class="rotion-richtext-link" href="https://www.core.edu.au/icore-portal" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Core Rank</span></a><span class="rotion-richtext-annot rotion-richtext-default">によると、A（上位14%）に位置づけられており、この分野における有力な難関国際会議といえます。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">mid4ccは、Middlewareに併設されたワークショップであり、エッジやクラウドなど、異なる特性のコンピューティングプラットフォームをシームレスに連携させるためのミドルウェアを主に扱っています。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">会場のヴァンダービルト大学に、世界中から100人程度の研究者が集まり、興味深い発表と活発な議論が行われました。</span></p></div><div><p class="rotion-text rotion-text-p"></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-2d397d4e-f442-80fd-8411-fbb60186f05f-c3865243587ae778480a3349a2d57cf69004a5ad.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><h3 class="rotion-text rotion-text-h2" id="5908b310"><span class="rotion-richtext-annot rotion-richtext-default">発表内容</span></h3></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">この研究は、Wasmランタイム間での効率的なチェックポイント・レストアにセルフホストWasmランタイム（WasmにコンパイルされたWasmランタイム）を活用するものです。Wasmランタイムには特性の異なる多様な実装があり、クラウドやエッジ、組み込みデバイスなど、それぞれの計算機環境の制約やユースケースに適したランタイムがあります。これらのランタイム間でチェックポイント・レストアが可能になると、ステートフルなアプリケーションのライブマイグレーションによるオフローディングやハンドオフが実現できます。一方、ランタイム間で実装や性能最適化手法が異なることで実行状態の互換性がなく、そのままではチェックポイント・レストアを実現できません。この研究では、軽量でコンパクトなセルフホストWasmランタイムをランタイム中立な内部実行状態表現として活用し、ランタイム中立なチェックポイント・レストアを実現しています。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">論文：</span><a class="rotion-richtext-link" href="https://dl.acm.org/doi/10.1145/3774898.3778040" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge-Cloud Continuum</span></a></p></div><div><div class="rotion-embed"><div class="rotion-embed-speakerdeck"><div class="rotion-embed-html"><iframe id="talk_frame_1479847" class="speakerdeck-iframe" src="https://speakerdeck.com/player/811f6adf7f634ddc8b1d6ead5602f24e" width="710" height="399" style="aspect-ratio:710/399; border:0; padding:0; margin:0; background:transparent;" frameborder="0" allowtransparency="true" allowfullscreen="allowfullscreen"></iframe> </div><div class="rotion-embed-caption"></div></div></div></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-2d397d4e-f442-80c6-98e9-db6d009a66f9-7e9d6195e7aecaf4ea36336b96282442645b6050.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><h3 class="rotion-text rotion-text-h2" id="2bfb90ad"><span class="rotion-richtext-annot rotion-richtext-default">おわりに</span></h3></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">難関国際会議の併設ワークショップということもあり、メインシンポジウムとワークショップ双方で非常に興味深い発表を聞くことができ、研究に関するモチベーションが更にアップしました。また、活発な質疑応答によって今後の研究のアイデアや改善の種を得られたので、研究をよりブラッシュアップさせ、一流国際会議やジャーナルに挑戦したいと思います。</span></p></div><div><p class="rotion-text rotion-text-p"></p></div></div>]]></content:encoded>
            <author>さくらインターネット研究所</author>
        </item>
        <item>
            <title><![CDATA[NeurIPS 2025招待講演：「異質な知能」としてのAI — 認知能力を評価する6つの原則]]></title>
            <link>https://research.sakura.ad.jp/blog/neurips2025-invited-talk-alien-intelligences</link>
            <guid isPermaLink="false">https://research.sakura.ad.jp/blog/neurips2025-invited-talk-alien-intelligences</guid>
            <pubDate>Wed, 24 Dec 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<link rel="preload" as="image" href="/images/block-2d197d4e-f442-8063-813a-da841724e740-51dede80f802b71a28f9f749debe1be99deee57e.webp"/><link rel="preload" as="image" href="/images/block-2d197d4e-f442-8095-9b8b-e43cb4aef3c8-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp"/><link rel="preload" as="image" href="/images/block-2d197d4e-f442-808a-b33b-e75f152327e7-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp"/><link rel="preload" as="image" href="/images/block-2d197d4e-f442-8075-ab8f-fee5537f016e-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp"/><link rel="preload" as="image" href="/images/block-2d197d4e-f442-8079-96ec-c532a3d56fb5-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp"/><link rel="preload" as="image" href="/images/block-2d197d4e-f442-8007-ba58-c8db276b41a1-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp"/><link rel="preload" as="image" href="/images/block-2d197d4e-f442-80d4-b9d4-d11d98c493dc-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp"/><div class="rotion-blocks"><div><h2 class="rotion-text rotion-text-h1" id="136c4770"><span class="rotion-richtext-annot rotion-richtext-default">はじめに</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">さくらインターネット研究所の鶴田（</span><a class="rotion-richtext-link" href="https://twitter.com/tsurubee3" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">@tsurubee3</span></a><span class="rotion-richtext-annot rotion-richtext-default">）です。2025年12月にサンディエゴで開催されたNeurIPS 2025に参加してきました。本記事では、サンタフェ研究所のMelanie Mitchell氏による招待講演「</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">On the Science of "Alien Intelligences": Evaluating Cognitive Capabilities in Babies, Animals, and AI</span><span class="rotion-richtext-annot rotion-richtext-default">」の内容を紹介します。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">近年、大規模言語モデル（LLM）は多くのベンチマークで人間を超えるスコアを達成しています。しかし、その高い精度は本当に「知性」や「理解」を示しているのでしょうか。Mitchell氏は、AIの認知能力評価における根本的な問題を提起し、発達心理学や比較認知科学の知見を踏まえた、より厳密な評価のための6つの原則を示しました。非常に示唆に富んだ講演でしたので、本記事ではその要点を共有します。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-2d197d4e-f442-8063-813a-da841724e740-51dede80f802b71a28f9f749debe1be99deee57e.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><h2 class="rotion-text rotion-text-h1" id="e33eca0c"><span class="rotion-richtext-annot rotion-richtext-default">エイリアン・インテリジェンスとは</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">講演タイトルにある「エイリアン・インテリジェンス（Alien Intelligence：異質な知能）」とは、人間とは異なる形で知性を持つ存在を指す概念です。本講演の冒頭では、Terry Sejnowski氏の論文「</span><a class="rotion-richtext-link" href="https://arxiv.org/abs/2207.14382" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Large Language Models and the Reverse Turing Test</span></a><span class="rotion-richtext-annot rotion-richtext-default"> (2022)」から以下の一節が引用され、LLMの知性の本質についての疑問が投げかけられました。</span></p></div><div><blockquote class="rotion-text rotion-text-quote"><span class="rotion-richtext-annot rotion-richtext-default">ほんの数年前には予想もされていなかったことが起こり始めている。あたかも、不気味なほど人間的な方法でコミュニケーションができる宇宙人（エイリアン）が突然現れたかのようだ。ただ一つ明らかなのは、LLMは人間ではないということだ。しかし世界中のテキストデータベースから情報を抽出する能力においては超人的である。</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">その行動の一端は知的に見えるが、もしそれが人間の知性ではないなら、その知性の本質とは何なのか？</span></blockquote></div><div><h2 class="rotion-text rotion-text-h1" id="65d985f1"><span class="rotion-richtext-annot rotion-richtext-default">ベンチマークの問題点</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">Mitchell氏はまず、今日の生成AIシステムが多くのベンチマークで人間のパフォーマンスを超えている一方で、実世界のタスクにおいては依然として人間とは異なる形で苦戦していることを指摘しました。この背景には、現在のAI評価手法には以下のような深刻な問題があります。</span></p></div><div><ul class="rotion-listblocks rotion-list-ul"><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">データ汚染</span><span class="rotion-richtext-annot rotion-richtext-default">：学習データにテストデータの内容が含まれている。</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">近似的な検索</span><span class="rotion-richtext-annot rotion-richtext-default">：真の理解ではなく、検索やパターンマッチングに近い形で回答している。</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">疑似相関の利用</span><span class="rotion-richtext-annot rotion-richtext-default">：表面的な相関をショートカットとして利用して回答している。</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">一貫性・頑健性・汎化性の欠如</span><span class="rotion-richtext-annot rotion-richtext-default">：これらを検証するテストが不足している。</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">構成概念妥当性の欠如</span><span class="rotion-richtext-annot rotion-richtext-default">：測定しようとしている概念や特性を正しく測定できていない。</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">擬人化（anthropomorphism）の問題</span><span class="rotion-richtext-annot rotion-richtext-default">：人間向けテストの前提条件がAIシステムには当てはまらない。</span></li></ul></div><div><h2 class="rotion-text rotion-text-h1" id="60e40f68"><span class="rotion-richtext-annot rotion-richtext-default">発達心理学・比較認知科学からの知見</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">講演の核心は、発達心理学や比較認知科学からの知見の応用です。Mitchell氏はMichael Frank氏の論文「</span><a class="rotion-richtext-link" href="https://www.nature.com/articles/s44159-023-00211-x" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Baby steps in evaluating the capacities of large language models</span></a><span class="rotion-richtext-annot rotion-richtext-default"> (2023)」ら以下の一節を引用しました。</span></p></div><div><blockquote class="rotion-text rotion-text-quote"><span class="rotion-richtext-annot rotion-richtext-default">エイリアン・インテリジェンスとの初めての接触を想像してみてください。科学者はこう問うかもしれません。エイリアンは人間と同じ概念を持っているのか？他者の心を理解できるのか？因果関係を推論できるのか？こうしたシナリオはSF作品でよく見られる。そしてここ数年、大規模言語モデル（LLM）との対話においても同様だ。しかし発達心理学者は長年、別のエイリアン・インテリジェンス、つまり人間の子どもについて同じ疑問を投げかけてきた。この研究の手法は、LLMの能力を探る上で研究者に役に立つだろう。</span></blockquote></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">発達心理学者や比較認知科学者は、長年にわたり人間の乳幼児という、ある意味での「エイリアン・インテリジェンス」を研究対象としてきました。Mitchell氏は、これらの分野で培われた知見がAIの認知能力評価にも応用できると主張しています。</span></p></div><div><h2 class="rotion-text rotion-text-h1" id="60c13bf6"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">認知能力をより厳密に評価するための6つの原則</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">講演では、AIの認知能力をより厳密に評価するための「6つの原則」が提示されました。</span></p></div><div><h3 class="rotion-text rotion-text-h2" id="c6b10570"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">1. 擬人化への認知バイアスを自覚する</span></h3></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">講演中では例として、赤ちゃんが笑ったとき、人間は喜んでいると解釈するが、猿は恐怖やストレスを感じたときに笑ったような表情（Fear grimaceと呼ばれる）を示すことが挙げられました。それでは、AIが組み込まれたロボットが笑ったときはどう解釈すべきでしょうか。この例は、AIが人間と同じように感じたり考えたりしていると安易に思い込まないよう注意を促しています。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-2d197d4e-f442-8095-9b8b-e43cb4aef3c8-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><h3 class="rotion-text rotion-text-h2" id="fc4f1624"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">2. 仮説を疑う</span></h3></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">観察された行動を生み出しうる代替戦略（暗記やショートカット）を考慮し、それらに対する統制を設計すべきです。これについては、乳児の道徳的な推論に関する論文「</span><a class="rotion-richtext-link" href="https://www.nature.com/articles/nature06288" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Social evaluation by preverbal infants</span></a><span class="rotion-richtext-annot rotion-richtext-default"> (2007)」から非常にユニークな事例が紹介されました。この研究では、生後6〜10ヶ月の乳児に以下に示す2種類のアニメーション動画を見せます。左側がHelperシナリオで、赤い丸のキャラクターが坂を登ろうとするのを黄色い三角のキャラクターが後ろから押して助け、無事に坂を登りきります。一方、右側がHindererシナリオで、赤い丸のキャラクターが坂を登ろうとするのを青い四角のキャラクターが上から押し戻して邪魔をし、坂を登れません。この2種類の動画を見せた後、乳児にどちらのキャラクターがより好きかを選んでもらいます。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-2d197d4e-f442-808a-b33b-e75f152327e7-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-italic">出典：「</span><a class="rotion-richtext-link" href="https://www.nature.com/articles/nature06288" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-italic">Social evaluation by preverbal infants</span></a><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-italic">」のFigure 1</span></p></div><div><p class="rotion-text rotion-text-p"></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">その結果、乳児は有意にHinderer（青い四角）よりもHelper（黄色い三角）を選びました。この論文では、乳児はキャラクターの社会的行動に基づいて他者を評価しており、道徳の概念を持っていると主張しています。しかし、後続研究の論文「</span><a class="rotion-richtext-link" href="https://journals.plos.org/plosone/article?id=10.1371%2Fjournal.pone.0042698" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Social Evaluation or Simple Association? Simple Associations May Explain Moral Reasoning in Infants</span></a><span class="rotion-richtext-annot rotion-richtext-default"> (2012)」では、この乳児の選択は道徳的な概念ではなく、別の要因による単純な連想に起因することが示されました。実は元の動画では、Helperシナリオの場合のみ、丘の頂上まで登りきった際に赤いキャラクターが小さく小刻みにジャンプを繰り返す演出が含まれていました。そこで、Hindererシナリオでも丘を登れなかった際にキャラクターが小刻みにジャンプするよう変更したところ、Hindererを選ぶ乳児が有意に増えたのです。このように、観測される結果が本来意図していない要因によって引き起こされている可能性を常に疑う必要があります。</span></p></div><div><h3 class="rotion-text rotion-text-h2" id="eda627ef"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">3. 失敗のタイプを分析する</span></h3></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">多くの場合、失敗は成功よりも多くの洞察を与えてくれるため、ネガティブな結果を受け入れることが重要です。この点に関連して、ICML 2024で発表された論文「</span><a class="rotion-richtext-link" href="https://arxiv.org/abs/2406.03980" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Position: Embracing Negative Results in Machine Learning</span></a><span class="rotion-richtext-annot rotion-richtext-default"> (2024)」を紹介しています。この論文では、新しい機械学習手法を提案する論文が、選択された問題に対する予測性能のみで評価されがちな現状に警鐘を鳴らしています。著者らは、予測性能だけでは論文の価値を測る良い指標にはならないと主張しています。むしろ、予測性能のみを重視することは、機械学習研究コミュニティ全体の非効率性を助長し、研究者に誤ったインセンティブを与える問題を引き起こすと指摘しています。そこで著者らは「ネガティブな結果」の発表を呼びかけており、これによりこれらの問題の一部が緩和され、機械学習研究コミュニティの科学的成果が向上すると論じています。</span></p></div><div><h3 class="rotion-text rotion-text-h2" id="4c461417"><span class="rotion-richtext-annot rotion-richtext-default">4. 頑健性と汎化性をテストするための</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">バリエーションを設計する</span></h3></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">この原則については、文字列の類推問題（letter-string analogy problems）が例に用いられました。文字列の類推問題とは、例えば「a b c d → a b c e」と与えられたときに「i j k l → ?」の答えを推論する（この場合、最後の文字を一つ進めて「i j k m」と答える）というような問題です。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">2023年に発表された論文「</span><a class="rotion-richtext-link" href="https://www.nature.com/articles/s41562-023-01659-w" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Emergent analogical reasoning in large language models</span></a><span class="rotion-richtext-annot rotion-richtext-default"> (2023)」では、文字列の類推問題においてGPT-3が人間を凌駕するスコアを達成したと報告されました。しかし、このようなLLMの文字列推論は本当に頑健なのでしょうか。この疑問を検証するため、Mitchell氏は自身の研究論文「</span><a class="rotion-richtext-link" href="https://arxiv.org/abs/2411.14215" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Evaluating the Robustness of Analogical Reasoning in Large Language Models</span></a><span class="rotion-richtext-annot rotion-richtext-default"> (2024)」を紹介しました。<br />本論文の実験では、元の類推問題の変種に対する頑健性を人間とGPTモデルで比較しています。具体的には、「a b c d」のような通常のアルファベット順の中でn個の文字の位置をランダムに入れ替えて再配置したアルファベットを用いた場合と、文字の代わりに非文字記号（non-letter symbols）を特定の順序で並べたものを用いた場合について、人間とLLMの類推精度を比較しました。その結果を以下の図に示します。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-2d197d4e-f442-8075-ab8f-fee5537f016e-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-italic">出典：「</span><a class="rotion-richtext-link" href="https://arxiv.org/abs/2411.14215" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Evaluating the Robustness of Analogical Reasoning in Large Language Models</span></a><span class="rotion-richtext-annot rotion-richtext-default">」</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-italic">のFigure 4</span></p></div><div><p class="rotion-text rotion-text-p"></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">これらの変種問題は同じ抽象的推論能力をテストするものであり、真に類推能力を持っているならば、性能が著しく低下すべきではありません。しかし結果を見ると、人間は2種類の変種問題のいずれでも高い性能を維持している一方、GPTモデルの性能は急激に低下し、特に記号を用いた場合には著しく低下することが判明しました。このことは、LLMが人間の類推能力のような頑健性を欠いていることを示しており、AIシステムの認知能力を評価する際には精度だけでなく頑健性も慎重に検証すべきであることを示唆しています。</span></p></div><div><h3 class="rotion-text rotion-text-h2" id="ad26e632"><span class="rotion-richtext-annot rotion-richtext-default">5. CompetenceとPerformanceを区別する</span></h3></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">CompetenceとPerformanceは心理学や言語学でよく用いられる概念で、Competenceは「潜在的な知識・能力」を、Performanceは「その知識・能力を実際の状況で使った結果」を指します。システムがある能力（Competence）を持っていても、それを実際の状況で実行（Performance）できるとは限らず、逆もまた然りです。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">この原則については、LLMの抽象化と推論能力を評価するためのAbstraction and Reasoning Corpus（ARC）が例に用いられました。ARCは、オブジェクト性、単純な幾何学と位相、基本的な数といった「コア知識」に基づいて手動で作成された1,000のタスクが含まれています。例えば、以下のようなタスクです。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-2d197d4e-f442-8079-96ec-c532a3d56fb5-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-italic">出典：「</span><a class="rotion-richtext-link" href="https://arxiv.org/abs/1911.01547" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-italic">On the Measure of Intelligence</span></a><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-italic"> (2019)</span><span class="rotion-richtext-annot rotion-richtext-default">」</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-italic">のFigure 8</span></p></div><div><p class="rotion-text rotion-text-p"></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">このタスクでは、水色のピクセルの延長線が赤い障害物に接触すると「跳ね返る」というルールを外挿して解くものになっています。これらのタスクに対する人間の精度は64%程度であり、LLMはこれを超えられずにいました。しかし2024年、OpenAIのo3モデルがブレイクスルーを起こし、驚異の88%という精度を叩き出しました。<br />ここでMitchell氏はある疑問を投げかけました。これらのモデルは、意図された「コア知識」の抽象化をどの程度把握しているのか？それとも、これらの課題を解決するために「異質な」推論方法を用いているのか？</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">この疑問を検証した論文「</span><a class="rotion-richtext-link" href="https://neurips.cc/virtual/2025/loc/san-diego/136968" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Investigating Abstraction Capabilities of the o3 Model Using Textual and Visual Modalities</span></a><span class="rotion-richtext-annot rotion-richtext-default"> (2025)」が、NeurIPS 2025のMultimodal Algorithmic Reasoning Workshopで発表されています。この論文はMitchell氏自身も共著者として参加しており、ARCを単純化したConceptARCベンチマークを用いてo3モデルの抽象化能力を評価しています。<br />実験では、o3に出力グリッドだけでなく、変換ルールを自然言語で説明させました。そして、生成されたルールを「correct-intended（タスク作成者が意図した抽象化を捉えている）」「correct-unintended（正しく機能するが、意図した抽象化を捉えていない）」「incorrect（誤り）」の3つに分類しました。以下の図はその結果を示しています。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-2d197d4e-f442-8007-ba58-c8db276b41a1-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-italic">出典：「</span><a class="rotion-richtext-link" href="https://neurips.cc/virtual/2025/loc/san-diego/136968" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-italic">Investigating Abstraction Capabilities of the o3 Model Using Textual and Visual Modalities</span></a><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-italic"> (2025)」のFigure 2</span></p></div><div><p class="rotion-text rotion-text-p"></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">この実験では、入力モダリティ（テキスト形式か画像形式か）とReasoning effort（lowかmediumか）を変えて評価が行われました。テキスト入力・medium設定において、o3は出力グリッドの精度では人間に匹敵する性能を示しました。しかし、正解した出力のうち約28%は、correct-unintendedまたはincorrectなルールに基づいていることが判明しました。つまり、意図された抽象概念ではなく、表面的なパターンに基づいた推論で正解を導き出していたのです。一方、人間が生成したルールの約90%はcorrect-intendedでした。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">テキスト形式では色が数値（例：黒=0、青=1、赤=2）でエンコードされているため、o3モデルの変換ルールはオブジェクトの形状ではなく、数値比較をショートカットとして利用するケースが見られました。correct-unintendedの具体例として、以下の図のTask 2を見てみましょう。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-2d197d4e-f442-80d4-b9d4-d11d98c493dc-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-italic">出典：「</span><a class="rotion-richtext-link" href="https://neurips.cc/virtual/2025/loc/san-diego/136968" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-italic">Investigating Abstraction Capabilities of the o3 Model Using Textual and Visual Modalities</span></a><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-italic"> (2025)」のFigure 1</span></p></div><div><p class="rotion-text rotion-text-p"></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">Task 2において、意図された変換ルールは次の通りです。「入力グリッドには、特定のパターンの中に場違いな図形が含まれている。出力グリッドはこの図形であり、寸法と色をコピーするが、入力グリッドに含まれる元のパターンはコピーしない。」これに対し、o3が生成した変換ルールは次の通りでした。「入力グリッド内で最も高い非ゼロの色値を持つセルをすべて含む最小の長方形を切り取る。この長方形の内側ではその色を保持し、他のすべてのセルを0（黒）に変換する。その長方形を出力する。」<br />o3のルールは、与えられたデモンストレーションに対しては正しく機能しますが、「場違いな図形を抽出する」という意図された抽象化を捉えておらず、代わりに「最も高い色値」という数値的なショートカットに依存しています。このため、本実験ではcorrect-unintendedと分類されました。<br />これらの結果は、AIシステムの認知能力を評価する際には、単純な精度だけでなく、頑健性やシステムが汎化可能なメカニズムを使用しているかどうかを評価することの重要性を浮き彫りにしています。</span></p></div><div><h3 class="rotion-text rotion-text-h2" id="86c8651b"><span class="rotion-richtext-annot rotion-richtext-default">6. 他者の成果を再現し発展させる</span></h3></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">先行研究を再現して異なる結果を得たり、少しだけ実験条件を変えて同じような結果を得たりした成果を学会に投稿すると、査読者から「新規性がない」と指摘されるかもしれません。しかし、優れた科学の特徴は、先行研究の再現とその「漸進的」な発展にあります。Mitchell氏は、このような研究に対してコミュニティがより価値を認めるようになることを望んでいると述べています。<br />実際に、本講演で紹介された研究事例も、先行研究の結果を疑い、異なる実験条件で検証したものばかりです。乳児の道徳的推論に関する研究では、元の実験の動画に含まれていた小刻みなジャンプという交絡要因を特定しました。文字列の類推問題では、アルファベットの順序を入れ替えたり記号に置き換えたりすることで、LLMの頑健性の欠如を明らかにしました。そしてARCベンチマークにおけるo3モデルの評価では、出力の正解・不正解だけでなく生成されたルールの質を分析することで、高い精度の裏に隠れたショートカット的推論を浮き彫りにしました。これらはいずれも、先行研究の追試や条件の変更を通じて、新たな洞察を得た好例といえます。</span></p></div><div><h2 class="rotion-text rotion-text-h1" id="1be0c264"><span class="rotion-richtext-annot rotion-richtext-default">精度だけでは測れない知性</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">重要なメッセージとして、Mitchell氏はベンチマークでの高い精度が、必ずしもモデルがタスク作成者の意図した抽象概念を認識し推論していることを意味しないと強調しました。精度だけでは、表面的な特徴の利用やショートカット、人間らしくない推論を覆い隠してしまう可能性があります。人間とAIの「理解」の整合性についての洞察は、これらのシステムが人間世界でどのように能力を汎化させるかを予測するために不可欠です。</span></p></div><div><h2 class="rotion-text rotion-text-h1" id="822b8d63"><span class="rotion-richtext-annot rotion-richtext-default">AIに求められる性質の二面性</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">また、Mitchell氏はAIシステムに人間と同じような推論が求められるかどうかは文脈によって異なることも指摘しました。AIシステムに求められる思考の在り方には二面性があります。</span></p></div><div><ul class="rotion-listblocks rotion-list-ul"><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">人間とは異なる思考が求められるケース</span><span class="rotion-richtext-annot rotion-richtext-default">：AlphaFoldがタンパク質・DNA・RNAの立体構造を予測し、データから新しいパターンを見出すような場面。</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">人間と同じ世界理解が求められるケース</span><span class="rotion-richtext-annot rotion-richtext-default">：自動運転車が、看板に描かれた一時停止標識の画像を本物の標識と誤認して急ブレーキをかけてしまうような、人間世界での安全性が問われる場面。</span></li></ul></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">前者のように、AIシステムに人間とは異なる思考を期待する場合もありますが、後者のように人間社会で共生するシステムには、人間と同じように世界を理解することが求められます。人間とAIの「理解」がどれだけ一致しているかを知ることは、AIシステムが人間世界でどのように振る舞うかを予測するために不可欠です。</span></p></div><div><h2 class="rotion-text rotion-text-h1" id="776c33a2"><span class="rotion-richtext-annot rotion-richtext-default">より厳密な評価手法の必要性</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">結論として、Mitchell氏は動物、子ども、そして機械といった「エイリアン・インテリジェンス」の本質を見極めるには、相当な厳密さと創造性が必要であると述べました。私たちはAI評価においてもっとそのような厳密さと創造性を必要としており、現在必要なのはより難易度の高いベンチマークを作ることではなく、本講演で紹介した原則に基づいた、より厳密な評価手法を確立することなのだと締めくくりました。</span></p></div><div><h2 class="rotion-text rotion-text-h1" id="3ba57bac"><span class="rotion-richtext-annot rotion-richtext-default">まとめ</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">本講演を通じてMitchell氏は、AIがベンチマークで示す「高い精度」が、必ずしも人間のような「真の理解」を意味しないことを浮き彫りにしました。この課題に対処するため、発達心理学や比較認知科学の知見を応用した6つの原則が提示されました。これらの原則は、AIが「正解を出せるか」ではなく「どのように正解に至ったか」を問う姿勢の重要性を示しています。AIが科学の進歩に寄与する「異質な思考」を持つ一方で、人間社会で安全に機能するためには、私たちの世界理解と整合する頑健な汎化能力が欠かせません。精度という指標の先にある「知性の本質」を多角的に検証し続ける姿勢こそが、これからのAI研究においてますます重要になっていくのではないかと思いました。</span></p></div><div><p class="rotion-text rotion-text-p"></p></div></div>]]></content:encoded>
            <author>さくらインターネット研究所</author>
        </item>
        <item>
            <title><![CDATA[WasmCon North America 2025でセルフホストWasmランタイムに関して発表しました]]></title>
            <link>https://research.sakura.ad.jp/blog/wasmcon-na-2025</link>
            <guid isPermaLink="false">https://research.sakura.ad.jp/blog/wasmcon-na-2025</guid>
            <pubDate>Wed, 24 Dec 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<link rel="preload" as="image" href="/images/block-2d197d4e-f442-8052-84c7-ffd4519c56dc-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp"/><link rel="preload" as="image" href="/images/block-2d197d4e-f442-8044-b070-ecc197770fff-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp"/><link rel="preload" as="image" href="/images/block-2d197d4e-f442-804a-8252-ce300fde206d-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp"/><link rel="preload" as="image" href="/images/block-2d197d4e-f442-8017-9873-de770bbe1cf5-14ef4a20a14ffd7bcc4968ed27c6a87876735e62.webp"/><div class="rotion-blocks"><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">研究所の中田 (</span><a class="rotion-richtext-link" href="https://x.com/chiku_wait" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">@chiku_wait</span></a><span class="rotion-richtext-annot rotion-richtext-default">)です。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">2025年11月にアメリカのアトランタで開催されたWasmCon North America 2025にて、自身の研究の一つを発表しました。</span></p></div><div><h2 class="rotion-text rotion-text-h1" id="d1154a45"><span class="rotion-richtext-annot rotion-richtext-default">WasmConとは</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">WasmConは、クラウドネイティブ技術に関する最大の技術カンファレンスであるKubeCon + CloudNativeCon North Americaの併設イベントで、WebAssembly（Wasm）に関する内容に特化しています。Wasmの標準化やWasm関連のOSS、Wasmに関するハックなど多くの有用な情報や最新動向が共有されるイベントです。WasmConは、KubeConや他の併設イベントと同様に、プロポーザルの質やオリジナリティ、エコシステムへの貢献などの項目で内容をレビューされ、発表の採録・不採録が決定されます。</span></p></div><div><h2 class="rotion-text rotion-text-h1" id="4ff59099"><span class="rotion-richtext-annot rotion-richtext-default">発表内容</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">私が研究開発用に実装している、セルフホストに特化したWasmランタイム（</span><a class="rotion-richtext-link" href="https://github.com/oss-fun/chiwawa" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">https://github.com/oss-fun/chiwawa</span></a><span class="rotion-richtext-annot rotion-richtext-default">）について発表をしました。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">セルフホストWasmランタイムは、軽量でコンパクトなWasmランタイムをWasmにコンパイルし、任意のWasmランタイム上で実行することで互換レイヤーとして様々な機能拡張や検証に活用できるものです。元々はランタイム中立なライブマイグレーションのために実装していましたが、今回の発表ではより汎用的な機能拡張機構としてユースケースを検討し、その有用性を議論するものとなっています。</span></p></div><div><div class="rotion-embed"><div class="rotion-embed-speakerdeck"><div class="rotion-embed-html"><iframe id="talk_frame_1465252" class="speakerdeck-iframe" src="https://speakerdeck.com/player/705448317da9456ca9d25772694ec55a" width="710" height="399" style="aspect-ratio:710/399; border:0; padding:0; margin:0; background:transparent;" frameborder="0" allowtransparency="true" allowfullscreen="allowfullscreen"></iframe> </div><div class="rotion-embed-caption"></div></div></div></div><div><h3 class="rotion-text rotion-text-h2" id="a19f45f0"><span class="rotion-richtext-annot rotion-richtext-default">発表の様子 (Photo by </span><a class="rotion-richtext-link" href="https://x.com/amsy810" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">@amsy810</span></a><span class="rotion-richtext-annot rotion-richtext-default">氏) </span></h3></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-2d197d4e-f442-8052-84c7-ffd4519c56dc-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-2d197d4e-f442-8044-b070-ecc197770fff-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><h2 class="rotion-text rotion-text-h1" id="57ebabd4"><span class="rotion-richtext-annot rotion-richtext-default">おわりに</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">自身の研究について、学術コミュニティだけではなく業界のカンファレンスで発表することは、実用的なソフトウェアという観点で自身の研究を見直すきっかけとなりました。発表者や運営メンバーは、Wasm/WASIの標準化に関わっている方やWasm向けOSSの作者なども多く、ソフトウェアとしての実用性や有用性を議論できるのは非常に有意義でエキサイティングでした。また、偶然にも自身の研究で大いに参考としている研究のPhD学生が発表しており、Wasm関連の研究をしている者同士で研究に関して深い議論をするなど、思わぬ出会いもありました。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">今後も学術的な新規性と、ソフトウェアとしての有用性やOSSコミュニティへの貢献を両立する研究開発を目指していきます。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-2d197d4e-f442-804a-8252-ce300fde206d-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-2d197d4e-f442-8017-9873-de770bbe1cf5-14ef4a20a14ffd7bcc4968ed27c6a87876735e62.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div></div>]]></content:encoded>
            <author>さくらインターネット研究所</author>
        </item>
        <item>
            <title><![CDATA[NeurIPS 2025参加レポート：新設のPosition Paper TrackとAI4Mat Workshopでの発表]]></title>
            <link>https://research.sakura.ad.jp/blog/neurips2025-report</link>
            <guid isPermaLink="false">https://research.sakura.ad.jp/blog/neurips2025-report</guid>
            <pubDate>Mon, 22 Dec 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<link rel="preload" as="image" href="/images/block-2d197d4e-f442-8084-b189-d41b1e1cd639-d32e1bb03831661018657c682f04871c54aa7316.webp"/><link rel="preload" as="image" href="/images/block-2d197d4e-f442-8063-9fef-f91bdece614c-e9de07587fb4fb6d1f860cb8a36bf3066233da04.webp"/><link rel="preload" as="image" href="/images/block-2d097d4e-f442-8035-aaf2-d587b27286f5-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp"/><link rel="preload" as="image" href="/images/block-2d197d4e-f442-8044-8f2a-d20fb053d79c-e39c3dad6a6d406552a235f8fc84a72ce66edbbe.webp"/><div class="rotion-blocks"><div><h2 class="rotion-text rotion-text-h1" id="5060e48b"><span class="rotion-richtext-annot rotion-richtext-default">はじめに</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">さくらインターネット研究所の鶴田（</span><a class="rotion-richtext-link" href="https://twitter.com/tsurubee3" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">@tsurubee3</span></a><span class="rotion-richtext-annot rotion-richtext-default">）です。このたび、大規模言語モデル（LLM）を用いた実験プロセスの構造化データ抽出に関する研究論文が、AIおよび機械学習分野の最難関国際会議であるNeural Information Processing Systems (NeurIPS) 2025のAI for Accelerated Materials Discovery (AI4Mat) Workshopに採択されました。<br />Workshopは会期後半の開催でしたが、初日のメインカンファレンスから現地参加してきました。本記事では、NeurIPS 2025の概要、新設されたPosition Paper Trackの概要、そして自身のポスター発表について報告します。</span></p></div><div><h2 class="rotion-text rotion-text-h1" id="d43a48bd"><span class="rotion-richtext-annot rotion-richtext-default">NeurIPS 2025の概要</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">NeurIPS 2025は、2025年12月2日から7日にかけて、アメリカ・カリフォルニア州サンディエゴで開催されました。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-2d197d4e-f442-8084-b189-d41b1e1cd639-d32e1bb03831661018657c682f04871c54aa7316.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">会場となったSan Diego Convention Centerには世界中から研究者が集まり、Opening Remarksで発表された数字によると、バーチャル参加者を含めた参加者総数は29,124名にのぼりました。また、Main Trackへの今年の論文投稿数は21,575件、採択率は24.52%でした。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-2d197d4e-f442-8063-9fef-f91bdece614c-e9de07587fb4fb6d1f860cb8a36bf3066233da04.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><h2 class="rotion-text rotion-text-h1" id="e110d3df"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">Position Paper Trackの新設</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">NeurIPS 2025ならではの特徴の一つとして、Position Paper Trackが新設されたことが挙げられます。ICML 2024・2025に続く形での導入であり、NeurIPSとしては初めての試みとなりました。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">このトラックの重要性を語る上で欠かせないのが、近年の論文投稿プラットフォームの大きな変化です。2025年10月、arXivのコンピュータサイエンス（CS）カテゴリにおいて、</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">レビュー論文（サーベイ論文）およびPosition Paperの投稿を「ジャーナルやカンファレンスで採択・査読されたもの」に限定する</span><span class="rotion-richtext-annot rotion-richtext-default">という運用変更が発表されました。arXivという「誰でも自由に未査読のアイデアを公開できる場」で投稿要件が厳格化された今、NeurIPSという最高峰のカンファレンスで厳格な査読を勝ち抜き、「お墨付き」を得たPosition Paperを読めることの価値は、これまで以上に高まっていくと思います。</span></p></div><div><h3 class="rotion-text rotion-text-h2" id="29129085"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">Position Paperとは</span></h3></div><div><p class="rotion-text rotion-text-p"><a class="rotion-richtext-link" href="https://neurips.cc/Conferences/2025/CallForPositionPapers" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">NeurIPS 2025 Call for Position Papers</span></a><span class="rotion-richtext-annot rotion-richtext-default">によると、Position Paperは以下のような役割を担うものとされています。</span></p></div><div><blockquote class="rotion-text rotion-text-quote"><span class="rotion-richtext-annot rotion-richtext-default">Position Paperとは、すでに達成された研究成果を報告する「Research Track」の論文とは対照的に、</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">「今後何がなされるべきか」という視点や展望についての議論を展開するもの</span><span class="rotion-richtext-annot rotion-richtext-default">です。また、個別の研究領域を超えた、機械学習分野全体に対するメタレベルの視点を持つことが求められます。</span></blockquote></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">つまり、具体的なアルゴリズムの提案よりも、</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">「私たちはどこに向かうべきか」というビジョンや、現在の研究の進め方に対する提言に重きを置いたトラック</span><span class="rotion-richtext-annot rotion-richtext-default">と言えます。</span></p></div><div><h3 class="rotion-text rotion-text-h2" id="9f289b6d"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">独自の査読基準</span></h3></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">Position Paper Trackでは、査読の基準もResearch Track (Main Paper Track)とは大きく異なります。</span></p></div><div><ul class="rotion-listblocks rotion-list-ul"><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">Research Track</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">：</span><span class="rotion-richtext-annot rotion-richtext-default"> 研究の独創性や、新規性のある結果を重視</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">Position Paper Track</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">：</span><span class="rotion-richtext-annot rotion-richtext-default"> その主張が「</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">機械学習コミュニティにおいて、より広く議論されるべき説得力のある主張を提示しているかどうか</span><span class="rotion-richtext-annot rotion-richtext-default">」が最大の判断基準</span></li></ul></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">たとえ査読者がその主張に個人的に賛成できなくても、それが</span><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">コミュニティにとって有益で建設的な議論を促すものであれば高く評価</span><span class="rotion-richtext-annot rotion-richtext-default">されます。公式に「議論を呼ぶような（Controversialな）トピックも歓迎する」と明言されている点も、このトラックのユニークな特徴です。</span></p></div><div><h3 class="rotion-text rotion-text-h2" id="cba82b24"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">採択状況</span></h3></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">初開催となったPosition Paper Trackを振り返る</span><a class="rotion-richtext-link" href="https://blog.neurips.cc/2025/10/02/reflecting-on-the-inaugural-neurips-position-paper-track-a-pilot-year-journey/" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">公式ブログ</span></a><span class="rotion-richtext-annot rotion-richtext-default">が公開されています。ブログによると、初回の投稿数は約700件に達し、運営チームも予想を上回る反響があったとしています。取り下げやデスクリジェクトを除くと、496件が本審査の対象となりました。この中から40件の論文がカンファレンスでの発表に選ばれ、採択率は他のトラックと比較しても非常に低い約8%でした。この低い採択率の背景には、採択された論文に対して、より集中的な注目を集めるという事務局側の戦略的な判断があったようです。</span></p></div><div><h3 class="rotion-text rotion-text-h2" id="ba59368b"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">現地での発表：オーラルとパネルディスカッション</span></h3></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">NeurIPS 2025では、採択された40件のPosition Paperの中から3件のオーラル発表と2件のパネルディスカッション（それぞれ3件の論文で構成）が選ばれました。ここでは、どのようなPosition Paperが採択されているかを概観するために、簡単に内容を紹介します。</span></p></div><div><h4 class="rotion-text rotion-text-h3" id="ab6b13f9"><span class="rotion-richtext-annot rotion-richtext-default">オーラル①「</span><a class="rotion-richtext-link" href="https://openreview.net/forum?id=PFRandBfSz" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Position: If Innovation in AI systematically Violates Fundamental Rights, Is It Innovation at All?</span></a><span class="rotion-richtext-annot rotion-richtext-default">」</span></h4></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">規制とイノベーションは対立するものではなく、むしろ適切な規制こそがイノベーションの基盤となると主張しています。EU AI Actをリスクベースかつ責任重視の規制モデルとして検討し、規制サンドボックスや中小企業支援などの適応的メカニズムが、技術的進歩を遅らせるのではなく責任ある形で加速させることを示しています。</span></p></div><div><h4 class="rotion-text rotion-text-h3" id="b78e9550"><span class="rotion-richtext-annot rotion-richtext-default">オーラル②「</span><a class="rotion-richtext-link" href="https://openreview.net/forum?id=rdeCalg68L" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">More effort is needed to protect pedestrian privacy in the era of AI</span></a><span class="rotion-richtext-annot rotion-richtext-default">」</span></h4></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">自動運転や監視システムの開発において、公共の場でのデータ収集が歩行者の同意なしに行われている現状に警鐘を鳴らしています。AIコミュニティに対してデータ収集・匿名化の方法を再考するよう呼びかけています。</span></p></div><div><h4 class="rotion-text rotion-text-h3" id="f404fc43"><span class="rotion-richtext-annot rotion-richtext-default">オーラル③「</span><a class="rotion-richtext-link" href="https://openreview.net/forum?id=1IpHkK5Q8F" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Real-Time Hyper-Personalized Generative AI Should Be Regulated to Prevent the Rise of "Digital Heroin"</span></a><span class="rotion-richtext-annot rotion-richtext-default">」</span></h4></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">リアルタイムで生成される超パーソナライズされたAIコンテンツが、SNS中毒を超える「デジタル・ヘロイン」とも言える依存性の危険を指摘しています。特に若年層のメンタルヘルスへの悪影響を防ぐため、依存性薬物と同様の厳格な政府監視と、開発者向けの倫理ガイドラインの策定を強く訴えました。</span></p></div><div><h4 class="rotion-text rotion-text-h3" id="bdedacf1"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">パネルディスカッション①</span><span class="rotion-richtext-annot rotion-richtext-default">「Responsible AI Research & Unlearning: From Consent to Compliance to Critique」</span></h4></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">責任あるAI/ML研究に向けて、データに対する同意の問題とモデルのアンラーニングの技術的・法的課題に焦点を当てた3つの論文が取り上げられました。</span></p></div><div><ul class="rotion-listblocks rotion-list-ul"><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">「</span><a class="rotion-richtext-link" href="https://openreview.net/forum?id=Ev5xwr3vWh" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Stop the Nonconsensual Use of Nude Images in Research</span></a><span class="rotion-richtext-annot rotion-richtext-default">」：裸体検出や裸体画像データセットに関する研究が、しばしば同意なく進められ、非同意のコンテンツの流通を正常化し、被害を永続させている問題を指摘しています。</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">「</span><a class="rotion-richtext-link" href="https://openreview.net/forum?id=0ngi2StMwC" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Position: Bridge the Gaps between Machine Unlearning and AI Regulation</span></a><span class="rotion-richtext-annot rotion-richtext-default">」：機械学習モデルのアンラーニング（データの影響の削除など）技術と、EU AI Actなどの既存の規制フレームワークを比較検討し、法的・技術的なギャップを明らかにしています。</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">「</span><a class="rotion-richtext-link" href="https://openreview.net/forum?id=mfd6GRW4Az" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Machine Unlearning Doesn't Do What You Think: Lessons for Generative AI Policy, Research, and Practice</span></a><span class="rotion-richtext-annot rotion-richtext-default">」：生成AIシステムにおける技術的なアンラーニング手法と、法律・政策の関係者がこれらの手法に期待するものとの間のミスマッチを深く掘り下げています。</span></li></ul></div><div><h4 class="rotion-text rotion-text-h3" id="64fb5fd9"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">パネルディスカッション②「Strengthening the AI Research Ecosystem: Integrity, Critique, and Consensus」</span></h4></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">機械学習研究エコシステムの構造的な脆弱性を指摘し、大胆な改革を提案する3つの論文が議論されました。</span></p></div><div><ul class="rotion-listblocks rotion-list-ul"><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">「</span><a class="rotion-richtext-link" href="https://openreview.net/forum?id=R5uuqCAPf8" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Stop DDoS Attacking the Research Community with AI-Generated Survey Papers</span></a><span class="rotion-richtext-annot rotion-richtext-default">」：AI生成による大量生産されたサーベイ論文の急増を、研究記録を氾濫させ劣化させる「サーベイ論文DDoS攻撃」の一形態として問題提起しています。</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">「</span><a class="rotion-richtext-link" href="https://openreview.net/forum?id=DS1XSAPvKs" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Position: Machine Learning Conferences Should Establish a ”Refutations and Critiques” Track</span></a><span class="rotion-richtext-annot rotion-richtext-default">」：主要なMLカンファレンスには、先行研究に対する厳密な批評や訂正のための信頼性・可視性の高い場が欠如していると主張し、専用の「反論・批評」トラックの創設を提案しています。</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">「</span><a class="rotion-richtext-link" href="https://openreview.net/forum?id=a4oXTW1PW2" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">NeurIPS should lead scientific consensus on AI policy</span></a><span class="rotion-richtext-annot rotion-richtext-default">」：NeurIPS（ひいてはMLコミュニティ全体）がAI政策に関する科学的コンセンサスの形成において積極的な役割を果たすべきであると主張し、エビデンスの統合と意思決定における重要なギャップを埋めることを求めています。</span></li></ul></div><div><h2 class="rotion-text rotion-text-h1" id="59d401b0"><span class="rotion-richtext-annot rotion-richtext-default">AI4Mat Workshopでのポスター発表</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">NeurIPSでは例年、メインカンファレンス終了後に各Workshopが並列で開催されます。NeurIPS 2025では合計56のWorkshopが2日間にわたって開催されました。私は2023年から3年連続でNeurIPSに参加していますが、2024年のAlphaFold関連のノーベル賞受賞などの影響もあってか、AI for Science系のWorkshopは参加人数も増え、非常に盛り上がっているように感じました。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">私は「AI4Mat Workshop (AI for Accelerated Materials Design)」にてポスター発表を行ってきました。「AI4Mat Workshop」は、材料科学とAIの研究者が、AIによる材料発見の最前線を切り開く課題や成果を議論・共有する場として2022年に発足したワークショップです。今年は他のWorkshopと比べても大きな部屋が割り当てられており、参加者数も多く盛況でした。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">NeurIPSのメインカンファレンスでは、各ポスターに専用の展示ボードが用意されるのが通例ですが、ワークショップは少し勝手が異なります。写真のように、会場の壁面に自分の好きな場所を見つけてポスターを直接貼り付けるという、スタイルとなっています。AI4Mat Workshopではポスター数も多かったため、隣のポスターとの間隔が数センチしかないような密集地帯も多く、発表しづらさを感じる場面もありました。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-2d097d4e-f442-8035-aaf2-d587b27286f5-0e76292794888d4f1fa75fb3aff4ca27c58f56a6.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">そんな過密状態の中での発表でしたが、セッション中は聴衆が絶えることがなく、研究内容への関心の高さを実感しました。本研究の内容は、以前のブログ「</span><a class="rotion-richtext-link" href="https://research.sakura.ad.jp/blog/neurips2025-ai4mat-workshop" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">LLMによる構造化データ抽出に関する論文が「NeurIPS 2025 AI4Mat Workshop」に採択</span></a><span class="rotion-richtext-annot rotion-richtext-default">」にて解説しています。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">今回の発表で特に手応えを感じたのは、公開したデータセットに対する反応です。多くの参加者がその場でポスターに記載したQRコードを読み込んでダウンロードページにアクセスしていたのが印象的でした。このことは、我々の研究成果が理論的な貢献に留まらず、具体的な研究リソースとしても実用性・有用性を認められたことを示しており、大変嬉しく思いました。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-portrait" src="/images/block-2d197d4e-f442-8044-8f2a-d20fb053d79c-e39c3dad6a6d406552a235f8fc84a72ce66edbbe.webp" alt=""/></div><div class="rotion-image-caption"></div></div></div><div><h2 class="rotion-text rotion-text-h1" id="a30cd98b"><span class="rotion-richtext-annot rotion-richtext-default">おわりに</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">NeurIPS 2025への参加を通じて、機械学習コミュニティが技術的な成果だけでなく、研究の方向性や倫理的課題についても活発に議論する場へと進化していることを実感しました。新設されたPosition Paper Trackは、「私たちはどこに向かうべきか」という問いを正面から扱う貴重な試みであり、今後の発展が楽しみです。また、AI4Mat Workshopでのポスター発表では、公開したデータセットへの関心の高さから、研究成果が実際に活用される手応えを得ることができました。この経験を糧に、さくらインターネット研究所からより実用的で価値のある研究成果を生み出せるよう、引き続き研究開発に取り組んでいきたいと思います。</span></p></div></div>]]></content:encoded>
            <author>さくらインターネット研究所</author>
        </item>
        <item>
            <title><![CDATA[Github Actionsにおけるフロントエンドテストの安定化とテストカバレッジの収集]]></title>
            <link>https://research.sakura.ad.jp/blog/frontend-parallel-testing</link>
            <guid isPermaLink="false">https://research.sakura.ad.jp/blog/frontend-parallel-testing</guid>
            <pubDate>Fri, 21 Nov 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<link rel="preload" as="image" href="/images/block-2b197d4e-f442-80d7-935e-ec22e75befb9-24840a94e0b45b03def1c1c9628a35d2cbcb82c2.webp"/><link rel="preload" as="image" href="/images/block-2b197d4e-f442-80a9-81c8-fcf223602c12-271125d14d3bb88e6704d96b7d2f0a92bf00b2cf.webp"/><div class="rotion-blocks"><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">こんにちは！研究開発エンジニアの森田(</span><a class="rotion-richtext-link" href="https://x.com/tascript" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">@tascript</span></a><span class="rotion-richtext-annot rotion-richtext-default">)です。今年は筋トレを頑張ったので肩と背中が去年より大きくなりました。もはやトレーニングというより「育てる」感覚に近いので、最近は肩と背中に語りかけるようにしています。今のところ特に返事はありません。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">さて、さくらインターネット研究所では</span><a class="rotion-richtext-link" href="https://research.sakura.ad.jp/blog/rc-activity-policy-2025" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">プロダクト開発グループ</span></a><span class="rotion-richtext-annot rotion-richtext-default">を設けており、研究成果をプロダクトを通じて社会実装し社会に役立てるという目標があります。今回はプロダクト開発グループ内で採用したフロントエンドのテスト設計の一部を紹介します。</span></p></div><div><h2 class="rotion-text rotion-text-h1" id="7e1e23e0"><span class="rotion-richtext-annot rotion-richtext-default">テスト実行時間の増大とFlaky Testの発生</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">プロダクト開発グループでは </span><a class="rotion-richtext-link" href="https://vitest.dev/" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Vitest</span></a><span class="rotion-richtext-annot rotion-richtext-default"> と </span><a class="rotion-richtext-link" href="https://testing-library.com/docs/react-testing-library/intro/" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">React Testing Library</span></a><span class="rotion-richtext-annot rotion-richtext-default"> (以下、RTL)を活用してユニットテストおよびインテグレーションテストを実施しています。開発初期段階からテストを導入していて、開発が進むにつれてCI上でのテスト実行時間が増大する傾向を確認しました。また、既存のテストに依存しない新規テストケースを追加した際に、開発環境ではパスするもののCI上では失敗するといったFlaky Testが発生しました。Flaky Testの原因を追求すべく調査した結果、CIで以下のような現象が発生していました。</span></p></div><div><ul class="rotion-listblocks rotion-list-ul"><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">インテグレーションテストにてデータがDOMに反映されないままテストが開始されている</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">ユーザーアクションによる状態変化がDOMに反映されないままテストが開始されている</span></li><li class="rotion-bulleted-list"><span class="rotion-richtext-annot rotion-richtext-default">CI上でのテスト実行時間が開発環境の約3倍長い</span><div class="rotion-blocks"><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-shell"><code> Test Files  41 passed (41)       Tests  325 passed (325)    Start at  06:08:03    Duration  167.13s (transform 1.18s, setup 4.68s, collect 19.12s, tests 106.83s, environment 21.60s, prepare 4.31s)</code></pre></div><div class="rotion-code-caption"><span class="rotion-richtext-annot rotion-richtext-default">Github Actionsでのテスト実行時間</span></div></div></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-shell"><code> Test Files  41 passed (41)       Tests  325 passed (325)    Start at  15:32:23    Duration  61.28s</code></pre></div><div class="rotion-code-caption"><span class="rotion-richtext-annot rotion-richtext-default">開発環境でのテスト実行時間</span></div></div></div></div></li></ul></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">CIにはGithub Actionsを利用していますが、</span><a class="rotion-richtext-link" href="https://docs.github.com/en/actions/reference/runners/github-hosted-runners" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Github-hosted runners</span></a><span class="rotion-richtext-annot rotion-richtext-default">で割り当てられるコンピューティングリソースと開発マシンで使用できるリソースとの差異が大きいことによってFlaky Testが発生していると予想し、CI上のリソース不足課題に取り組みました。（Self-hosted runnersを使ってお金の力で雑にスペックアップする方法は今回見送っています）</span></p></div><div><h2 class="rotion-text rotion-text-h1" id="fec90ec7"><span class="rotion-richtext-annot rotion-richtext-default">VitestのSharding</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">Vitestにはテストケースを分割する </span><a class="rotion-richtext-link" href="https://vitest.dev/guide/improving-performance.html#sharding" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Sharding</span></a><span class="rotion-richtext-annot rotion-richtext-default"> と呼ばれる機能があります。例えば、以下のコマンドを実行することでテストケースを4つに分割してそのうちの1つ目(シャード)を実行することができます。</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-shell"><code>$ vitest run --shard=1/4</code></pre></div><div class="rotion-code-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">Shardingによる分割はテストケースを追加しない限り一定で、</span><a class="rotion-richtext-link" href="https://vitest.dev/config/coverage.html#coverage" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">オプション</span></a><span class="rotion-richtext-annot rotion-richtext-default">を付与することで、テストカバレッジのレポートを作成することもできます。例えば、以下のようなコマンドを実行することでテストケースを4つに分割して実行およびテストカバレッジを収集します。</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-shell"><code>$ vitest run --shard=1/4 --coverage.enabled --coverage.reportsDirectory=coverage/shard-1 $ vitest run --shard=2/4 --coverage.enabled --coverage.reportsDirectory=coverage/shard-2 $ vitest run --shard=3/4 --coverage.enabled --coverage.reportsDirectory=coverage/shard-3 $ vitest run --shard=4/4 --coverage.enabled --coverage.reportsDirectory=coverage/shard-4</code></pre></div><div class="rotion-code-caption"></div></div></div><div><h2 class="rotion-text rotion-text-h1" id="e7b6568b"><span class="rotion-richtext-annot rotion-richtext-default">マトリックス戦略を利用したテストの並列実行</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">Github Actionsではワークフローのジョブ内部に</span><a class="rotion-richtext-link" href="https://docs.github.com/ja/actions/how-tos/write-workflows/choose-what-workflows-do/run-job-variations#adding-a-matrix-strategy-to-your-workflow-job" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">マトリックス</span></a><span class="rotion-richtext-annot rotion-richtext-default">を作成することが可能です。こちらと先ほどのVitest Shardingを利用してテストを並列実行します。ワークフローは下記のように記述します。</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-yaml"><code>name: Parallel Test  on:   workflow_dispatch:   push:     branches:       - main   pull_request:    jobs:   # テストを並列実行   test:     name: UI Tests     runs-on: ubuntu-latest     strategy:       matrix:         shardTotal: [4]         shardIndex: [1,2,3,4]     steps:       - uses: actions/checkout@v5       - uses: pnpm/action-setup@v4         with:           version: 10           run_install: false       - uses: actions/setup-node@v4         with:           node-version: 22       - run: echo &quot;STORE_PATH=$(pnpm store path --silent)&quot; &gt;&gt; $GITHUB_ENV       - uses: actions/cache@v4         with:           path: ${{ env.STORE_PATH }}           key: ${{ runner.os }}-pnpm-store-${{ hashFiles(&#x27;**/pnpm-lock.yaml&#x27;) }}           restore-keys: |             ${{ runner.os }}-pnpm-store-       - name: Install Dependencies         run: pnpm install --frozen-lockfile       - name: Run UI Test         run: pnpm exec vitest run --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --coverage.enabled --coverage.reportsDirectory=./coverage/shard-${{ matrix.shardIndex }}       - name: Upload Coverage Artifact         uses: actions/upload-artifact@v4         with:           name: shard-${{ matrix.shardIndex  }}           path: ./coverage/shard-${{ matrix.shardIndex  }}</code></pre></div><div class="rotion-code-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot  rotion-richtext-code rotion-richtext-code-color">shardTotal</span><span class="rotion-richtext-annot rotion-richtext-default"> にてテストを4分割(4つのシャードを生成)することを宣言し、</span><span class="rotion-richtext-annot  rotion-richtext-code rotion-richtext-code-color">shardIndex</span><span class="rotion-richtext-annot rotion-richtext-default"> にマトリックス戦略によって起動する各VM上で担当するシャードの番号を宣言します。これにより、各VM上では各VMにて下記のコマンドがそれぞれ実行されるため、テストを並列で実行することができます。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">VM1</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-shell"><code>$ pnpm exec vitest run --shard=1/4 --coverage.enabled --coverage.reportsDirectory=coverage/shard-1</code></pre></div><div class="rotion-code-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">VM2</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-shell"><code>$ pnpm exec vitest run --shard=2/4 --coverage.enabled --coverage.reportsDirectory=coverage/shard-2</code></pre></div><div class="rotion-code-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">VM3</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-shell"><code>$ pnpm exec vitest run --shard=3/4 --coverage.enabled --covera3e.reportsDirectory=coverage/shard-3</code></pre></div><div class="rotion-code-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default rotion-richtext-bold">VM4</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-shell"><code>$ pnpm exec vitest run --shard=4/4 --coverage.enabled --coverage.reportsDirectory=coverage/shard-4</code></pre></div><div class="rotion-code-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">各VMは以前までのテストと比較して1/4の量を処理すればよいので、以前よりもテスト実行による負荷が軽減します。結果として、Flakyテストの発生率が低下すると同時にテスト実行時間も短縮することができました。</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-shell"><code> Test Files  41 passed (41)       Tests  325 passed (325)    Start at  03:00:24    Duration  139.39s (transform 1.64s, setup 4.64s, collect 19.01s, tests 85.13s, environment 20.33s, prepare 2.28s)</code></pre></div><div class="rotion-code-caption"><span class="rotion-richtext-annot rotion-richtext-default">直列でテストを実行した場合は139.39sで完了</span></div></div></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-shell"><code> Test Files  10 passed (10)       Tests  75 passed (75)    Start at  09:54:09    Duration  37.64s (transform 1.44s, setup 1.38s, collect 7.31s, tests 21.60s, environment 5.16s, prepare 228ms)</code></pre></div><div class="rotion-code-caption"><span class="rotion-richtext-annot rotion-richtext-default">並列で実行したテストの内、最も時間を要しても37.64sで完了</span></div></div></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-2b197d4e-f442-80d7-935e-ec22e75befb9-24840a94e0b45b03def1c1c9628a35d2cbcb82c2.webp" alt=""/></div><div class="rotion-image-caption"><span class="rotion-richtext-annot rotion-richtext-default">並列実行していることが確認できる</span></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">また、マトリックス戦略の具体的な数値は、同時実行できるjob(起動できるVMのインスタンス数)にあわせて設定するとよいでしょう。例えば、Github-hosted runnersの場合は</span><a class="rotion-richtext-link" href="https://docs.github.com/ja/actions/reference/limits#job-concurrency-limits-for-github-hosted-runners" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">プランによって異なる</span></a><span class="rotion-richtext-annot rotion-richtext-default">ため注意が必要です。</span></p></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">また、各jobで生成されたカバレッジレポートは、一時的に下記のように保存されます。</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-plain text"><code>coverage/ ├─ shard-1/ │  └─ coverage-final.json ├─ shard-2/ │  └─ coverage-final.json ├─ shard-3/ │  └─ coverage-final.json └─ shard-4/    └─ coverage-final.json</code></pre></div><div class="rotion-code-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">今後のジョブでこれらのカバレッジレポートを再利用するため、</span><a class="rotion-richtext-link" href="https://github.com/actions/upload-artifact" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">upload-artifact</span></a><span class="rotion-richtext-annot rotion-richtext-default">を利用してアップロードします。各レポートは</span><span class="rotion-richtext-annot  rotion-richtext-code rotion-richtext-code-color">shard-1</span><span class="rotion-richtext-annot rotion-richtext-default"> 、</span><span class="rotion-richtext-annot  rotion-richtext-code rotion-richtext-code-color">shard-2</span><span class="rotion-richtext-annot rotion-richtext-default"> 、</span><span class="rotion-richtext-annot  rotion-richtext-code rotion-richtext-code-color">shard-3</span><span class="rotion-richtext-annot rotion-richtext-default"> 、</span><span class="rotion-richtext-annot  rotion-richtext-code rotion-richtext-code-color">shard-4</span><span class="rotion-richtext-annot rotion-richtext-default"> として保存されます。</span></p></div><div><h2 class="rotion-text rotion-text-h1" id="5f24e1e6"><span class="rotion-richtext-annot rotion-richtext-default">カバレッジの集計</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">生成したカバレッジレポートをマージしてテスト全体のカバレッジを集計するためのジョブを作成します。ワークフローは下記のように記述します。</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-yaml"><code>name: Parallel Test  on:   workflow_dispatch:   push:     branches:       - main   pull_request:    jobs:   # テストを並列実行   test:     name: UI Tests     runs-on: ubuntu-latest     strategy:       matrix:         shardTotal: [4]         shardIndex: [1,2,3,4]     steps:       - uses: actions/checkout@v5       - uses: pnpm/action-setup@v4         with:           version: 10           run_install: false       - uses: actions/setup-node@v4         with:           node-version: 22       - run: echo &quot;STORE_PATH=$(pnpm store path --silent)&quot; &gt;&gt; $GITHUB_ENV       - uses: actions/cache@v4         with:           path: ${{ env.STORE_PATH }}           key: ${{ runner.os }}-pnpm-store-${{ hashFiles(&#x27;**/pnpm-lock.yaml&#x27;) }}           restore-keys: |             ${{ runner.os }}-pnpm-store-       - name: Install Dependencies         run: pnpm install --frozen-lockfile       - name: Run UI Test         run: pnpm exec vitest run --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --coverage.enabled --coverage.reportsDirectory=./coverage/shard-${{ matrix.shardIndex }}       - name: Upload Coverage Artifact         uses: actions/upload-artifact@v4         with:           name: shard-${{ matrix.shardIndex  }}           path: ./coverage/shard-${{ matrix.shardIndex  }}      # レポートをマージしてカバレッジを集計する   report:     name: Report Test Coverage     needs: [test]     runs-on: ubuntu-latest     steps:       - uses: actions/checkout@v5       - uses: pnpm/action-setup@v4         with:           version: 10           run_install: false       - uses: actions/setup-node@v4         with:           node-version: 22       - run: echo &quot;STORE_PATH=$(pnpm store path --silent)&quot; &gt;&gt; $GITHUB_ENV       - uses: actions/cache@v4         with:           path: ${{ env.STORE_PATH }}           key: ${{ runner.os }}-pnpm-store-${{ hashFiles(&#x27;**/pnpm-lock.yaml&#x27;) }}           restore-keys: |             ${{ runner.os }}-pnpm-store-       - name: Install Dependencies         run: pnpm install --frozen-lockfile       - uses: actions/download-artifact@v4         with:           pattern: shard-*           path: ./coverage       - name: Generate Reports         uses: ./generate-report.sh       - name: Run octocov         uses: k1LoW/octocov-action@v1</code></pre></div><div class="rotion-code-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><a class="rotion-richtext-link" href="https://github.com/actions/download-artifact" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">download-artifacts</span></a><span class="rotion-richtext-annot rotion-richtext-default">を利用して先程アップロードしたカバレッジレポート(</span><span class="rotion-richtext-annot  rotion-richtext-code rotion-richtext-code-color">shard-1</span><span class="rotion-richtext-annot rotion-richtext-default"> 、</span><span class="rotion-richtext-annot  rotion-richtext-code rotion-richtext-code-color">shard-2</span><span class="rotion-richtext-annot rotion-richtext-default"> 、</span><span class="rotion-richtext-annot  rotion-richtext-code rotion-richtext-code-color">shard-3</span><span class="rotion-richtext-annot rotion-richtext-default"> 、</span><span class="rotion-richtext-annot  rotion-richtext-code rotion-richtext-code-color">shard-4</span><span class="rotion-richtext-annot rotion-richtext-default">)をダウンロードします。</span><span class="rotion-richtext-annot rotion-richtext-default">取得したカバレッジレポートをマージするために</span><a class="rotion-richtext-link" href="https://github.com/istanbuljs/nyc" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">nyc</span></a><span class="rotion-richtext-annot rotion-richtext-default">を利用します。</span><span class="rotion-richtext-annot rotion-richtext-default">nycは</span><a class="rotion-richtext-link" href="https://github.com/istanbuljs/istanbuljs" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">IstanbulJS</span></a><span class="rotion-richtext-annot rotion-richtext-default">のCLIで、テストカバレッジをマージおよび様々な形式のカバレッジレポートを作成することができます。Vitestの</span><a class="rotion-richtext-link" href="https://vitest.dev/guide/reporters.html#blob-reporter" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">Blob Reporter</span></a><span class="rotion-richtext-annot rotion-richtext-default">および</span><a class="rotion-richtext-link" href="https://vitest.dev/guide/cli.html#merge-reports" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">merge-reportsオプション</span></a><span class="rotion-richtext-annot rotion-richtext-default">を利用することで各シャードから生まれたJSONをマージしてレポートを生成することができます。しかし、他の形式のカバレッジレポートに変換する機能がないことおよび</span><a class="rotion-richtext-link" href="https://github.com/k1LoW/octocov" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">octcov</span></a><span class="rotion-richtext-annot rotion-richtext-default">を使ってテストカバレッジを集計したいというユースケースから今回はnycを採用しました。Vitestでは</span><a class="rotion-richtext-link" href="https://vitest.dev/guide/coverage" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">カバレッジプロバイダー</span></a><span class="rotion-richtext-annot rotion-richtext-default">として</span><span class="rotion-richtext-annot rotion-richtext-default">v8</span><span class="rotion-richtext-annot rotion-richtext-default">とistanbulのどちらかが選択できますが、Vitest v3.2.0からv8でもistanbulと同一のレポートを生成することができます。また、カバレッジの精度もistanbulと同等な上、メモリ使用量がistanbulより少ないため今回のユースケースにはv8が適切だと判断しました。最終的なレポート作成のスクリプト(</span><span class="rotion-richtext-annot  rotion-richtext-code rotion-richtext-code-color">generate-report.sh</span><span class="rotion-richtext-annot rotion-richtext-default">)は以下のように記述します。記述後はスクリプトの実行権限を付与しておきましょう。</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-shell"><code>#!/usr/bin/env bash  set -euo pipefail  DIST_DIR=&quot;coverage&quot; TEMP_DIR=&quot;_temp&quot; FLATTEN_DIR=&quot;$DIST_DIR/$TEMP_DIR&quot; MERGED_FILE=&quot;coverage-final.json&quot;  rm -rf &quot;$FLATTEN_DIR&quot; mkdir -p &quot;$FLATTEN_DIR&quot;  # レポートをcoverage/_temp配下で平坦化 find $DIST_DIR -type d -name $TEMP_DIR -prune -o -type f -name &quot;$MERGED_FILE&quot; -print0 | while IFS= read -r -d &#x27;&#x27; f; do   parent=&quot;$(basename &quot;$(dirname &quot;$f&quot;)&quot;)&quot;   output=&quot;$FLATTEN_DIR/${parent}.json&quot;   cp &quot;$f&quot; &quot;$output&quot; done  # coverage/_tempに配置したレポートをマージしてcoverage/coverage-final.jsonに集約 pnpm exec nyc merge &quot;$FLATTEN_DIR&quot; &quot;$DIST_DIR/$MERGED_FILE&quot;  # coverage/coverage-final.jsonを元にlcov形式でレポートをcoverage/reportに保存 pnpm exec nyc report -t coverage \   --reporter=lcov \   --report-dir=coverage/report</code></pre></div><div class="rotion-code-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">上記のコマンドを実施後、CI上にて</span><span class="rotion-richtext-annot  rotion-richtext-code rotion-richtext-code-color">coverage</span><span class="rotion-richtext-annot rotion-richtext-default">ディレクトリ配下は以下のような構成になります。</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-plain text"><code>coverage/ ├─ _temp/ │  ├─ shard-1.json │  ├─ shard-2.json │  ├─ shard-3.json │  └─ shard-4.json ├─ report/ │  ├─ lcov-report/ │  └─ lcov.info ├─ shard-1/ │  └─ coverage-final.json ├─ shard-2/ │  └─ coverage-final.json ├─ shard-3/ │  └─ coverage-final.json ├─ shard-4/ │  └─ coverage-final.json └─ coverage-final.json</code></pre></div><div class="rotion-code-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot  rotion-richtext-code rotion-richtext-code-color">coverage/report</span><span class="rotion-richtext-annot rotion-richtext-default"> ディレクトリには、最終的なテストカバレッジをlcov形式(</span><span class="rotion-richtext-annot  rotion-richtext-code rotion-richtext-code-color">lcov.info</span><span class="rotion-richtext-annot rotion-richtext-default">)で保存し、</span><a class="rotion-richtext-link" href="https://github.com/k1LoW/octocov-action" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">k1LoW/octocov-action</span></a><span class="rotion-richtext-annot rotion-richtext-default">を利用することで、テストカバレッジを集計します。</span></p></div><div><div class="rotion-image"><div class="rotion-image-area"><img class="rotion-image-img rotion-image-ratio-landscape" src="/images/block-2b197d4e-f442-80a9-81c8-fcf223602c12-271125d14d3bb88e6704d96b7d2f0a92bf00b2cf.webp" alt=""/></div><div class="rotion-image-caption"><span class="rotion-richtext-annot rotion-richtext-default">テストカバレッジをoctcovで集計</span></div></div></div><div><h2 class="rotion-text rotion-text-h1" id="3776f9a2"><span class="rotion-richtext-annot rotion-richtext-default">複合アクションの活用</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">Node.js環境のセットアップや、テストの並列実行など再利用性の高いものは</span><a class="rotion-richtext-link" href="https://docs.github.com/ja/actions/tutorials/create-actions/create-a-composite-action" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">複合アクション</span></a><span class="rotion-richtext-annot rotion-richtext-default">にまとめました。　例えば、Node.js環境セットアップの複合アクションは以下のように記述します。</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-yaml"><code># .github/actions/set-up/action.yml runs:   using: &quot;composite&quot;   steps:     - uses: pnpm/action-setup@v4       with:         version: 10         run_install: false     - uses: actions/setup-node@v4       with:         node-version: 22     - run: echo &quot;STORE_PATH=$(pnpm store path --silent)&quot; &gt;&gt; $GITHUB_ENV       shell: bash     - uses: actions/cache@v4       with:         path: ${{ env.STORE_PATH }}         key: ${{ runner.os }}-pnpm-store-${{ hashFiles(&#x27;**/pnpm-lock.yaml&#x27;) }}         restore-keys: |           ${{ runner.os }}-pnpm-store-     - run: pnpm install --frozen-lockfile       shell: bash</code></pre></div><div class="rotion-code-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">テストおよびカバレッジのアップロードの複合アクションは以下のように記述します。</span><a class="rotion-richtext-link" href="https://docs.github.com/ja/actions/reference/workflows-and-actions/metadata-syntax#inputs" rel="noreferrer" target="_blank"><span class="rotion-richtext-annot rotion-richtext-default">inputs</span></a><span class="rotion-richtext-annot rotion-richtext-default">を利用してジョブのマトリックス戦略に対応します。</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-yaml"><code># .github/actions/run-test-and-upload-report/action.yml inputs:   shardIndex:      description: &quot;The index of the shard&quot;     required: true   shardTotal:     description: &quot;The total number of shards&quot;     required: true runs:   using: &quot;composite&quot;   steps:     - name: Run UI Test       run: pnpm exec vitest run --shard=${{ inputs.shardIndex }}/${{ inputs.shardTotal }} --coverage.enabled --coverage.reportsDirectory=./coverage/shard-${{ inputs.shardIndex }}       shell: bash     - name: Upload Coverage Artifact       uses: actions/upload-artifact@v4       with:         name: shard-${{ inputs.shardIndex }}         path: ./coverage/shard-${{ inputs.shardIndex }}</code></pre></div><div class="rotion-code-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">最終的なレポート作成のアクションは以下のように記述します。</span><span class="rotion-richtext-annot  rotion-richtext-code rotion-richtext-code-color">github.action_path</span><span class="rotion-richtext-annot rotion-richtext-default"> は複合アクションが存在するパスを指します。コロケーションを意識して最終的なレポート作成のスクリプトも同一パス配下に配置します。</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-yaml"><code># .github/actions/generate-report runs:   using: &quot;composite&quot;   steps:     - run: ${{ github.action_path }}/script.sh       shell: bash</code></pre></div><div class="rotion-code-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">これらの複合アクションを利用したワークフローは以下のように記述します。</span></p></div><div><div class="rotion-code"><div class="rotion-code-area"><pre class="language-yaml"><code>name: Parallel Test  on:   workflow_dispatch:   push:     branches:       - main   pull_request:    jobs:   # テストを並列実行   test:     name: UI Tests     runs-on: ubuntu-latest     strategy:       matrix:         shardTotal: [4]         shardIndex: [1,2,3,4]     steps:       - uses: actions/checkout@v5       - name: Setup Node.js         uses: ./.github/actions/setup       - name: Run Test And Upload Report         uses: ./.github/actions/run-test-and-upload-report         with:           shardIndex: ${{ matrix.shardIndex }}           shardTotal: ${{ matrix.shardTotal }}      # レポートをマージしてカバレッジを集計する   report:     name: Report Test Coverage     needs: [test]     runs-on: ubuntu-latest     steps:       - uses: actions/checkout@v5       - name: Setup Node.js         uses: ./.github/actions/setup       - uses: actions/download-artifact@v4         with:           pattern: shard-*           path: ./coverage       - name: Generate Reports         uses: ./.github/actions/generate-report       - name: Run octocov         uses: k1LoW/octocov-action@v1</code></pre></div><div class="rotion-code-caption"></div></div></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">こうすることでコードの視認性も高くなり、類似したアクションを記載する必要がなくなります。</span></p></div><div><h2 class="rotion-text rotion-text-h1" id="634ae46a"><span class="rotion-richtext-annot rotion-richtext-default">最後に</span></h2></div><div><p class="rotion-text rotion-text-p"><span class="rotion-richtext-annot rotion-richtext-default">Flaky Testは、今回のようにCI環境だけでなく、アプリケーションの実装やテストの手法が要因となって発生します。テストコードを増やすことはプロダクトの品質を上げるために必須です。そして、テストをいかに安定して動作させるか、ということも同時に達成しなければ開発の体験はもちろん、顧客への価値提供が遅れてしまう要因になります。これからもFlaky Testとの戦いに備えて、常に考え抜く力と探求する力を鍛錬していきたいと思い筆を取った次第です。少しでもお役に立てれば幸いです。</span></p></div></div>]]></content:encoded>
            <author>さくらインターネット研究所</author>
        </item>
    </channel>
</rss>