ノートPCの前で接続した演算装置、文書カード、半透明の吹き出し。

Edge0連載 2: Microsoft LearnとApple Translationの実行環境

2026年9月13日時点で、この連載のサンプルはEdge0-35B、Microsoft Learn CLI、macOSのTranslationフレームワークを使用します。第1回で決めた役割分担に沿って、推論サーバーとPythonエージェントのホストを別々のターミナルで実行します。 この記事ではEdge0とモデルの導入、ストリーミングサーバーの起動、公式文書の検索、韓国語と英語の翻訳、質問の正規化を扱います。ファイル全体はサンプルGistのREADME.md、apple_translate.swift、microsoft_expert_agent.pyにあります。 実行条件とインストール手順から説明します。最初のターミナルでサーバーを起動した後、検索ツールと翻訳CLIを準備し、二つ目のターミナルでエージェントを実行できる状態にします。 以下の手順は、次の公開バージョンとAPI条件を前提にしています。 文書は2026年9月13日に確認しました。Edge0-35B-A3B-previewの構成は今後変わる可能性があります。Swiftの例で使用するTranslationSession(installedSource:target:preferredStrategy:)は、macOS 26.4以降と、このAPIを含むSDKを前提とします。 Edge0と35Bモデルの導入条件 実験にはApple Silicon Mac、Python 3.12、Node.js 22以降、Xcode Command Line Toolsを使用します。約23GBのモデルファイルを保存する空き容量と、韓国語および英語の翻訳リソースも用意します。対応環境とモデルファイルの構成は公式READMEに記載されています。 リポジトリとPython仮想環境 作業ディレクトリでリポジトリを取得し、仮想環境を有効にしてサンプルの依存関係をインストールします。 git clone https://github.com/Edge0-AI/Edge0.git cd Edge0 python3.12 -m venv .venv source .venv/bin/activate pip install -e '.[dev,fetch]' pip install flask requests 以後のコマンドはEdge0リポジトリのルートを作業ディレクトリにします。flaskはストリーミング転送、requestsはPythonホストのHTTPリクエストに使用します。 モデルのダウンロードとパスの指定 公式スクリプトで35Bモデルを取得し、現在のシェルにモデルパスを設定します。 python scripts/fetch_models.py \ --tier edge0-35b \ --target-dir models export EDGE0_35B_MODEL="$PWD/models/edge0-35b" models/edge0-35b/には、設定、モデルの重み、トークナイザー、LoRAとプリルーターのアダプターが含まれます。アダプターを含むディレクトリ全体をモデルパスとして指定します。 最初のターミナルで動かすストリーミングサーバー Edge0の35Bモデル文書は、Flask転送層によるSSEストリーミングと、状態確認用の/healthzを説明しています。このサンプルでは接続先を127.0.0.1:8083に設定します。 仮想環境の再有効化とサーバー起動 新しいターミナルでは、作業パス、仮想環境、モデルの環境変数を再設定します。/path/to/Edge0は、リポジトリを取得した実際のパスに置き換えます。 cd /path/to/Edge0 source .venv/bin/activate export EDGE0_35B_MODEL="$PWD/models/edge0-35b" edge0 serve edge0-35b \ --host 127.0.0.1 \ --port 8083 \ --flask サーバーの実行中は最初のターミナルを開いたままにします。別のターミナルで有効にした仮想環境は、新しいシェルに自動では適用されません。 ...

2026年9月14日 · 2 分 ·  rkttu
銀色のノートPCの上に浮かぶガラスのブロックと積み重ねたストレージで表したローカルモデルの推論。

Edge0連載 1: 16GB Macで動かす35BローカルLLMと根拠に基づくエージェント

2026年9月13日時点で、Edge0はApple Silicon向けのMLXバックエンドとEdge0-35B-A3B-previewモデルを公開しています。私は16GBのM2 MacBook Airでこのモデルを実行し、Microsoft Learnの資料を根拠に回答する技術専門エージェントを構成しました。 この連載では、35Bクラスのモデルを動かす条件、検索資料による回答の変化、韓国語の入出力、ストリーミング性能の計測、社内PoCへ拡張する条件を扱います。実行コード全体はEdge0 Microsoft Technology Expert AgentのGistにまとめています。 第1回ではモデルを実行した経験から説明します。外部の根拠を与えた実験と入力資料を短くした結果を比較し、後続の記事で実装するエージェントの構造を紹介します。 公開状況と計測結果には、次の範囲を適用します。 公開文書は2026年9月13日に確認しました。モデルはプレビュー段階にあり、構成や性能は今後変わる可能性があります。実行時間と回答例は私が行った個別の実験記録であり、すべての機器や質問に共通する性能を示すものではありません。 必要な重みをSSDから読み込む35Bモデル Edge0のメモリ利用方式から確認します。プロジェクトの説明によると、Edge0は疎なMoEモデルのエキスパート重みをSSDに置き、推論に必要な部分を読み込みます。このため、起動時にモデル全体をRAMへ読み込む構成とはメモリの利用状況が異なります。 公開モデルの仕様と公式の計測値、私の実験環境を項目ごとに分けて示します。 公開モデル:Edge0-35B-A3B-previewは35BクラスのMoE構造に4ビット量子化を適用しています。 モデルファイルのサイズ:SSDに保存するチェックポイントは約23GBを占めます。 公式のメモリ計測値:短いコンテキストで、MLXアロケーターの最大アクティブメモリが約2.9GiBを記録しました。 個人の実験機器:この連載ではM2 MacBook Air 16GBを使用しました。 最初の生成実験:特定の入力と実行条件で、128トークンの生成に約43.8秒かかりました。 公式のメモリ値はシステム全体の使用量を表していません。OS、トークナイザー、キャッシュ、コンテキスト長による追加の使用量も考慮できます。重みの読み込み経路はアーキテクチャ文書が説明しています。 私の機器でもモデルは文章を生成しました。16GBのノートPCで実行できることを確認したうえで、応答速度と回答の正確さは別々に評価しました。 外部の根拠を中心にした回答生成 質問だけを与えるzero-shotの実験では、C# Native AOTとRustのコンパイルモデルを誤って説明する回答がありました。英語の質問でも同様の誤りが繰り返されました。十分な数の質問を用いた品質評価ではないため、この経験だけでモデル全体の性能は判断していません。 そこで、事実知識をモデル自身に任せる範囲を狭めました。自分で回答を評価できる.NET Native AOTとJITの質問を使い、Microsoft LearnのNative AOT文書を一緒に渡しました。 その後のエージェントでは、役割を次のように分けました。図内の表記は韓国語原稿のまま保持しています。 Edge0 질문과 문서의 내용 파악 관련 근거 선택 근거에 따른 답변 생성 외부 시스템과 Python 호스트 공식 문서 검색 입력 자료 구성 대화 상태 관리 한국어 입출력 처리 実験では、モデルが渡された文書を読み、質問に合う回答を構成できるかに焦点を当てました。 ...

2026年9月13日 · 1 分 ·  rkttu
明るい茶色の五線譜上の C# と分岐するノードで表現したプラットフォーム別の自動配布

netcoredbg 統合 C# 拡張の 8 プラットフォーム自動リリース構築記

2026年9月6日、私が運営する vscode-csharp-autobuild リポジトリで C# (with netcoredbg) 2.148.23001 の初回リリースを完了しました。Windows、Linux、Alpine Linux、macOS の x64 と ARM64 向けパッケージをすべて Open VSX に公開し、公開ファイルのハッシュが検証に使用した VSIX と一致することを確認しました。初回リリースには、C# 拡張と netcoredbg のソースバージョン、プラットフォーム別パッケージ、検証記録をまとめています。 本稿では、既存コミュニティの貢献と AI を活用したプロジェクトの出発点、8 プラットフォームの互換性検証、公開処理が中断した場合の復旧を扱います。定期ワークフローが新しいバージョンを検出すると、ソースビルドから公開ファイルの確認まで処理し、問題があればその候補の公開を停止する構成にしました。今回のリリースを踏まえて考えている後続の開発ツールについても紹介します。 まず別の拡張を作った理由から始め、プラットフォームの互換性問題とテスト範囲を説明します。その後、バージョンの対応付け、初回公開で判明した運用上の問題、実験用ワークフローの整理を取り上げます。最後に VS Code OSS ベースの .NET 開発ツール構想を紹介します。本稿のサポート範囲と実行結果は、2026年9月6日の初回リリースを基準としています。 既存の C# 配布を維持する別の拡張 ID 従来のリポジトリでは、Microsoft の C# 拡張ソースを自動ビルドして Open VSX に公開してきました。対象は C# 拡張であり、C# Dev Kit は含みません。公開用メタデータとビルド環境を調整しつつ、上流拡張の動作とデバッガー実装を維持する配布です。 C# 拡張のソース公開と、同梱デバッガーの利用範囲は別々に考えられます。Microsoft は vsdbg に関する文書で、このデバッガーをプロプライエタリな構成要素と説明し、Microsoft の IDE での利用に制限しています。そのため、拡張を Open VSX に移すだけでは VS Code 派生エディターにおけるデバッガーの制約までは解消できません。 既存の配布には、上流の動作をできる限り維持する価値があります。既存ユーザー全員にデバッガーの置き換えを適用するのではなく、別の拡張 ID を作りました。二つの配布は次の基準で選択できます。 配布 拡張 ID 維持または変更する範囲 従来の C# 配布 dotnetdev-kr-custom.csharp 上流拡張の動作とデバッガー実装を維持 C# (with netcoredbg) dotnetdev-kr-custom.csharp-with-netcoredbg coreclr デバッグアダプターを本リポジトリでビルドした netcoredbg に置き換え コミュニティでは muhammadsammy/free-vscode-csharp がすでに netcoredbg を統合し、VS Code 派生エディターで使える C# 開発環境を提供してきました。私は、このプロジェクトが築いた選択肢と、その過程で積み重ねた貢献に大きな歴史的価値を感じています。代替手段を実際に使える拡張として公開し、維持してきた muhammadsammy と貢献者の皆さんに敬意と感謝を表します。 ...

2026年9月6日 · 3 分 ·  rkttu
構成ファイルが状態管理ツールを経由してユーザー単位の SDK とランタイムコンポーネントへ接続されるイラスト

dotnetup プレビュー: global.json からの SDK とランタイム管理

Microsoft は Microsoft Build 2026 の事前収録セッション OD804 「Simplifying .NET installs with .NET Up」で、ユーザー単位の .NET インストールを管理する新しいツール dotnetup を紹介しました。2026年8月22日現在、dotnet/sdk リポジトリの release/dnup ブランチでは、Windows、macOS、Linux 向けのプレビュー版インストール手順とコマンドリファレンスを公開しています。この記事では、セッションが示した課題と設計意図をもとに、現在のプレビューで確認できる動作を整理します。 dotnetup は管理者権限を使わず、ユーザープロファイル配下に .NET SDK とランタイムをインストールします。リポジトリの global.json を読み取って必要な SDK チャネルを追跡し、複数の要件が共有するインストールファイルを更新または整理します。シェルやアプリケーションが管理対象の dotnet を見つける方法も選択できます。この記事では、インストール方法、global.json の解釈、SDK とランタイムの分離、インストール状態の管理、自動化での利用を扱います。 最初に、既存のインストール方法に残っていた管理上の空白を確認します。次に、プレビュー版のインストールとリポジトリ単位の SDK 準備をたどります。後半ではランタイムと更新モデルを説明し、現在の実装と OD804 のロードマップの差を検討します。 基準日: 2026年8月22日。dotnetup はプレビュー段階であり、コマンド名や動作が変わる可能性があります。この記事は release/dnup ブランチの公式ドキュメントと、同日にダウンロードした 0.2.0-preview.1.26410.1 を基準にしています。 インストールスクリプトより rustup に近い状態管理ツール .NET のインストール経路を一つの管理ツールへまとめる理由から確認します。OD804 セッションは、Windows で Visual Studio がツールチェーンを管理する場合と、それ以外の場合を対比しています。後者では、オペレーティングシステムのパッケージマネージャー、Web インストーラー、dotnet-install スクリプト、DNVM や mise のようなバージョン管理ツールが混在します。インストール主体と更新周期が異なると、必要な SDK を準備して古いインストールを削除する手順もリポジトリごとに変わります。セッションの課題定義は、この差をツールが解決しようとする出発点として示しています。 既存の dotnet-install スクリプトも、管理者権限を使わないインストールをサポートします。ただし、Microsoft はこのスクリプトを、実行のたびに SDK が消えても問題のない CI 環境で主に使うものと説明しています。開発環境にはインストーラーを案内してきました。dotnet-install の公式ドキュメントが、この利用範囲を明記しています。 ...

2026年8月23日 · 3 分 ·  rkttu
dotnet bot が半透明の数字11へ飛んでいく明るい紫色のイラスト

リリースを控えた .NET 11 の変更点と導入判断

Microsoft は .NET 11 の正式版を 2026年11月10日にリリースする予定です。2026年8月23日現在、8月11日に公開された .NET 11 Preview 7 が最新ビルドです。Microsoft はランタイムと SDK、C# 15、ASP.NET Core、.NET MAUI、Entity Framework Core を含む製品群を引き続き調整しています。正式リリースまでに機能や動作が変わる可能性も残っています。Microsoft による .NET 11 Preview 7 の発表 この記事では .NET 11 の変更を、サポート期間、ハードウェア基準、ランタイムと開発ツール、C# 15、アプリケーションフレームワークという五つの軸で整理します。機能の数より、既存サービスの移行に影響する点を中心に扱います。 最初にサポート期間と実行環境を扱い、次に Runtime Async と SDK を確認します。その後で C# 15 の型モデルと ASP.NET Core、EF Core の主な機能を検討します。最後に正式リリース前に適用できる確認手順を示します。 この記事は、次の基準日に公開されていたプレビュー資料をもとに作成しました。 基準日: 2026年8月23日 対象バージョン: .NET 11 Preview 7、SDK 11.0.100-preview.7 状態: プレビュー機能と互換性変更の一覧は正式リリースまでに変わる可能性があります。プレビュービルドは一般に本番環境での利用をサポートしません。 サポート期間を延ばさない STS リリース .NET 11 のサポート期間から整理します。Microsoft は .NET 11 を STS に分類し、2026年11月10日から2028年11月9日までの2年間サポートする予定です。LTS と STS の品質水準は同じで、サポート期間だけが異なります。LTS は3年間、STS は2年間にわたってパッチと技術サポートを提供します。この予定は .NET 11 のリリース計画と .NET のサポートポリシーで確認できます。 ...

2026年8月23日 · 3 分 ·  rkttu
C# 50行でOpenAI Codex CLIを任意のLLMに繋ぐコンセプト画像

OpenAI Codex CLIをClaude・Gemini・Llamaの上で動かす — C# 50行で

OpenAIのCodex CLIは優れたエディタエージェントUXを提供します(shellツール、apply_patch、plan tracking がすべて揃っています)。問題は、2026年2月時点でOpenAI Responses APIだけをサポートしていることです。Chat Completionサポートは削除されており(codex-rs/model-provider-info/src/lib.rsのWireApi enumにはResponsesのみが残っています)、Chat Completionのみをサポートするエンドポイント(Ollama、LM Studio、お気に入りのLlama runner)はそのまま閉ざされてしまいます。本記事は.NET 10のfile-basedプログラムとMicrosoft.Extensions.AIのIChatClient抽象化を活用し、50行のC#一ファイルでResponses互換サーバーを立て、OpenRouterを介してCodex CLIを任意のモデル上で動作させた過程をまとめます。 はじめに Codex CLIはResponsesを話すどんなサーバーとも気持ちよく対話します。model_provider configブロックがまさにこのために存在します。つまり、好きなモデルでバックされたResponses互換HTTPエンドポイントを立てさえすれば、Codexは汎用フロントエンドになり、頭脳はユーザーが選べます。 最近私が気に入っているトリックは次のとおりです。Microsoft.Extensions.AIのベンダー中立なIChatClient抽象化の上で、OpenAI Chat CompletionサーバーとResponses APIサーバーを同時に動かす50行のC#スクリプトを起動します。バックエンドはOpenRouterに向けます(APIキー1つで Claude、Gemini、Llama、GPTなど数百のモデルを使えます)。そしてCodexに対して、OpenAIではなくこのローカルスクリプトと対話するよう設定します。 最終的な結果は、OpenAI Codex CLIがAnthropicのClaude 3.5 Sonnetの上で動作する状態です(あるいはその日に使いたい別のモデルの上でも)。 構成要素 私が自分で公開しているCadenza.AgentというMSBuild SDKを使います。単一の.csファイルを実行可能なエージェントサーバーに変換するSDKで、.NET 10のfile-basedプログラム向け単一ファイルスクリプティングSDKファミリーの一部です(dotnet run script.csと同じ発想ですが、より豊富なTier-1 API(Tool、UseOllama、UseOpenAi、Runなど)を提供します)。Agentバリアントは次を公開します。 POST /v1/chat/completions — Aider / Continue / Cursor / Copilot BYOK / sgpt 向け POST /v1/responses — Codex CLI 向け どちらもユーザーが構成した同じIChatClientでバックされます。バックエンドを変えても wireフォーマットはそのままです。 LLM側はOpenRouterを使います。OpenAIのChat Completion wireフォーマットを別のbase URLでそのまま提供するので、Microsoft.Extensions.AI.OpenAIのChatClientをそのまま挿して使えます。環境変数1つ、任意のモデル。 Codexの設定はCODEX_HOME環境変数のトリックを活用します。~/.codex/config.tomlを編集する代わりに、Codexが指すディレクトリをサンプル専用に別途作っておけば、そこから新しいconfig.tomlを読みます。これでユーザーのグローバル設定に一切触れない、自己完結型のサンプルが作れます。 スクリプト バックエンドのすべて、ファイル1つです。 #!/usr/bin/env dotnet run #:sdk Cadenza.Agent@1.0.14 using System.ClientModel; using OpenAI; var apiKey = Env.Get("OPENROUTER_API_KEY") ?? throw new InvalidOperationException("OPENROUTER_API_KEY env var missing"); var model = Env.Get("OPENROUTER_MODEL") ?? "anthropic/claude-3.5-sonnet"; ServedModelName = "cadenza-codex-openrouter"; // サンプル専用のCodex homeディレクトリを作成。 var codexHome = Path.Combine(Env.Cwd, ".cadenza-codex-openrouter"); MakeDir(codexHome); var catalogPath = Path.Combine(codexHome, "cadenza-catalog.json").Replace('\\', '/'); var configToml = $""" model = "cadenza-codex-openrouter" model_provider = "cadenza" model_catalog_json = "{catalogPath}" [model_providers.cadenza] name = "Cadenza.Agent (OpenRouter-backed)" base_url = "http://localhost:8080/v1" wire_api = "responses" env_key = "CADENZA_API_KEY" stream_idle_timeout_ms = 300000 """; WriteText(Path.Combine(codexHome, "config.toml"), configToml); // Catalog JSON: Codex に提供するモデル id を宣言して "Defaulting to // fallback metadata" 警告を防ぎます。フィールドは codex-rs/protocol/src/ // openai_models.rs の ModelInfo スキーマ基準 — すべてのキーが必須です。 var catalogJson = """ { "models": [{ "slug": "cadenza-codex-openrouter", "display_name": "Cadenza (OpenRouter)", "description": "OpenRouter-backed agent served by Cadenza.Agent", "supported_reasoning_levels": [], "shell_type": "default", "visibility": "list", "supported_in_api": true, "priority": 50, "availability_nux": null, "upgrade": null, "base_instructions": "", "supports_reasoning_summaries": false, "support_verbosity": false, "default_verbosity": null, "apply_patch_tool_type": "freeform", "truncation_policy": { "mode": "tokens", "limit": 8192 }, "supports_parallel_tool_calls": true, "context_window": 200000, "max_context_window": 200000, "auto_compact_token_limit": 180000, "effective_context_window_percent": 95, "experimental_supported_tools": [] }] } """; WriteText(Path.Combine(codexHome, "cadenza-catalog.json"), catalogJson); WriteLine($"Codex config generated at: {codexHome}"); WriteLine("In another terminal, run:"); WriteLine($" $env:CODEX_HOME = \"{codexHome}\""); WriteLine($" $env:CADENZA_API_KEY = \"any-non-empty-string\""); WriteLine($" codex"); // OpenRouter を LLM バックエンドとして接続。 var openAiOptions = new OpenAIClientOptions { Endpoint = new Uri("https://openrouter.ai/api/v1") }; var chatClient = new OpenAI.Chat.ChatClient(model, new ApiKeyCredential(apiKey), openAiOptions) .AsIChatClient(); UseChatClient(chatClient); await Run(); これがすべてです。プロジェクトファイルも、.csprojも、Program.csもありません。一番上の#:sdkディレクティブが.NET 10のfile-basedプログラムシステムに「このスクリプトはCadenza.Agent SDKを使う」と知らせ、SDKがHTTPサーバー、Responses wireフォーマット、すべてのパッケージ参照を引き込みつつ、Tool、UseOllama、UseChatClient、Runを名前空間なしですぐ呼べる名前として公開します。 ...

2026年5月27日 · 3 分 ·  rkttu
C#とPythonが出会う機械学習インターロップの概念図

C#からHugging Faceモデルを呼ぶ:DotNetPy 0.6.0でWhisper・sentence-transformers・Stable Diffusionを動かす

週末に小さなC#ライブラリ DotNetPy の0.6.0をリリースしました。CPythonのC APIを直接呼び出して、.NETアプリの中でPythonを動かすインターロップライブラリです。本記事は0.6.0に含まれる3つの機械学習サンプル(sentence-transformersによる意味検索、Whisperによる音声認識、Stable Diffusion Turboによる画像生成)をどうまとめたか、そしてその過程でPEP 703 free-threaded CPythonをどのように検証したかを記録したものです。 出発点:手元にあるのはC#だけ、モデルはHugging Faceにある 数か月ごとに同じパターンが繰り返されます。字幕用にWhisperが必要、検索用にsentence-transformerが必要、ときにはStable Diffusionのようなモデルを使いたい。しかし手元にあるのはC#一つだけ。こんなとき、よく取られる回避策にはそれぞれ決定的な欠点があります。 ONNXに変換する。 画像系やエンコーダ系のモデルにはよく合いますが、新しいアーキテクチャやdiffusionパイプラインでは、変換そのものが別プロジェクトになります。 Pythonマイクロサービスとして立ち上げる。 プロセスが2つ、デプロイのシナリオが2つ、そしてホットパスにネットワークホップが1つ追加されます。 外部APIを呼び出す。 コストがかかり、インターネット接続が必要で、データが箱の外に出ます。 pythonnet や CSnakes を使う。 堅実な選択肢ですが、pythonnetはまだNative AOTをサポートしておらず、CSnakesはSource Generatorベースのワークフローを強制します。さらに、両ライブラリともfree-threaded CPythonビルドに対する公開された検証結果をまだ出していません。 私はもう少し薄い選択肢が欲しかったのです。C#コードの中にPythonスニペットを文字列としてインラインで書き、配列をそのまま渡し、JSON形式で結果を受け取り、全体がAOTコンパイルされて単一バイナリになる 形です。それがDotNetPyの目標であり、以下の3つのサンプルはすべてGPUのない普通のWindows 11ノートPCで最初から最後まで動作します。 サンプル1 — sentence-transformers による意味検索 最初のサンプルは小さなコーパスを埋め込み、クエリをエンコードして、最も類似する上位K件の文を返します。戻り値はDotNetPyValueで、内部的にはJSONドキュメントをラップしたもので、GetString()・GetInt32()・GetDouble()、そしてパスベースのプロパティアクセスを通じて.NETの世界に戻ってきます。 using DotNetPy; using DotNetPy.Uv; using var project = PythonProject.CreateBuilder() .WithProjectName("dotnetpy-ml-embeddings") .WithPythonVersion("==3.12.*") .AddDependencies( "sentence-transformers==2.7.0", "transformers==4.40.2", "torch>=2.2,<2.5") .Build(); await project.InitializeAsync(); var executor = project.GetExecutor(); executor.Execute(@" import numpy as np from sentence_transformers import SentenceTransformer model = SentenceTransformer('all-MiniLM-L6-v2') "); var corpus = new[] { "Python is a popular programming language for data science.", "C# and .NET are great for building enterprise applications.", "Rust offers memory safety without garbage collection.", "Pizza is delicious with various toppings.", // … }; var query = "Tell me about programming languages"; using var hits = executor.ExecuteAndCapture(@" corpus_emb = model.encode(corpus, normalize_embeddings=True) query_emb = model.encode([query], normalize_embeddings=True)[0] sims = corpus_emb @ query_emb top_idx = np.argsort(-sims)[:3] result = [ {'rank': int(rank + 1), 'score': float(sims[i]), 'text': corpus[int(i)]} for rank, i in enumerate(top_idx) ] ", new Dictionary<string, object?> { { "corpus", corpus }, { "query", query } }); foreach (var hit in hits!.RootElement.EnumerateArray()) { Console.WriteLine($" {hit.GetProperty("rank").GetInt32()}. " + $"[{hit.GetProperty("score").GetDouble():F3}] " + $"{hit.GetProperty("text").GetString()}"); } 実際の出力はこうなります。 ...

2026年5月11日 · 4 分 ·  rkttu
クラウドプラットフォームアーキテクチャのコンセプトイメージ

RoleEntryPointからFoundryCBAgentまで — .NET開発者が見たMicrosoft Foundry Hosted Agentのアーキテクチャ

この記事は2026年3月時点で、パブリックプレビュー状態にあるMicrosoft Foundry Hosted Agentの設計を、.NETアーキテクチャの系譜の中で分析します。現時点でプロダクション利用を推奨する記事ではなく、エンタープライズAIアーキテクトが注目すべき設計の方向性に焦点を当てています。 エージェントをプロダクションに載せるということ エンタープライズでAIエージェントをプロダクションにデプロイしようとする際、現在の選択肢は2つです。 宣言的エージェント。 Microsoft Foundryポータルでプロンプトとツールを組み合わせて作るno-code方式です。素早く作成できますが、複雑な分岐ロジックやマルチステップワークフロー、外部システムとの精密な連携をコードで制御できません。一定レベルを超えた瞬間に限界に突き当たります。 セルフホストコンテナ。 エージェントロジックをコードで直接記述し、コンテナに入れてデプロイする方式です。自由度は完全ですが、HTTPサーバー構成、認証、会話状態管理、スケーリング、モニタリング、バージョン管理をすべて自前で実装する必要があります。そして決定的に、コンテナ内でエージェントが何をしているか プラットフォームには一切わかりません。 LLMをどう呼び出したか、ツールをどの順序で使ったか、なぜそのレスポンスを生成したかがブラックボックスです。 Hosted Agentはこの間の空白を埋めます。コードレベルの自由度を維持しつつ、エージェントの動作がプラットフォームに構造的に透明に公開される第3の道です。 Windows Azureを覚えていますか 現在のMicrosoft Azureは、2010年2月に Windows Azure という名前で商用リリースされました。2014年3月にMicrosoft Azureにリブランディングされるまで、このプラットフォームのアイデンティティは現在とはかなり異なっていました。 Windows Azureは本質的に PaaSプラットフォーム でした。VMを直接操作するIaaSは当初存在せず、2012年になってようやくVirtual Machinesが追加されました。出発点はCloud Services(Web Role、Worker Role)、SQL Azure(現在のAzure SQL Database)、Storage Servicesのようなマネージドサービスでした。開発者がインフラを意識せずコードと設定ファイルだけでデプロイすることが核心の約束であり、これは当時AWSがEC2中心のIaaSで市場を切り開いていたのとは根本的に異なるアプローチでした。 2014年のリブランディング後、AzureはAWSを強く意識しながらIaaS機能を急速に拡充しました。VM、VNET、Load Balancer、そして後のAKSまで。市場で「クラウド=仮想マシンを借りて使うこと」という認識が支配的だった時期にIaaSを強化したのは商業的に正しい判断でしたが、その過程でWindows Azure時代のPaaS中心の哲学は多少希薄化しました。 しかしMicrosoftの本来の強みは常にPaaSとSaaSにありました。.NET Framework、Visual Studio、SQL Server、Office 365、SharePoint — この会社は開発者とインフォメーションワーカーに マネージドプラットフォーム 上で働かせることに30年以上の歴史を持っています。Windows Azure時代のCloud Servicesはその哲学のクラウド拡張であり、その後のApp Service、Azure Functions、Container Appsも同じ文脈にあります。 この背景を理解すると、Hosted Agentがなぜこの形で設計されたかが明確になります。MicrosoftはAIエージェントという新しいワークロードに対して、IaaS的アプローチ(セルフホストコンテナを直接管理)ではなくPaaS的アプローチ(プラットフォームがホスティングし、開発者はロジックに集中)を選択したのです。これはAWSがBedrock Agentsで取る方向とも、GoogleがVertex AI Agent Builderで取る方向とも異なります。MicrosoftのPaaS DNAがAI時代に再び発現したと見ることができます。 どこかで見たパターン .NET開発者であれば、そしてAzureの歴史を共に歩んできた開発者であれば、Hosted Agentのアーキテクチャに強いデジャヴを感じるでしょう。 Windows Azure Cloud Servicesの時代を思い出してみましょう。あの時も「開発者はビジネスロジックだけを書き、プラットフォームが提供するホストプロセスがそのロジックを包んでインフラに載せる」というのが核心の約束でした。RoleEntryPointを継承し、OnStart()、Run()、OnStop()を実装すれば、WaWorkerHost.exeがそのコードをロードして実行し、Fabric Controllerがインスタンスのプロビジョニングとヘルスモニタリングを担当していました。 Hosted Agentの構造は、このパターンをAIエージェントドメインに再解釈したものです。 Windows Azure Cloud Services Microsoft Foundry Hosted Agent RoleEntryPoint 抽象クラス FoundryCBAgent / IAgentInvocation インターフェース OnStart(), Run(), OnStop() InvokeAsync() + liveness/readinessプローブ WaIISHost.exe / WaWorkerHost.exe AgentServerアダプター内蔵Kestrelサーバー .csdef + .cscfg agent.yaml + 環境変数 Fabric Controller Agent Service Runtime DiagnosticMonitor (WAD) OpenTelemetry自動計装 + Application Insights Input/Internal Endpoint宣言 Foundry Responses APIプロトコル自動公開 核心的な共通点は3つです。プラットフォームのホストプロセスが開発者コードをロードする構造、プラットフォームが定義した契約(contract)に合わせてコードを書くルール、インフラの関心事がプラットフォームに移転する効果。15年前にCloud Servicesで機能したこの設計原則が、今AIエージェントという新しいワークロードに再び適用されています。 ...

2026年3月17日 · 3 分 ·  rkttu
単一のC#ファイルで実行されるコードのコンセプトイメージ

.NETの新ジャンル:NuGet-Free Single File C#コーディングの時代

C#がスクリプト言語のように軽くなるのではなく、スクリプト言語が羨むほど速くなるということです。 はじめに .NET 10で導入されたdotnet run file.cs——いわゆる** file-based app**——は、.csprojファイルなしで単一の.csファイルだけでC#コードを実行できる機能です。しかし、現在この機能の実行速度は初回実行基準でWindowsで約1.5秒、WSL2で約0.8秒レベルです。Pythonのpython script.pyが50ms前後であることと比較すると、まだ「スクリプティング」と呼ぶには物足りない水準です。 しかし、現在.NETエコシステムで同時に進行中の2つの大きな変化が、この状況を根本的に変える可能性があります: dotnet run file.csのビルド最適化 — MSBuildをバイパスしてRoslynを直接呼び出す戦略 Runtime Async (async2) — async/awaitをランタイムレベルで処理し、ステートマシンのオーバーヘッドを除去 この2つが組み合わさると、** NuGetパッケージなしでBCLだけで書くシングルファイルC#プログラム** が独立したコーディングジャンルとして確立される可能性があります。この記事では、その技術的基盤と将来像を描きます。 File-Based Appの現状:MSBuildというボトルネック 本質:.csproj + .cs = 1つの.cs File-based appはC#スクリプト(.csx)とは根本的に異なります。.csxは別のスクリプトホストがランタイムで解釈しますが、file-based appは** コンパイル時に仮想.csprojに変換** されて正規のビルドパイプラインを通ります。出力は通常のプロジェクトと同一のmanaged DLLです。 // これらのディレクティブが.csprojの内容になる #:package System.CommandLine@2.0.0 // ここからが実際のコード Console.WriteLine("Hello, file-based app!"); 問題:MSBuildの重さ dotnet run hello.csを実行すると内部で起こること: ステップ 所要時間(概算) 説明 CLIロード ~200ms .NETランタイムJIT、CLIコマンドディスパッチ MSBuildエンジンロード ~200ms ビルドエンジン初期化 SDK targets評価 ~300ms 数百の.props/.targetsファイルの順次評価 NuGet restore ~100ms+ パッケージ依存性解決(キャッシュ済みの場合) Roslynコンパイル ~200ms 実際のC# → IL変換 実行 ~50ms 結果のDLL実行 合計約1.5秒 のうち実際の「コンパイル+実行」は約250msに過ぎません。残りはすべてMSBuild関連のオーバーヘッドです。 ...

2026年3月16日 · 4 分 ·  rkttu
虫眼鏡でコードを検査するコンセプトイメージ

AIが見たことのない.NET UIフレームワークでIDEを作るとき、エージェントはどうやってAPIを把握するのか

2026-02-08 — LibraStudio開発記 #1 背景 なぜまた別の.NET IDEなのか .NETエコシステムにおけるIDEの選択肢は、実はそれほど広くありません。Visual Studioは強力ですがWindows専用であり、Community Editionでさえ商用利用に制約があります。VS Code + C# Dev Kitの組み合わせも優れていますが、C# Dev Kitがプロプライエタリライセンスである点は変わりません。結局、重要な部分でベンダーロックインが発生し、その上に構築したツールチェーンとワークフロー全体が特定ベンダーの意思決定に依存してしまいます。 かつてはSharpDevelopがWindowsで、MonoDevelop(Xamarin Studio)がクロスプラットフォームでその役割を担っていました。しかしSharpDevelopは2017年に開発が停止し、MonoDevelopはXamarinに統合された後、事実上スタンドアロンIDEとしての役目を終えました。それ以降、最新の.NET(Core以降)開発環境を適切にサポートする** オープンソースでリベラルライセンスのクロスプラットフォームIDE** は登場していません。 この点がずっと惜しいと感じていました。そこでLibraStudioを始めました。ElectronやVS Codeベースではなく、純粋な.NETネイティブIDEを目指します。一人でVisual Studioレベルのものを作ろうというわけではありません。しかし2026年にはAIベースのコードエディタの力を借りることができます。AIエージェントにフレームワークAPIの探索、ボイラープレートの生成、繰り返しの実装を委任すれば、一人でカバーできる範囲は過去とはまったく異なります。 UIフレームワークにはAprillz.MewUIを使用しています。NativeAOTに対応し、XAMLなしでC#コードだけでUIを構築する軽量フレームワークです。このフレームワークは、私と同じく韓国の代表的な.NET開発者コミュニティであるDotNetDev(.NET Dev、https://forum.dotnetdev.kr/)で活動しているソン・ヨンジェ氏のオープンソースプロジェクトです。 AIが知らない新生フレームワークという難関 MewUIはまったく新しいコンセプトの新生UIフレームワークです。XAMLベースのWPFやAvaloniaUIとは異なり、純粋なC# fluent APIでUIを構築する独自の設計を持っています。当然、公式ドキュメントが豊富ではなく、Stack Overflowに関連する質問が蓄積されてもいません。 これに.NETというプラットフォーム自体の問題も重なります。大規模言語モデルの学習データにおいて、.NET/C#はJavaScriptやPythonに比べて相対的に学習頻度が低いです。メジャーフレームワークであるWPFやWinFormsでさえ不正確なコードを生成することがあるのに、学習データにほとんど含まれていないMewUIのAPIを正確に当てる可能性は極めて低いです。 このような状況でAIコーディングエージェントに「最小限のタブベースのテキストエディタを作ってください」と依頼すると、何が起こるでしょうか。 一般的なアプローチ:推測と反復 通常のAIコーディングエージェントのワークフローは次のとおりです: 学習データから類似のAPIを思い出してコードを書きます ビルドします エラーが出たらエラーメッセージを見て修正します 2〜3を繰り返します この方式は、学習データに豊富に含まれているメジャーフレームワーク(WPF、React、SwiftUIなど)ではうまく機能します。しかし、MewUIのようにまったく新しいコンセプトの新生フレームワーク――しかも相対的に学習頻度が低い.NETベース――では、** 推測の精度が極めて低くなります**。メソッド名、パラメータの順序、オーバーロードの有無、イベントシグネチャ――すべてが外れる可能性があります。 別のアプローチ:アセンブリを直接覗く 今回の作業では、私自身が開発したHandMirror MCPを使用しました。HandMirrorは、NuGetパッケージの** コンパイル済みアセンブリを直接検査する** MCP(Model Context Protocol)サーバーです。 Webドキュメントを検索する代わりに、実際の.dllを分析し、次の情報を返します。注目すべきは、HandMirrorが一般的な.NETリフレクション(System.Reflection)ではなくMono.Cecilを使用している点です。Cecilは.NETアセンブリのメタデータをランタイムロードなしに直接読み取るため、検査対象アセンブリの.NETランタイムバージョンに影響されません。.NET Framework 4.x用ライブラリでも.NET 10対象でも同様に分析できます: すべての名前空間と型の一覧 各型のコンストラクタ、プロパティ、メソッド、イベントのシグネチャ Extension methodがどの名前空間にあるか 継承階層構造 実際に得られた情報 Aprillz.MewUI v0.9.1を検査した結果: 178個のパブリック型、14個の名前空間 MultiLineTextBoxがTextBaseを継承し、Text、Placeholder、AcceptTab、Wrap、IsReadOnlyなどのプロパティを持つこと TabControl.SelectionChangedがAction<int>であること(ドキュメントがなければAction<TabItem>と推測していたでしょう――実際そうでした) FileDialog.OpenFile()がOpenFileDialogOptionsを受け取り、Title、Filter、Ownerなどのプロパティを持つこと Menu.Item()とContextMenu.Item()のオーバーロードが異なること――Menu.Itemにはショートカット文字列パラメータがない ObservableValue<T>がSubscribe()、NotifyChanged()、Set()メソッドを持つこと この情報だけで、エディタのコアコードをほぼ正確に記述できました。 結果:初回ビルドでエラー3個 コード全体を書き上げた後、初回ビルドで発生したエラーはわずか3個でした: エラー 原因 Menu.Item("text", "shortcut", action) — オーバーロードなし ContextMenu.ItemにしかないショートカットパラメータをMenu.Itemでも使用 BorderThickness(0, 1, 0, 0) — 4パラメータのオーバーロードなし 実際にはBorderThickness(double)の単一パラメータのみ存在 SelectionChangedの型不一致 HandMirrorがAction<int>と教えてくれたが、コードで誤ってAction<TabItem>を使用 3つ目は純粋に** 読み取った情報をコードに誤って反映したミス** でした。HandMirrorが提供した情報自体は正確でした。 ...

2026年2月8日 · 2 分 ·  rkttu