TECH PLAY

サイオステクノロジー(Tech.Lab)

サイオステクノロジー(Tech.Lab) の技術ブログ

546

こんにちは。サイオステクノロジーの木村です。 今回は、mod_auth_basic でBasic認証する手順について記載します。 mod_auth_basic は、Apache HTTP Server におけるBasic認証を実現するモジュールです。検証環境などで、まずは簡易的に認証を導入したい場合などに手軽に利用できる仕組みとして便利です。 以下の手順ではHTTPで説明していますが、通信内容が平文で送信されるためHTTPSを利用するなど注意が必要です。 Apacheのモジュールを使用したOIDC認証について記載した以下の記事もございますので、あわせてご参照ください。 Apache【mod_auth_openidc】×【Entra ID】:OpenID Connect認証でシングルサインオン 検証環境 Rocky Linux 9.0 Apache 2.4.62 手順 Apache のインストールと確認 ・インストール・バージョン確認 $ sudo dnf install -y httpd $ httpd -v ・モジュールの確認 mod_auth_basic は Apache HTTP Server のコアモジュールの一つであり、Apache をインストールすると基本的にデフォルトで含まれます。以下でモジュールがロードされているか確認します。 $ httpd -M | grep auth_basic_module auth_basic_module (shared) と表示されればモジュールがロードされています。 ・Apache の起動と自動起動設定 $ sudo systemctl start httpd $ sudo systemctl enable httpd ブラウザで http://[サーバIP]/ にアクセスし、Apache のデフォルトのテストページが表示されれば、インストールと起動が正常に完了していることを確認できます。 Rocky Linux 9 では、デフォルトで firewalld が有効化されており、HTTP が許可されていない場合、外部からのアクセスが制限されます。アクセス可能にするには以下のコマンドを実行します。(以下は HTTP および HTTPS を許可する場合) $ sudo firewall-cmd --permanent --add-service=http $ sudo firewall-cmd --permanent --add-service=https $ sudo firewall-cmd --reload 認証ファイルの作成 Basic認証で使用するユーザー名とパスワードを格納する「認証ファイル」を作成します。 認証情報はファイル以外にも、LDAP サーバーやデータベースなどと連携して管理することもできます。 ・認証ファイルの作成とユーザ追加 $ sudo htpasswd -c /etc/httpd/.htpasswd [ユーザー名] -c は新規作成を意味します。2人目以降を追加する場合は -c を付けずに実行してください。 コマンドを実行すると、パスワードの入力を求められるので、パスワードを入力します。 ・認証ファイルの確認 $ cat /etc/httpd/.htpasswd 認証後に表示するページの作成 今回はPHPで作成します。 /var/www/html/secure/index.php を以下の内容で作成します。 <?php echo "<h1>Basic認証テスト</h1>"; echo "<p>こんにちは、" . htmlspecialchars($_SERVER['REMOTE_USER']) . " さん.</p>"; ?> Apache 上で PHP を動かすため、モジュールがインストールされていない場合は、以下のコマンドでインストールします。 $ sudo dnf install -y \ php php-cli php-common php-fpm php-mbstring php-xml php-json Basic認証の設定 ・設定ファイルの作成 $ sudo vi /etc/httpd/conf.d/basic-auth.conf 以下の内容を記載し保存します。 <Location "/secure/"> AuthType Basic AuthName "Restricted Area" AuthUserFile /etc/httpd/.htpasswd Require valid-user </Location> ・設定の反映 設定を反映するため Apache を再起動します。 $ sudo systemctl restart httpd 動作確認 ブラウザで http://[サーバIP]/secure/index.php にアクセスします。 ユーザー名とパスワードの入力を求めるダイアログが表示されますので「認証ファイルの作成」の手順で作成したユーザー名とパスワードを入力します。 PHPで作成したページに遷移し、ユーザー名が表示されます。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Apache【mod_auth_basic】でBasic認証 first appeared on SIOS Tech. Lab .
アバター
こんな方へ特におすすめ 「自分専用のChatGPT」を作ってみたいと思っている方 RAGやLLM(大規模言語モデル)の具体的な使い方に興味がある方 Pythonとオープンソース技術で、何か面白いものを作りたい開発者 概要 こんにちは。サイオステクノロジーのはらちゃんです!AI相棒の開発ブログ、第一弾へようこそ! このページでは「 AI相棒 」を、話題の技術 RAG とオープンソースのツールを駆使して開発した軌跡をご紹介します。 APIを使った簡単な方法から、最終的にはPCの中だけで完結する完全ローカル環境の構築まで、試行錯誤の過程をステップバイステップで解説します。この記事を読めば、きっとあなたも自分だけのAI相棒が欲しくなるはずです! RAGの育て方を試行したブログも執筆予定ですので合わせて覗いてもらえると嬉しいです。 今回の完成イメージです。 コードで最も簡単に開発する方法 |LlamaIndex はじめに、今から使う基盤となるものを簡単に紹介します。 LlamaIndex は、RAGシステムを構築することに特化したフレームワークで、非常に直感的かつ少ないコード量で実装できるのが特徴です。 なぜ簡単? 抽象化 データ読み込み、ベクトル化、保存、検索、LLMとの連携といった複雑な処理を、フレームワークが裏側で自動的にやってくれます。 設定が少ない OpenAIのAPIキーさえあれば、Embeddingモデルやベクトルストアの難しい設定を気にせず始められます。 環境構築が容易 Pythonと数個のライブラリをインストールするだけですぐに試せます。 今回は以下の構成で手軽に実装を試したいと思います。 your_project/ │ ├── data/ │ └── knowledge.txt │ └── app.py Step1:APIでAI相棒を爆速起動 それでは早速作っていきましょう。 何事も、まずは小さく始めるのが成功の秘訣です。最初は、自分のPCに負荷をかけず、無料で使えるAPIサービス Groq を利用して、AI相棒のプロトタイプを作成しました。 準備 LlamaIndex と Groq を連携させるためのライブラリをインストールし、 knowledge.txt というファイルにAI相棒に覚えてほしい情報(今回は架空のプロジェクト情報)を書き込みます。 Bash pip install llama-index openai #ライブラリの追加 pip install llama-index-llms-groq llama-index-embeddings-huggingface APIキーの取得 Groqの公式サイト にサインアップします。 画面左のメニューから「API Keys」を選択します。 「+ Create API Key」ボタンをクリックします。 自分で分かりやすいキーの名前を入力し、作成します。 表示されたAPIキーをコピーします。 このキーは一度しか表示されないため、必ず安全な場所に控えておいてください。 コーディング 驚くことに、コードはたったこれだけです。 LlamaIndex が、データの読み込みからインデックス作成、質問応答までの複雑な処理をすべて裏側でよしなにやってくれます。ポイントは、LLMに Groq を、文章をベクトル化するEmbeddingモデルにオープンソースのものを指定している点です。 「gsk_あなたのGroqのAPIキー」と書かれている部分に先ほど取得したAPIキーを書き込んでください。 app.py import os from llama_index.core import ( VectorStoreIndex, SimpleDirectoryReader, Settings, ) from llama_index.llms.groq import Groq from llama_index.embeddings.huggingface import HuggingFaceEmbedding # 1. GroqのAPIキーを設定 os.environ["GROQ_API_KEY"] = "gsk_あなたのGroqのAPIキー" # 2. LLMをGroqが提供する最新のモデルに変更 Settings.llm = Groq(model="llama-3.1-8b-instant") # 3. EmbeddingモデルをHuggingFaceの無料モデルに設定 Settings.embed_model = HuggingFaceEmbedding( model_name="BAAI/bge-small-en-v1.5" ) # 4. データの読み込み、インデックスの作成、クエリエンジンの構築 print("データを読み込んでいます...") documents = SimpleDirectoryReader("data").load_data() print("インデックスを作成しています...") index = VectorStoreIndex.from_documents( documents, ) print("クエリエンジンを作成しました。質問を入力してください。") query_engine = index.as_query_engine() while True: query = input("質問: ") if query == "exit": break # フレンドリーな口調で答えるよう指示文を付加 friendly_prompt = f"次の質問にフレンドリーな口調で答えて:{query}" response = query_engine.query(friendly_prompt) print("回答:", response) 実行 これだけでもチャットを実行させることができるので、 knowledge.txt を自由に記述して試してみてください。 Bash python app.py このような入力画面が立ち上がれば実行成功です。 knowledge.txt の書き方 AIが情報を効率よく見つけ出せるように、少しだけ書き方を工夫すると性能が上がります。 一つの段落には一つのトピック 関連する情報は近くにまとめて書くと、AIが文脈を理解しやすくなります。 見出しや箇条書きを活用する 人間が読みやすいように情報を整理すると、AIにとっても処理しやすくなります。 「未来の自分は他人」だと思って書く 自分だけが分かるような省略語や暗黙の前提を避け、誰が読んでも分かるように具体的に書くことが重要です。 data/knowledge.txt ## RAG学習用情報テンプレート(仕事用) ### ユーザーのプロフィール - 名前/ニックネーム: - 職業/役割: - 所属部署/チーム: - 得意分野/苦手分野: ### コミュニケーション方針 - 呼び方: - 好ましい対応例: - 避けてほしい対応例: ### よく使う言葉・口癖 - 例: ### 目標・課題 - 現在の目標: - 直面している課題: ### サポートしてほしいこと - 具体的なサポート内容: ### その他メモ - 自由記述: --- ## RAG学習用情報テンプレート(趣味・プライベート用) ### ユーザーのプロフィール - 名前/ニックネーム: - 趣味・関心: - よく行く場所: ### コミュニケーション方針 - 呼び方: - 好ましい対応例: - 避けてほしい対応例: ### よく使う言葉・口癖 - 例: ### 目標・課題 - 現在の目標: - 直面している課題: ### サポートしてほしいこと - 具体的なサポート内容: ### その他メモ - 自由記述: トラブルシューティング 実は、開発中に「指定したモデルは提供終了しました」というエラーに2度も遭遇しました。AIの世界の進化の速さを肌で感じた瞬間です。これは、 Groq の公式サイトで利用可能な最新モデル名を確認し、コードを修正することで簡単に解決できました。 Groqのモデル一覧ページ にアクセスします。 ページに表示されているモデルのリストから、利用したいモデルの「Model ID」をコピーします。 コピーした「Model ID」を、 app.py の Groq(model="...") の部分に貼り付けます。 Step2:Ollamaで完全ローカルなAI相棒へ進化 続いて、APIで手応えを掴んだところで、本命の 「完全ローカル環境」 の構築に挑戦します。これぞオープンソースの醍醐味!インターネットに繋がっていなくても、自分のPCの中だけでAIが動く世界を目指します。 Ollamaのセットアップ Ollama は、様々なオープンソースLLMをコマンド一つで簡単にPCにインストール・実行できる魔法のようなツールです。 公式サイトからインストーラーをダウンロードし、ターミナルで以下のコマンドを実行するだけで、Googleの高性能モデル gemma:7b がPCにインストールされます。 注意点として、WSL環境では ollama serve で手動起動が必要です。現在のターミナルで、以下のコマンドを実行してOllamaサーバーを起動します。 Bash ollama serve 新しいターミナルで、モデル実行コマンドを入力します。 Bash ollama run gemma:7b LlamaIndexとの連携 次に、 app.py のLLM指定部分を、先ほどPCにインストールしたOllamaのモデルに向けるだけです。APIキーの記述はもう必要ありません。 app.py from llama_index.llms.ollama import Ollama # LLMをOllamaで動いているローカルモデルに変更 Settings.llm = Ollama(model="gemma:7b", request_timeout=120.0) 実行 このスクリプトを実行すると、見事に回答が返ってきました。 Bash ollama run gemma:7b このような入力画面が立ち上がれば実行成功です。 まとめ 今回は 「 自分だけのAI相棒作り 」 をしていきました。 LlamaIndex や Ollama といったオープンソースツールのおかげで、専門家でなくても驚くほど簡単にRAGシステムを構築できることがお分かりいただけたかと思います。 APIを使えば、数行のコードで爆速プロトタイピングが可能。 Ollamaを使えば、オフラインで動作するプライベートな環境も実現できる。 このブログが、皆さんの「何か作ってみたい」という気持ちを刺激できたら嬉しいです。まずはこの記事のコードを真似して、あなた自身のメモやブログ記事を読み込ませてみてください。きっと、最高の「AI相棒」が生まれるはずです。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post RAGの作り方|LlamaIndexで簡単2ステップ first appeared on SIOS Tech. Lab .
アバター
今号では、nftables で設定可能なオプションや、様々な設定方法について、もう少し深堀りして説明します! 代表的なオプション -a (もしくは –handle) オプション 前回の記事 でもご説明した通り、ハンドル番号を表示します。 # nft --handle list chain inet table1 chain1 table inet table1 { chain chain1 { # handle 1 type filter hook input priority filter; policy accept; tcp dport 22 accept # handle 2 tcp dport 80 accept # handle 3 } } -f オプション ファイルに記載されたルールセットを読み込みます。 nftabels のルールは nft ファイル に定義します。例えば、 test.nft というファイルに、下記の内容で新たにテーブル、チェーン、ルールを追加するとします。 table inet table2 { chain chain2 { type filter hook input priority filter; policy accept; tcp dport 25 accept } } test.nft を -f オプション を指定して読み込みます。 # nft -f test.nft nft list ruleset コマンドでルールセットを確認してみると、test.nft で指定したテーブル、チェーン、ルールが追加されたことが分かります。 # nft list ruleset table inet table1 { chain chain1 { type filter hook input priority filter; policy accept; tcp dport 22 accept tcp dport 80 accept } } table inet table2 { chain chain2 { type filter hook input priority filter; policy accept; tcp dport 25 accept } } -c オプション nft ファイルの構文が正しいかを確認します。 # nft -c -f test.nft 何らかの構文ミスがあった場合、下記の様に表示されることがあります。 # nft -c -f test.nft ルールの書き方 ルールを設定する際の基本的な構造は、 ①条件 (どんなプロトコルやパケットが対象か) と、 ②処理 (そのパケットをどうするか) となります。 前回の記事 での例を見てみましょう。 # nft add rule inet table1 chain1 tcp dport 22 accept # nft add rule inet table1 chain1 tcp dport 80 accept この場合、 tcp dport が ① 、 22 accept や 80 accept が② になります。 ちなみに、 ①に指定可能なパラメータとしては、下記のようなものがあります。 プロトコルの種類 tcp udp icmp プロトコルに対する詳細な条件 dport 宛先ポート番号 sport 送信元ポート番号 daddr 宛先 IP アドレス saddr 送信元 IP アドレス iif パケットが入ってきたネットワーク機器名 oif パケットが出ていくネットワーク機器名 さらに、 ②に指定可能なパラメータは、下記の通りです。 accept パケットを許可 drop パケットを拒否 (送信元に拒否された旨の通知なし) reject パケットを拒否 (送信元に拒否された旨の通知あり) 一般的な設定例 最後に、これまでの内容を踏まえ、簡単な設定例を 2つご紹介します。 ※あくまで最小限の構成です。必要に応じてルールの追加をしてください。 注意事項 これから紹介する設定例では、複数の条件を指定する必要があるため nft ファイルの形式にて記載しました。 下記の内容を nft 形式のファイルに記載の上 nft -f コマンド でそのファイルを指定し、設定を反映させてください。 nft -f コマンド実行後は、設定を永続化するため systemctl reload nftables を実行してください。 設定例 例1:一般的な Web サーバ ・SSH (22)、HTTP (80)、HTTPS (443) のみを許可 ・上記以外は拒否 table inet server1 { chain input { type filter hook input priority 0; policy drop; # 確立済み・または関連のある通信を許可 (これがないとレスポンスが遮断される) ct state established,related accept # 自分の SSH 接続を許可 tcp dport 22 accept # Web サーバ用のポート (80、443) を許可 tcp dport { 80, 443 } accept # ループバックを許可 iif lo accept } chain forward { type filter hook forward priority 0; policy drop; } chain output { type filter hook output priority 0; policy accept; } } 例2:IP アドレスのブロックリスト ・指定した IP アドレスからのアクセスを拒否 (drop) table inet server2 { chain input { type filter hook input priority 0; policy accept; # ブロックしたい IP アドレス (1つのルールごとに 1つ) ip saddr 192.0.2.10 drop ip saddr 192.0.2.50 drop ip saddr 203.0.113.12 drop } } ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 知っておくとちょっと便利!nftables によるパケットフィルタリング2 first appeared on SIOS Tech. Lab .
アバター
こんにちは! 今月も「OSSのサポートエンジニアが気になった!OSSの最新ニュース」をお届けします。 9/29、アサヒグループホールディングスは社内システムにサイバー攻撃を受けたと発表しました。 アサヒグループHDにサイバー攻撃 ビールなどグループ各社の出荷業務が停止 復旧時期は未定 https://www.itmedia.co.jp/news/articles/2509/29/news144.html 10/14 (米国時間)、「Windows 10 バージョン 22H2」のサポートが終了となりました。 「Windows 10」のサポートが終了 ~最後の「Windows Update」がリリース https://forest.watch.impress.co.jp/docs/news/2054961.html Commodore は、Windows ユーザを対象として自社の無料 OS「Commodore OS Vision 3.0」へ誘導するためのキャンペーンを開始しました。 Commodore、Windows 10 ユーザー救済のため無料 Linux OS を発表 https://biggo.jp/news/202510161732_Commodore_Linux_OS_Windows_10_Alternative ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 【2025年10月】OSSサポートエンジニアが気になった!OSS最新ニュース first appeared on SIOS Tech. Lab .
アバター
はじめに こんにちは! 参画しているプロジェクトが少し落ち着いてきて余裕が出てきたなーがです。今回はClaude Code UI×Tailscaleで外出先でもセキュアにClaude Codeを使う方法について解説します。 Claude Codeは通常ターミナルベースで動作するため、外出先からスマートフォンやタブレットで利用するのは困難です。しかし、Claude Code UIとTailscaleを組み合わせることで、モバイルデバイスからも安全にClaude Codeにアクセスできるようになります。 今回の設定を行うことで、自宅のPCで動作しているClaude Code UIに、外出先からセキュアにアクセスできるようになります。 Claude Code UIとは Claude Code UIは、Anthropic社のClaude Code CLIをWebブラウザから操作できるオープンソースのGUIツールです。siteboon氏によって開発され、GitHubで公開されています。 Claude Code UIの主な特徴は以下の通りです。 デスクトップ、タブレット、モバイルデバイスでシームレスに動作するレスポンシブデザイン ~/.claude/projects/ から自動的にプロジェクトを検出し、視覚的なプロジェクトブラウザを提供 セッション管理機能により、過去の会話の再開や複数セッションの管理が可能 MCP(Model Context Protocol)サーバーのサポート シンタックスハイライト機能を備えたファイルツリーとライブ編集機能 WebSocketによるリアルタイムストリーミング通信 Claude Code UIは、Node.js環境で動作し、Viteの開発サーバーを使用してローカルで実行されます。これにより、通常はターミナルでしか操作できないClaude Code CLIを、直感的なWebインターフェースから利用できるようになります。 参照: GitHub – siteboon/claudecodeui Claude Code UI公式サイト 既存の方法とセキュリティの課題 Claude Code UIをモバイルから利用する方法として、Cloudflare TunnelやVS Code Serverを使用した例がいくつか公開されています。 【徹底解説】Claude Code UI と Cloudflare Tunnelでスマホから快適にAIコーディング スマホでClaude Code!?外出先でClaude Codeを使ってみた!! これらの方法でも外出先からのアクセスは実現できますが、 URLを知っていれば誰でもアクセスできてしまう というセキュリティ上の問題があります。開発環境への不正アクセスは、ソースコードの流出やAPI鍵の漏洩など、深刻な被害につながる可能性があります。 そこで今回は、Tailscaleを使用したよりセキュアなアプローチをご紹介します。Tailscaleを利用することで、認証されたデバイスからのみアクセス可能な、真にプライベートなリモート開発環境を構築できます。 Tailscaleとは TailscaleはWireGuardプロトコルをベースとした、P2P型のメッシュVPNサービスです。2019年に元Googleのエンジニアによって設立されたTailscale社が提供しています。 従来のVPNは中央のゲートウェイサーバーを経由する必要があり、トラフィックの集中や単一障害点といった課題がありました。一方、Tailscaleはデバイス間で直接P2P接続を確立するため、これらの課題を解決しています。 Tailscaleの主な特徴は以下の通りです。 WireGuardによるエンドツーエンドの暗号化通信 ゼロトラスト・アーキテクチャによる高いセキュリティ NATやファイアウォールを自動で透過するNAT Traversal機能 GoogleやMicrosoftなどの既存アカウントで簡単にログイン可能 ACL(アクセス制御リスト)による柔軟なアクセス制御 個人利用であれば最大100台のデバイスまで無料で利用可能 Tailscaleは特別なハードウェアやサーバーの構築が不要で、数分でセキュアなプライベートネットワーク(tailnet)を構築できます。また、既存のネットワーク環境に影響を与えないオーバーレイネットワークとして動作するため、段階的な導入が可能です。 参照: What is Tailscale? – Tailscale Docs Tailscaleとは何? 普通のVPNとは何が違う? セットアップ Claude Code UIを実行するPC まずはClaude Code UIの設定から始めます。前回の記事ではClaude Code UIのライブラリをインストールするところまで行ったので、インストールに躓いた方はそちらを参考にしてください。 環境変数を設定します。README.mdに従って .env.example をコピーして .env を作成します。 cp .env.example .env .env ファイルを編集して、必要に応じてポート番号などを設定します。デフォルトでは3001番ポートが使用されます。 アプリケーションを起動します。 npm run dev ブラウザで http://localhost:5173 にアクセスし、Claude Code UIが正常に起動することを確認してください。 次に、PC起動時に自動でClaude Code UIを起動させるためのバッチファイルを作成します。Windows + Rキーを同時押しして下記のコマンドを入力し、OKを押すとスタートアップディレクトリが表示されます。 shell:startup 下記の内容でバッチファイル start-claude-code-ui.bat を作成し、スタートアップディレクトリに配置します。 @echo off cd /d "C:\\Users\\shota\\ws\\claudecodeui" npm run dev pause Tailscaleのインストールと設定 次にTailscaleをインストールして設定を行います。 Tailscale公式サイト からインストーラーをダウンロードして実行します GoogleやMicrosoftなどの任意のアカウントでログインします Windows版の場合、システムトレイにTailscaleのアイコンが表示されます アイコンをクリックして「Connect」ボタンを押し、VPN接続を確立します 接続が成功すると、デバイスにtailnet用のIPアドレス(100.x.x.x形式)が割り当てられます。 tailscale serveの設定 tailscale serve コマンドを実行して、ローカルで動作しているClaude Code UIをTailscaleネットワーク内に公開します。このコマンドを使用すると、開発中のWebアプリケーションをTailscaleネットワーク内の他のデバイスから安全にアクセス可能にできます。 Claude Code UIはViteの開発サーバーで実行されており、デフォルトではポート 5173 で動作しているため、接続先を http://localhost:5173 として指定します。さらに、オプション --bg を使用することで、ターミナルを閉じてもバックグラウンドでサービスが実行され続けるようにします。 tailscale serve --bg <http://localhost:5173> 実行すると、以下のような出力が表示されます。 Available within your tailnet: <https://test-server.tailXXXXXX.ts.net/> |-- proxy <http://localhost:5173> Serve started and running in the background. To disable the proxy, run: tailscale serve --https=443 off この https://test-server.tailXXXXXX.ts.net/ というURLが、Tailscaleネットワーク内からアクセスできるClaude Code UIのアドレスになります。 重要: tailscale serve で公開したサービスは、デフォルトではHTTPSで提供され、Tailscaleが自動的に証明書を発行します。 スマートフォンなど外出先で使用するデバイス Google Play StoreまたはApp StoreからTailscaleアプリをインストールします Google Play Store Apple App Store PC側と同じアカウントでログインします トグルボタンをタップして Connected 状態にします 接続が成功すると、スマートフォンもtailnet内のデバイスとして認識され、PC側で設定したドメイン名でアクセスできるようになります。 Tailscaleのアクセス制御設定 Tailscaleのデフォルト設定では、自分のデバイス間は全て許可されるというポリシーが設定されています。 { "acls": [ // Allow all connections. // Comment this section out if you want to define specific restrictions. {"action": "accept", "src": ["*"], "dst": ["*:*"]}, ], } しかし、セキュリティを強化するために、ACLを設定してアクセスできるデバイスを制限することをお勧めします。 ACLの設定手順 Tailscale管理コンソール にログインします Access controls から Tags を選択して + Create tag をクリックします 以下の2つのタグを作成します tag:server – Claude Code UIを実行するPC用 tag:client – 外出先で使用するデバイス用 General access rules セクションから + Add rule をクリックして、以下のようなアクセスルールを作成します このルールは「 tag:client を持つデバイスのみが tag:server を持つデバイスにアクセスできる」という意味になります。 Machines ページから各デバイスの設定を開き、適切なタグを割り当てます Claude Code UIを実行するPCに tag:server を設定 スマートフォンなど外出先で使用するデバイスに tag:client を設定 これで tag:client を設定したデバイスからのみ、Claude Code UIにアクセスできるようになりました。 アクセスの確認 スマートフォンのブラウザから、先ほど tailscale serve で表示されたドメイン名にアクセスします。 https://test-server.tailXXXXXX.ts.net/ セキュリティのポイント: Claude Code UIのWebインターフェースが表示されれば、設定は成功です。外出先からでも、自宅のPCで動作しているClaude Codeをセキュアに利用できるようになりました。 Tailscaleの通信は全てWireGuardによってエンドツーエンドで暗号化されています インターネットに直接サービスを公開する必要がなく、Tailscaleネットワーク内でのみアクセス可能です ACLによって、アクセス可能なデバイスを明示的に制限できます ポートフォワーディングやファイアウォールの設定変更が不要です おわりに 今回は、Claude Code UI×Tailscaleで外出先でもセキュアにClaude Codeを使う方法について解説しました。 Tailscaleの簡単なセットアップと強力なセキュリティ機能により、複雑なネットワーク設定なしにリモートアクセス環境を構築できます。 tailscale serve コマンド一つで、開発環境に対してセキュアにアクセスできるシンプルさが魅力です。 Claude Code UIとTailscaleを組み合わせることで、通勤中や外出先からでも、スマートフォンやタブレットを使ってAI支援コーディング環境にアクセスできるようになります。ぜひこの設定を活用して、より柔軟な開発スタイルを実現してみてください。 今回の設定内容については、Tailscaleの公式ドキュメントや Claude Code UI公式サイト も参考にしてください。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Claude Code UI×Tailscaleで外出先でもセキュアにClaude Codeを使おう! first appeared on SIOS Tech. Lab .
アバター
はじめに 前回 はKubeBlocksの解説と他類似OSSDB管理ソリューションの比較を行いました。今回はKubeBlocksでサポートされているDBソリューションについて説明します。 KubeBlokcsがサポートしているDB KubeBlocksとはKubernetesクラスタ上にプライベートなDBaaS(Database as a Service)を構築するためのオープンソース基盤です。多種多様なDBソリューションを統一された方法で管理することができます。 また、KubeBlocksはDB以外にもメッセージキューやストレージシステムに対応しています。 ここではKubeBlocksがサポートしているDBソリューションの説明、そのDBソリューションがどのような場面で利用されるかといったユースケースの説明、KubeBlocksがサポートしているDBの種類について紹介します。 Relational Databases Relational Databases(リレーショナルデータベース)とは データを行と列で構成されるテーブルで整理・格納するデータベースシステムです。リレーショナルデータベースではSQLという言語を使ってデータを操作します。 ユースケース 在庫管理や顧客の情報管理など、一貫性のあるデータの管理、データ同士で連携が必要なシステムで使用できます。 サポート対象DB MySQL:世界で最も広く使われているオープンソースのリレーショナルデータベース MariaDB:MySQLから派生したオープンソースのリレーショナルデータベース PostgreSQL:高機能さと拡張性が特徴のオープンソースのリレーショナルデータベース Vanilla PostgreSQL:カスタマイズしていない素のPostgreSQL  OrioleDB:PostgreSQLの容量、機能、パフォーマンスを最新のアプローチで向上させるために設計された、新しいストレージエンジン NoSQL NoSQLとは リレーショナルデータベースではないデータベースの総称です。リレーショナルデータベースのような厳格な構造(スキーマ)を緩和することで処理を単純にできるため高速に大量のデータを処理できます。 ユースケース ソーシャルメディアやECサイトなど高速に大量のデータを処理する必要があるシステムに向いています。 サポート対象DB MongoDB:大容量データの保存に使用されるドキュメント指向の NoSQL データベース Redis:高速でオープンソースの、メモリ内のキーバリューデータストア etcd:強力な一貫性のある分散キーバリューストア ZooKeeper:分散システムをまとめる、信頼性の高い集中型サービス OLAP Systems OLAP Systems(オンライン分析処理)とは 複雑なデータベースのクエリを高速に処理する技術の一つです。大量に蓄積されたデータを多角的な視点から素早く分析、集計するために特化したシステム。以下の図は、オンライン分析処理の概念図です。 OLAP Systemsの概念図 ユースケース 売り上げの分析やWebサイトのアクセス解析などのビジネスに関わるリアルタイム性が必要なシステムに向いています。 サポート対象DB Elasticsearch:本番規模のワークロードに最適化されたRESTful検索エンジン ClickHouse:列指向データベース StarRocks:リアルタイム、多次元、高度な同時データ分析が可能な高性能分析データウェアハウス高速な列指向データベース OpenSearch:オープンソースの分散型およびRESTful検索エンジン Distributed SQL Databases Distributed SQL Databases(分散SQLデータベース)とは 複数のサーバー(ノード)にデータを分散した状態で保存する仕組みです。データを分散して保存するが単一のリレーショナルデータベースのように振る舞うことが可能で可用性が高く高負荷の処理に強いという特徴があります。 ユースケース 金融プラットフォームなどの特に高可用性が求められるシステム、ユーザーが世界中にいるグローバルなオンラインサービスなど地理的に広範囲で展開され、一貫性を保つ必要があるシステムに向いています。 サポート対象DB TiDB:MySQL互換の分散データベース OceanBase-CE:C++ で開発された MySQL 互換の分散データベース PolarDB-X:MySQLをベースとした水平スケーリングをサポートするMySQL互換の分散データベース Vector Databases Vector Databases(ベクトルデータベース)とは テキスト、画像、音声などの複雑なデータを「ベクトル」という数値の配列に変換して保管します。意味の近さや類似性に基づいて高速で複合検索をすることができます。以下の図はベクトルデータベースの解説図です。 Vector Databasesの解説図 ユースケース ネットショッピングなどでの類似アイテムの推薦、意味検索など類似性や意味で検索を行うシステムで使用されます。 サポート対象DB Qdrant:ベクトルデータベースおよびベクトル類似性検索エンジン Weaviate:オープンソースのベクトルデータベース Milvus:非常に高速なクラウドネイティブのオープンソースベクトルデータベース Time Series Databases Time Series Databases(時系列データベース)とは 時間の経過とともに記録される時系列データを扱うことに特化したデータベースであり、時間の経過とともに記録されるデータを効率的に管理します。高速な書き込みと、特定の時間範囲での集計・分析処理を効率的に行えるように最適化されています。 ユースケース 需要予測、異常検知など時間ベースの分析が必要なシステムなど様々な分野で使用されています。 サポート対象DB InfluxDB:大規模な時系列データの処理に最適化された専用データベース VictoriaMetrics:監視ソリューションとしての利用に特化した時系列データベース GreptimeDB:スケーラビリティ、分析機能、効率性を重視したオープンソース時系列データベース TDengine:データベース、メッセージキュー、キャッシュ等の機能を統合した産業用IoT向けのデータプラットフォーム Graph Databases Graph Databases(グラフデータベース)とは データをノード(点)とエッジ(線)の集合体(グラフ)として捉えて格納するデータベースです。リレーショナルデータベースでは、テーブル同士の繋がりが増えるほど応答速度が低下します。一方、グラフデータベースは繋がりが増えても応答速度があまり低下しないというメリットがあります。以下の図は、グラフデータベースの概念図です。 Graph Databaseの概念図 ユースケース ソーシャルネットワーク、レコメンデーションなど繋がりがあるデータの検索などに向いています。 サポート対象DB Nebula:数兆のエッジと頂点を持つグラフを保存および処理できるオープンソースのグラフデータベース Message Queues Message Queues(メッセージキュー)とは アプリケーション間でデータを非同期で送受信するための中継役をするデータストレージです。キューがあることでデータを送る側も受け取る側も任意のタイミングで処理を行うことができます。以下の図はメッセージキューの概念図です。 Message Queuesの概念図 ユースケース 非同期処理の実装、マイクロサービス間の疎結合化など、システムの応答性・信頼性などを向上させるために様々な場面で使用されています。 サポート対象ソリューション RabbitMQ:オープンソースの分散イベント ストリーミングプラットフォーム Apache Kafka:信頼性が高いメッセージングおよびストリーミングブローカー Apache Pulsar:オープンソースの分散メッセージングおよびストリーミングプラットフォーム Storage System Storage Systemとは デジタルデータを物理的・論理的に保管、管理するための仕組みや製品全般を差します。 ユースケース データベースやアプリケーションのバックアップ先やAI / 機械学習のデータストレージなど様々なデータの保存や管理に使用されます。 サポート対象ソリューション MinIO:AWS S3互換APIを提供するオブジェクトストレージソリューション おわりに 今回の記事で見てきたように、KubeBlocksでは、多種多様なデータベースを、Kubernetesという共通の基盤の上で、統一された作法で管理することができるのがKubeBlocksの強みです。 KubeBlocksを利用することで開発者はインフラの細かな違いを意識することなく、アプリケーションの要件に最適なデータベースを利用できるようになります。 次回はKubeBlocksの導入としてKubernetes上にDBaaSを構築する手順を解説します。 参考文献 KubeBlocks公式: https://kubeblocks.io/docs/preview/user_docs/overview/supported-addons リレーショナルデータベースとは?メリット・デメリットや活用例を紹介: https://primenumber.com/blog/relational-database NoSQLデータベースとは?メリット・デメリットや活用例を紹介: https://primenumber.com/blog/nosql OLAPとは?特徴や実装方式から他の分析手法との比較も解説: https://primenumber.com/blog/olap OLAPデータベースにおける高速化の技術: https://tech.plaid.co.jp/fundamentals_of_olap_db_technology#%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%81%AE%E4%BE%8B 分散データベースとは?特徴とメリット・デメリットを解説: https://www.anken-navi.jp/news/work-freelance/distributed-database/ CockroachDB公式サイト: https://www.cockroachlabs.com/ TiDB公式サイト: https://pingcap.co.jp/ メッセージキューの基礎知識と活用方法: https://tech-education-nav.com/contents/educational-materials/backend-development/message-queues-explained Amazon SQSのユースケースとAWSサービスとの連携例: https://qiita.com/kenogi/items/ea6154a0fc3e2d81622b ベクトル・データベースとは: https://www.oracle.com/jp/database/vector-database/ Vector DB 入門: https://zenn.dev/atusi/articles/61b7f95b4df726 【2025年決定版】ベクトルDB完全比較とRAG最新活用: https://arpable.com/artificial-intelligence/rag/vector-database-rag/ 時系列データベースとは? 時系列データの活用例や専用DBの必要性について解説: https://www.ctc-g.co.jp/keys/blog/detail/what-is-a-time-series-database 時系列データベースとは?基本と活用のメリット: https://products.sint.co.jp/siob/blog/time-series-database グラフデータベースとは?RDBとの違いや主要4製品の比較まとめ: https://aerospike.co.jp/blog/what-is-graph-database/ グラフデータベースとは何か ~ネットワーク状のデータ構造から瞬時に情報を検索するDBを解説: https://www.imagazine.co.jp/12805-2/ いまさら聞けない、ストレージとサーバの違い: https://www.netapp.com/ja/blog/server-and-storage/ MinIO公式: https://www.min.io/   ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post KubeBlocksでサポートされるDBの種類を徹底解説! first appeared on SIOS Tech. Lab .
アバター
こんにちは、OSS よろず相談室の鹿島です。 はじめに 今回は、DifyとAmazon Bedrockを連携させて、チャットボットとRAG(検索拡張生成)を構築する手順の4回目、最終回です。 【実践】Dify + Amazon Bedrockで、ゼロからチャットボットと RAG を作る① 【実践】Dify + Amazon Bedrockで、ゼロからチャットボットと RAG を作る② 【実践】Dify + Amazon Bedrockで、ゼロからチャットボットと RAG を作る③ 【実践】Dify + Amazon Bedrockで、ゼロからチャットボットと RAG を作る④  ←本記事 前回までで、構築したDify環境とAmazon Bedrockを連携させ、チャットボットを作成しました。 今回は、RAGを作ってみます。 DifyのRAGは、PDFやテキストなどの社内文書を知識ベースとしてAIに組み込むことができる機能です。 これにより、AIはインターネット上にない社内情報や専門的な質問にも、正確な根拠を持って回答できるようになります。  ステップ1 ナレッジを作成する 以下のURLにアクセスします。 http://[DifyをインストールしたマシンのIPアドレス] 【実践】Dify + Amazon Bedrockで、ゼロからチャットボットと RAG を作る① でアカウントを作成してログインしていますので、ホームのページが表示されます。 ①「ナレッジ」②「ナレッジを作成」を選択します。 ステップ2 ナレッジを登録する ナレッジとして登録するサンプルとして、厚生労働省が公開しているモデル就業規則をダウンロードしましょう。 以下のページから「モデル就業規則」のPDF版をダウンロードしてください。 https://www.mhlw.go.jp/stf/seisakunitsuite/bunya/koyou_roudou/roudoukijun/zigyonushi/model/index.html ナレッジのデータソースの選択画面で、①「テキストファイルからインポート」②「テキストファイルをアップロード」を選択します。 ダウンロードしたPDFファイルを選択してアップロードします。最後に「次へ」を選択します。 ステップ3 ナレッジの設定をする はじめに、チャンクの設定をします。 チャンク とは、RAG(検索拡張生成)において、AIが扱いやすいようにドキュメントや知識ベースを分割した小さな情報の塊のことです。 長文をそのままAIに入力すると、重要な情報を見落としたり、処理の負荷が高くなったりする問題が発生します。 このチャンク単位で情報を検索し、質問に関連性の高い部分だけをAIに渡すことで、回答の精度と効率を向上させます。 チャンクの詳細については「 弊社ブログ(チャンキング) 」を参照してください。 ここではデフォルトのまま進めます。 次に「インデックス方法」という選択肢があります。 「経済的」は無料で使用できますが、キーワード検索が中心となります。 今回は、「 【実践】Dify + Amazon Bedrockで、ゼロからチャットボットと RAG を作る② 」で Amazon Bedrockでの設定/本記事で利用するモデル で、RAG用に以下のモデルを有効にしました。 Titan Text Embeddings V2 Rerank 1.0 これらのモデルを活用して高精度な検索を実現するため、今回は「高品質」を選んでみましょう。 高品質を選択すると、「埋め込みモデル」を選択できます。 注意点として、ここの選択肢には、 Amazon Bedrockの設定 で有効にしなかったモデルも表示されます。 有効にしていないモデルを選択すると、ここではエラーになりませんが、後にナレッジベースの作成でエラーになります。 有効にしたモデル、ここでは「amazon.titan-embed-text-v2:0」を選択します。 次に、「検索設定」を選択します。 検索方法には3種類あり、「ベクトル検索」は文章の意味の近さで探し、「全文検索」はキーワードの一致で探します。そして、両方を組み合わせた「ハイブリッド検索」が最も精度が高いとされ、推奨されています。 ここでは推奨の「ハイブリッド検索」を選択します。 検索設定では、「rerankモデル」を選択します。 ここでも、Amazon Bedrockの設定で有効にしなかったモデルも選択肢に表示されますが、有効にしたモデルを選択します。 ここでは、「amazon.rerank-v1:0」を選択します。 最後に「保存して処理」をクリックします。 「ナレッジベースが作成されました」「埋め込みが完了しました」と表示され、緑のチェックが付けば成功です。 なお、先述の通り、Bedrockで有効にしていないモデルを選択すると以下のように、赤く表示されます。 [!]マークにマウスカーソルを合わせると、「 AccessDeniedException: You don't have access to the model with the specified model ID 」と表示され、モデルへのアクセス権がないことが分かります。 処理が成功したら「ドキュメントに移動」を選択します。 以下のように、ステータスが「利用可能」になっていればナレッジの作成は成功です。 なお、検索設定やrerankの詳細については、Dify公式マニュアルもあわせて参照してください。 参考: Dify公式マニュアルー検索方法の指定 ステップ4 チャットボットにナレッジを適用する 【実践】Dify + Amazon Bedrockで、ゼロからチャットボットと RAG を作る③ と同様に、チャットボットを作成しましょう。 チャットボットの設定画面で、コンテキストの「追加」を選択します。 すると、先ほど作成したナレッジが表示されます。 ステップ3で作成したナレッジを選択します。 次に、オーケストレーションのプロンプトを編集します。 今回は以下のように入力してみましょう。 「あなたはコンテキストに基づいて回答するチャットボットです。コンテキストに無い質問には「コンテキストに回答がありません」とのみ回答してください」 と入力しておきます。 設定が完了したら、実際に質問してみましょう。 まずはナレッジに含まれる内容について、 「有給休暇について教えて」 と質問します。 すると、アップロードした就業規則のコンテキストに基づいて回答してくれます。 回答の下には根拠となった引用コンテキストが表示され、クリックすると関連度のスコアなどを確認することができます。 次にコンテキストと関係のない質問をします。 「 サンシャインコーストはどこにありますか 」と入力すると、プロンプトの指示通り、まずコンテキストに情報がない旨が表示され、その後にLLM自身の知識から回答が生成されます。 このように、ナレッジ(コンテキスト)がある場合はそれを優先して回答し、ない場合はLLMが直接回答するといった制御が、簡単な設定だけで実現できました。 以上、4回にわたり、DifyとAmazon BedrockのLLMを使用して、RAGアーキテクチャを採用したチャットボットを構築する手順をご紹介しました。 弊社の記述ブログには、Difyに関連する記事が複数ありますので、あわせてご参照ください。 Dify入門ガイド:初心者でもわかる!簡単RAG構築 世界一わかりみの深いDify ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 【実践】Dify + Amazon Bedrockで、ゼロからチャットボットと RAG を作る④ first appeared on SIOS Tech. Lab .
アバター
はじめに ども!今月はがっつりと開発期間をいただいて、社内で活用できるサービスを作成しつつ、AIとの開発検証を進めている龍ちゃんです。作るものが多くてあっちにフラフラこっちにフラフラって感じです。 今回は、「 Claude Code革命!3フェーズ開発で効率的な開発:計画→実装→検証術 」で提唱した「計画ドキュメント」を用いての開発を3カ月ほど続けたので、そこに対する知見を書いていこうと思います。 結論は「計画ドキュメント」ってめちゃくちゃ大事じゃね?ってお話です。 問題:AIに丸投げすると何が起きるか 技術選定を任せる危険性 開発を進めていく中で、最も課題となったのが「AIに技術選定を委ねてしまう」という問題でした。 具体的な例として、 私はSWRで全ての処理を自動生成しようと試みていました。SWRは本来データフェッチングに特化したライブラリですが、CRUD操作の全てをSWRで解決しようとしていたのです。これは設計思想から考えると適切ではありませんでした。 CRUDの4つの要素のうち、SWRが最適化されているのは主にRead(データ取得)の部分です。Create、Update、Deleteの3/4については本来の用途から外れているにも関わらず、統一性を重視して全てSWRで実装しようとしていました。 人間の開発者であれば「SWRの実装が複雑になるようであれば、素直にAxiosを使用した方が良い」という判断ができます。しかし、AIにはこうした経験に基づく技術的判断や、ライブラリの適切な使い分けに関する感覚が不足しているようです。 龍ちゃん システムプロンプトで「SWRを絶対使うように」って書いていたので、技術選定をしたのは人間なのですがそれに対する課題などの指摘は特にないってのが問題ですね。 AIの限界:誤字脱字と文脈の理解 プロンプトを通じたやり取りで発生する問題も重要な課題でした。 入力に誤字脱字が含まれている場合、AIはそれを修正することなく処理を継続してしまいます。技術用語の誤入力などがあっても、人間であれば文脈から推測して修正できるような内容でも、AIは字面通りに解釈して間違った方向に進んでしまうことがあります。 この結果、想定していたアーキテクチャから逸脱した実装が生成されたり、設計方針に一貫性がなくなったりする問題が発生しました。 具体例として、README.mdに「SWRを必ず使用すること」という記述があったのですが、これが問題の原因となりました。Orvalの設定を適切に調整すれば回避できた問題でしたが、全てのエンドポイントに対してAxiosとSWRの両方のクライアントが生成される状況で、AIは一貫してSWRを選択し続けていました。 根本原因:意思決定の不在 これらの問題の本質は、 人間が行うべき意思決定をAIに委ねてしまっている 点にあります。 人間の開発者は、明文化されていない暗黙知に基づいて技術的判断を行うことがあります。「この技術領域では一般的にこのようなアプローチを取る」といった、体系化されていない経験則や業界標準に関する知識です。 こうした暗黙知は、各開発者の経験や学習によって蓄積されたものですが、現在のAIには十分に備わっていないと感じています。もちろん、私の技術力が不足しているため、AIの能力を十分に引き出せていない可能性もありますが、この差を埋める仕組みが必要です。 その仕組みこそが、 計画ドキュメント による意思決定の明文化なのです。 解決策:計画ドキュメント = 意思決定の場 人間同士の協働 vs AI協働の違い 人間同士での開発とAI協働での開発では、「暗黙知の共有レベル」に大きな差があります。 人間同士での協働の場合: 共通の技術的背景知識を前提とした議論が可能 「一般的にはこのようなアプローチを取る」という共通認識 文脈を理解した柔軟な修正と提案 暗黙の了解による効率的なコミュニケーション AI協働の場合: 明示的に指示された内容のみに基づく判断 技術的なベストプラクティスの理解が限定的 プロンプトの内容に対する忠実な実行 全ての判断基準の明文化が必要 つまり、AI協働においては 全ての意思決定プロセスを文書化 することが不可欠となります。 計画ドキュメントで決めること 計画ドキュメントで明文化すべき要素は、主に以下の4つです: 技術選定: 選定理由とともに、採用しない選択肢(禁則事項)についても記載 ライブラリ間の使い分け基準の明確化 例:SWRはデータフェッチ(Read)操作のみに使用し、CUD操作にはAxiosを使用する アーキテクチャ方針: フロントエンド・バックエンド間の責任境界 エラーハンドリングの統一方針 状態管理の方法と各層の責務 API設計: エンドポイントの命名規則と構造 レスポンス形式の統一ルール エラーレスポンスの標準フォーマット 実装方針: ディレクトリ構成とファイル配置のルール コンポーネント設計のガイドライン テスト方針とカバレッジ基準 意思決定と実行の分離 効果的なAI協働を実現するには、 意思決定フェーズと実行フェーズを明確に分離 することが重要です。 人間の役割: 何を作るか、どのような方針で開発するかを決定する AIの役割: 決定された方針に従って、実際のコードを生成・組み立てる この役割分担により、AIの長所である「高速で大量のコード生成」を活かしながら、人間の「経験に基づく技術判断」を適切に反映できるようになります。 計画の品質が成果物の品質を決定するのは開発の基本原則ですが、特にAI協働においては「計画ドキュメントがプロジェクトの成否を左右する」と言えるでしょう。 実行の標準化:パーツと自動生成 品質保証としてのパーツ化 実際の開発では、意思決定した内容を「パーツ」として標準化することで品質を保証できます。これはソフトウェア工学における品質管理の考え方と共通しています。 システム開発において、個々のコンポーネントの品質がシステム全体に与える影響は重大です。一つのコンポーネントに不具合があると、それがシステム全体の信頼性を損なう可能性があります。プログラムにおいては多少の技術的負債を抱えても稼働し続けることは可能ですが、基盤となるパーツがすべて品質に問題を抱えている場合は、深刻な影響が生じます。 特にフロントエンドを開発する際は、外部のAPIや自作のAPIをパーツとしてとらえることで、作業領域が明確化されます。 人間の役割: 作成すべき機能と要件を明確に定義する 使用するパーツの選択と品質基準の設定 パーツの妥当性と整合性を検証する パーツ/自動生成の役割: 実装方法を標準化し、一貫性を保つ コードの品質を一定レベルに維持する 再利用性を高め、開発効率を向上させる AIの役割: 定義されたパーツを適切に組み合わせて実装する ボイラープレートコードの大量生成を効率化 人間が決定した設計方針に従ってコードを構築する 実例:自動生成パイプライン 具体例として、OpenAPIスペックから型定義を自動同期するパイプラインを構築した際の事例をご紹介します。 // DTO定義(人間による意思決定) interface UserCreateRequest { name: string; email: string; role: 'admin' | 'user'; } // 型定義とAPI関数は自動生成 const createUser = async (data: UserCreateRequest) => { return axios.post<UserResponse>('/api/users', data); }; この実装において重要なポイントは、 DTO定義という設計判断は人間が行い、実行部分(型定義生成、API関数生成)は自動化 している点です。これにより、設計の一貫性を保ちながら実装効率を大幅に向上させることができました。 参考事例:Shadcn/uiのアプローチ Shadcn/uiは、UIコンポーネント開発において「パーツ化」の優れた事例を提供しています。 このライブラリが革新的な点は、UIコンポーネントを標準化された「パーツ」として提供し、開発者が「どのコンポーネントを使用するか」という意思決定に集中できる環境を作り出していることです。AIは「パーツを選択して適切に組み合わせる」という作業に集中でき、結果として開発効率と品質の両立を実現しています。 この考え方は、API接続層やビジネスロジック層にも応用可能であり、AI協働開発における有効なパターンとなり得ると考えています。 実践:意思決定を握る3原則 原則1:計画ドキュメントでの明文化 実施内容: 技術選定の理由を具体的かつ詳細に文書化 実装方針を明確で実行可能なレベルまで記述 暗黙知となっている判断基準の言語化 明文化の範囲について: 理論的にはどこまで詳細化しても構いませんが、コンテキスト量の制約があることを考慮する必要があります。特にClaude等のLLMを使用する場合、トークン制限により詳細すぎる文書は処理できなくなる可能性があります。このバランス調整は現在の技術的制約として受け入れる必要があります。 実践的な運用方法: バックエンドとフロントエンドを並行開発する場合、計画ドキュメントに加えて具体的な実装手順をToDo形式で管理することを推奨します。進捗を可視化することで、AIツールが予期せず停止した場合でも、明確な再開ポイントを確保できます。 原則2:パーツによる実行の標準化 実施内容: 再利用可能なコンポーネント・関数の設計と整備 API接続の標準化(型定義、エラーハンドリング含む) 開発ツール(Linter、Formatter等)の統一と自動化 品質保証の重要性: 個々のパーツの品質は、システム全体の安定性に直結します。不適切な設計のパーツを多数組み合わせると、保守性や拡張性に深刻な問題が生じる可能性があります。そのため、パーツ設計段階での品質基準の設定と検証が不可欠です。 原則3:検証による継続的改善 実施内容: 計画と実装結果の差分分析と記録 発見された問題点や改善点の体系的な蓄積 得られた知見の次回プロジェクトへの適用 現実的な視点の重要性: 完璧な計画ドキュメントや仕様書を最初から作成することは現実的ではありません。開発過程で「より良いアプローチが明確になる」ことは自然な現象です。 そのような状況では、変更の必要性を適切に判断し、修正された方針で実装を完了させることが重要です。完了後には計画と実装の差分を分析し、その経験を将来のプロジェクトに活かすことで、継続的な改善を図ることができます。 まとめ:意思決定は人間、実行はAI 本記事では、3ヶ月間のAI協働開発を通じて得られた実践的な知見をもとに、効果的な協働体制の構築について詳しく解説してきました。 重要ポイントの整理: 技術選定の主導権確保 – AIに技術的判断を委ねることのリスクと、経験に基づく適切な技術選択の重要性 計画ドキュメントによる意思決定の明文化 – 暗黙知の言語化と、全ての判断基準の明確化の必要性 意思決定と実行の明確な分離 – 人間とAIの適切な役割分担による効率化の実現 パーツ化による実行の標準化 – 品質保証と再利用性向上のための設計アプローチ 継続的改善による知見の蓄積 – 完璧性よりも学習と改善を重視したアプローチ 結論として 、現在のAI協働開発においては、 人間が意思決定を行い、AIが実行を担当する という役割分担が最も効果的であると考えられます。 AI技術は急速に進歩していますが、現時点では経験に基づく技術的判断や、コンテキストを考慮した柔軟な意思決定において、人間の能力に及ばない側面があります。一方で、大量のコード生成や、定められたパターンに従った実装作業においては、AIの方が高速かつ正確に処理できます。 この技術特性を理解し、適切な役割分担を実装することで、AI協働開発の真価を発揮することが可能になります。 実践への提案 AI協働開発を検討されている方は、まず「計画ドキュメント」の作成から始めることをお勧めします。初期段階では作成コストが高く感じられるかもしれませんが、中長期的には開発効率と成果物の品質において大幅な改善効果が期待できます。 この記事で紹介した3原則と実践的アプローチが、皆さんのAI協働開発プロジェクトの成功に寄与できれば幸いです。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post AI協働開発の落とし穴回避!3ヶ月で実証した計画ドキュメントの価値 first appeared on SIOS Tech. Lab .
アバター
初めに ども!今月はAI開発にどっぷりな毎日な龍ちゃんです。今回は「 AIと爆速開発!Next.js×Nest.js型定義同期の自動生成パイプライン構築術 」で開発効率を上げたんですが、そこで起きた問題について原因究明と解決策を模索したので解説していこうと思います。 TL;DR Orvalで全APIエンドポイントにSWRフックを自動生成していたんですが、 バンドルサイズの肥大化 と 不要なオーバーヘッド が問題になってしまいました。 解決策 : client: "axios-functions" に変更して、Axios関数のみを自動生成。SWRは必要な箇所のみカスタムフック実装する方針に切り替えました。 結果 : 47ファイルの移行(4.2時間)で、バンドルサイズを20-30%削減できました! 問題の発見:便利すぎる自動生成の罠 最初はOrvalで全APIエンドポイントにSWRフックを自動生成する設定にしていました。便利だと思っていたんですよね。型安全だし、統一感もあるし。 でも2ヶ月ほど経った頃、ふと気づいたんです。バンドルサイズはどんどん肥大化していくし、mutation処理は無駄にSWRを経由しているし、コードは複雑になっていく一方。 何かがおかしい。 そこで改めて考え直してみました。SWRって、そもそも何のためのツールだったっけ?と。 SWRの本質を見つめ直す SWRは データ取得(Read)のために設計 されたライブラリです。名前の由来である「stale-while-revalidate」という戦略が示す通り、以下のような特徴があります: キャッシュ戦略による高速な表示 自動再検証(フォーカス時、再接続時など) 複数コンポーネント間でのデータ共有 これって、まさにCRUDのRead(データ取得)に最適化された設計なんですよね。 一方で、 CUD(Create/Update/Delete)はどうでしょうか? useSWRMutation というフックも用意されていますが、よく考えてみると一回限りのmutationにキャッシュ戦略は不要です。フォーム状態との統合も煩雑になりがちでした。 それなのに、全エンドポイント分のSWRフックを自動生成していたら、本質的には不要なコードが大量に生まれてしまっていたんです。 Before/After: Orval設定の変更 それでは、具体的にどう変更したのか見ていきましょう。 Before(旧設定) output: mode: "split" # ❌ ラッパー関数が生成される client: "swr" # ❌ SWRフック自動生成 # ... 問題点 : 全エンドポイント分のSWRフックが生成され、バンドル肥大化。mutationにも不要なSWRオーバーヘッドが発生していました。 After(新設定) output: mode: "single" # ✅ 直接エクスポート client: "axios-functions" # ✅ Axios関数のみ生成 # ... 改善点 : Axios関数のみを生成し、SWRは必要な箇所のみ手動で作成。バンドルサイズを20-30%削減できました。 シンプルですよね。でも、この変更が大きな効果を生んだんです。 自動生成の3つの問題 実際に移行作業を進めながら、自動生成のどこが問題だったのか明確になってきました。 1. 不要なオーバーヘッド 例えば、投稿を作成する処理を考えてみてください。これって一回限りのアクションですよね。キャッシュも再検証も不要なのに、SWRの状態管理オーバーヘッドが動いている。これは明らかに無駄でした。 2. バンドルサイズの肥大化 数字で見ると、問題の大きさがよくわかります: 項目 Before After 改善 自動生成フック数 41個 0個 完全削除 バンドルサイズ 100% 70-80% 20-30%削減 コード行数 ~2030行 ~800行 約60%削減 全エンドポイント分のSWRフックが生成されて、使わないものも含めて全部バンドルに入ってしまっていたんですね。 3. コンポーネント設計の硬直化 これが一番厄介でした。SWRの状態( isMutating , error )とフォームの状態( isSubmitting , validationErrors )が分裂してしまって、同期が複雑化していたんです。 実際にフォームを実装していると、「あれ、どっちのエラー状態を見ればいいんだっけ?」みたいなことが頻発していました。 解決策:適材適所のアプローチ そこで、シンプルな方針に切り替えました: ✅ Read(GET) → カスタムSWRフック ✅ CUD(POST/PUT/DELETE) → 直接Axios呼び出し それぞれ見ていきましょう。 パターン1: データ取得(カスタムSWRフック) データ取得には、SWRの恩恵を最大限活用します。 // hooks/useSeriesDrafts.ts import useSWR from "swr"; import { seriesDraftsControllerFindAll } from "@/lib/api/generated"; / シリーズ下書き一覧を取得するカスタムフック SWRのキャッシュ・再検証・データ共有の恩恵を受けられる / export const useSeriesDraftsControllerFindAll = () => { return useSWR("/api/series-drafts", () => seriesDraftsControllerFindAll()); }; // コンポーネントでの使用 const { data, error, isLoading } = useSeriesDraftsControllerFindAll(); SWRのキャッシュ戦略により、複数のコンポーネントで同じデータを効率的に共有できます。フォーカス時の自動再検証なども自動で行われるので、常に新鮮なデータを表示できるんですよね。 パターン2: mutation(直接Axios呼び出し) 一方、データの作成・更新・削除は直接Axiosを呼び出します。 import { useState } from "react"; import { mutate } from "swr"; import { seriesDraftsControllerCreate } from "@/lib/api/generated"; const [isCreating, setIsCreating] = useState(false); / シリーズ下書きを作成する処理 SWRのオーバーヘッドなしで、シンプルに実装できる / const handleCreate = async (data) => { setIsCreating(true); try { await seriesDraftsControllerCreate(data); // 作成後、SWRキャッシュを更新して一覧を再取得 mutate("/api/series-drafts"); } finally { setIsCreating(false); } }; このアプローチなら、不要なオーバーヘッドを回避できて、フォーム状態との統合も容易になります。必要に応じて mutate() でSWRキャッシュを更新すれば、一覧表示も自動的に最新化されます。 シンプルでわかりやすいですよね。 移行中に発見したバグ 実は移行作業中に、思わぬバグも見つかりました。 axiosInstance と axiosClient の混同 : 3つのファイルで axiosClient をAxiosインスタンスとして誤使用していたんです。 // ❌ Before(バグ) import { axiosClient } from "@/lib/axiosClient"; await axiosClient.get("/.auth/me"); // TypeError! // ✅ After(修正) import { axiosInstance } from "@/lib/axiosClient"; await axiosInstance.get("/.auth/me"); 教訓 : axiosClient はOrval mutator関数として使うもので、直接HTTP呼び出しには axiosInstance を使用する必要があります。 命名が似ていると、こういう混同が起きやすいんですよね。移行作業のおかげで、潜在的なバグを早期発見できたのは副次的な効果でした。 移行結果:数字で見る効果 実際の移行結果をまとめてみます。 対象範囲と効果 47ファイル移行完了 (実装時間: 4.2時間、推定14-20時間 → 21-30%効率化) バンドルサイズ20-30%削減 (自動生成フック: 41個 → 0個) カスタムフック : 9個を必要箇所のみ作成 コード行数 : ~2030行 → ~800行(約60%削減) 当初は14-20時間かかると見積もっていたんですが、4.2時間で完了できました。Axiosの関数がパーツとして提供されていたおかげで、AIに実装を任せる際もスムーズに進められたんです。 AI開発を効率化する「パーツ提供」の考え方 今回の経験で実感したのが、 AI開発を効率化する鍵は「パーツを提供する」という考え方 だということです。 shadcn/uiが成功しているのも同じ理由ではないでしょうか。コンポーネントをコピペして、必要に応じてカスタマイズできる。全部を自動生成するのではなく、パーツを提供する。 Axiosのインターフェース部分をパーツとして切り出しておけば、そこに処理を書かせるだけでOK。このアプローチによって、開発効率が飛躍的に向上しました。 フロントエンドとバックエンドの型の齟齬もなくなりましたし、手が止まることも減りました。すっきりとしたコードで実装できるようになったんです。 まとめ:適材適所が長期的な保守性を生む SWRは素晴らしいツールです。でも、すべてのAPI呼び出しに必要なわけではありません。 適材適所のアプローチ : データ取得(Read) : SWRの恩恵を最大限活用 mutation(CUD) : シンプルにAxiosで十分 「便利だから」という理由で全てを自動生成すると、不要な複雑さとバンドル肥大化を招いてしまいます。 Axiosでパーツのみを提供し、SWRは必要な箇所に手動で適用する。この「適材適所」のアプローチが、長期的な保守性と柔軟性を生むんですね。 皆さんも、もし自動生成で「何か複雑になってきたな」と感じたら、一度立ち止まって考えてみてください。本質的に必要なものは何か、ツールの設計思想に沿った使い方ができているか。そこを見直すことで、より良い設計にたどり着けるはずです。 今回の知識を活かして、ぜひ皆さんのプロジェクトでも最適なアプローチを見つけてみてください! 参考リソース Orval – OpenAPI to TypeScript SWR – React Hooks for Data Fetching 包括的な実装検証ドキュメント ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Orval SWRの自動生成をやめた理由 – SWRの本質を見失っていた話 first appeared on SIOS Tech. Lab .
アバター
こんな方へ特におすすめ これから本格的なWebアプリ開発を始めたい方 自分だけの快適な開発環境を整えたい方 チーム開発で「自分の環境だけ動かない…」を撲滅したい方 PCを買い替えてもすぐに開発を再開したい方 概要 こんにちは。サイオステクノロジーのはらちゃんです!今回5本目のブログ執筆です。 今回は、バックエンド(Python/FastAPI)とフロントエンド(Node.js/React)を分離したモダンなWebアプリケーション開発を想定し、 VS CodeのDev Container 機能を使って、誰でも同じ環境を再現できる開発環境を構築する手順を解説します。 Dev Containerという最適解 新しいプロジェクトを始めるたびに 「Pythonのバージョンは…?」 「Node.jsのバージョンは…?」 と環境構築で時間を取られていませんか?Dev Containerは、Dockerコンテナーの技術を使い、プロジェクトごとに隔離された最適な開発環境をコード(設定ファイル)で管理できるVS Codeの素晴らしい機能です。 これを使えば、新しいメンバーも数コマンドであなたと全く同じ開発環境を立ち上げることができます。今回は、無料のAIコーディング支援ツール Codeium も導入し、より快適な環境を目指します。 発生しがちなエラーとその解決策も詳しく紹介するので、ぜひ最後までお付き合いください! Step0:前提条件 VSCodeがインストールされている Docker Desktopまたは Rancher Desktop がインストールされている (Windowsの場合) WSL2が有効になっている Step1:プロジェクトの骨格を作る まず、プロジェクト全体のフォルダ構成を整え、Dockerで各サービス(バックエンド、フロントエンド、DB)をどう連携させるかを定義する docker-compose.yml を作成します。 ディレクトリの作成 以下のようなフォルダ構成を作成します。 .devcontainer フォルダの中に backend と frontend のサブフォルダを作るのがポイントです。 HaraSpace/ │ ├── .devcontainer/ │ │ │ ├── backend/ │ │ └── devcontainer.json │ │ │ └── frontend/ │ └── devcontainer.json │ ├── backend/ │ │ │ ├── Dockerfile │ └── requirements.txt │ ├── frontend/ │ │ │ ├── Dockerfile │ └── package.json │ ├── docker-compose.yml │ └── wait-for-it.sh docker-compose.ymlの作成 プロジェクトのルートに、3つのサービスを定義する docker-compose.yml を作成します。 docker-compose.yml services: backend: build: context: . dockerfile: backend/Dockerfile target: development # 開発用ステージを指定 command: ["wait-for-it.sh", "db:3306", "--", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] volumes: - ./backend:/workspace/backend ports: - "8000:8000" depends_on: - db frontend: build: context: . dockerfile: frontend/Dockerfile target: development # 開発用ステージを指定 # --hostフラグでコンテナ外からのアクセスを許可 command: ["npm", "run", "dev", "--", "--host"] volumes: - ./frontend:/workspace/frontend ports: - "3001:3000" depends_on: - backend db: image: mysql:8.0 ports: - "3307:3306" environment: - MYSQL_ROOT_PASSWORD=your_root_password - MYSQL_DATABASE=sql_app_db volumes: - db_data:/var/lib/mysql volumes: db_data: wait-for-it.sh ファイルの準備 GitHub からダウンロードし、プロジェクトの ルートディレクトリ ( docker-compose.yml と同じ場所)に配置するのが一般的です。 Step2:各サービスの設計図を書く 次に、バックエンドとフロントエンドそれぞれのコンテナー環境の設計図となる Dockerfile を作成します。今回は、開発用と本番用で設定を分ける「 多段ビルド 」という手法を採用します。 バックエンド 現在の既定である、Python 3.12をベースイメージとして使用します。 backend/Dockerfile # ---- 1. 全ステージで共通のベース ---- FROM python:3.12-slim as base WORKDIR /workspace/backend ENV PYTHONPATH "${PYTHONPATH}:/workspace/backend" # wait-for-it.shをコピーして実行権限を付与 COPY wait-for-it.sh /usr/local/bin/wait-for-it.sh RUN chmod +x /usr/local/bin/wait-for-it.sh # 依存関係をインストール COPY backend/requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt # ---- 2. 開発用ステージ ---- FROM base as development CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] # ---- 3. 本番用ステージ ---- FROM base as production # (ここに本番用の設定を記述...) 同じディレクトリに必要なライブラリを記述します。 backend/requirements.txt fastapi uvicorn[standard] pymysql フロントエンド Node.js 22をベースに使います。VS Codeとの相性を考慮し、 alpine ではなく slim イメージを使うのが安定動作の鍵です。 frontend/Dockerfile # ---- 1. ベースステージ (依存関係のインストール) ---- FROM node:22-slim as base WORKDIR /workspace/frontend COPY frontend/package*.json ./ RUN npm ci # ---- 2. 開発用ステージ ---- FROM base as development COPY frontend/ ./ EXPOSE 3000 CMD ["npm", "run", "dev", "--", "--host"] # ---- 3. 本番用ステージ ---- FROM base as production # (ここに本番用の設定を記述...) フロントエンドも同じディレクトリに必要なライブラリを記述します。 手動で package.json を作成するよりも、 Vite (ヴィート) というツールを使ってプロジェクトの雛形を自動生成するのが現在の主流で、簡単かつ確実です。 frontend ディレクトリの中で以下のコマンドを一度実行するだけで、ReactやVueなどに最適化された最低限の package.json が自動的に作成されます。 まず、 frontend ディレクトリに移動します。 bash cd frontend 次に、Viteの作成コマンドを実行します。 bash npm create vite@latest . -- --template react このコマンドを実行すると、いくつかの質問をされますが、基本的にはEnterキーを押していけばOKです。 Step 3:VS Codeとコンテナーを繋ぐ設定 最後に、VS Codeに対して「どちらのコンテナーに接続して開発作業を行うか」を教えるための devcontainer.json を作成します。 バックエンド backend/Dockerfile { "name": "Backend Container", // 使用するdocker-compose.ymlのパスを、このファイルからの相対パスで指定 "dockerComposeFile": [ "../../docker-compose.yml" ], // docker-compose.ymlに定義したサービスの中から、接続したいサービス名を指定(最重要) "service": "backend", // コンテナに接続したときに開く作業フォルダ "workspaceFolder": "/workspace/backend", "customizations": { "vscode": { // Python開発に特化した拡張機能を追加 "extensions": [ "ms-python.python", "ms-python.vscode-pylance", "charliermarsh.ruff" // Python用の高速Linter ] } } } フロントエンド frontend/Dockerfile { "name": "Frontend Container", // 使用するdocker-compose.ymlのパス "dockerComposeFile": [ "../../docker-compose.yml" ], // 今度は'frontend'サービスに接続するよう指定 "service": "frontend", // フロントエンド用の作業フォルダを指定 "workspaceFolder": "/workspace/frontend", "customizations": { "vscode": { // フロントエンド開発に特化した拡張機能を追加 "extensions": [ "dbaeumer.vscode-eslint", "esbenp.prettier-vscode", "Codeium.codeium" ] } }, // フロントエンドのポートをフォワーディング "forwardPorts": [3001] } これで準備完了です!VS Codeでプロジェクトフォルダを開き、左下の緑色のアイコン >< をクリックして「 コンテナーで再度開く (Reopen in Container) 」を選択すると、バックエンドとフロントエンドのどちらで作業を開始するか選べるようになります! ハマりどころを徹底解説!よくあるエラーと解決策 環境構築にはエラーがつきものです。今回私が遭遇した主なエラーとその解決策を共有します。 エラー1: wait-for-it.sh: not found や Dockerfile の変更が反映されない 原因 Dockerが古いイメージキャッシュを使い回している可能性があります。 対処法 VS Codeのコマンドパレット( Ctrl+Shift+P or Cmd+Shift+P )から Dev Containers: Rebuild and Reopen in Container を実行し、イメージを強制的に再構築します。 エラー2: port is already allocated (ポートが既に使用されている) 原因 以前のコンテナーが完全に停止しておらず、ポートを掴んだままになっています。 対処法 プロジェクトルートでターミナルを開き、 docker compose down コマンドを実行して関連コンテナーをすべて停止・削除します。 エラー3: Exit code 137 (メモリ不足) 原因 Docker (特にRancher Desktop) に割り当てられたメモリが不足し、コンテナーがOSに強制終了させられています。 対処法 (Rancher Desktopの場合) : Windowsのユーザーフォルダ( C:\Users\<ユーザー名> )に .wslconfig というファイルを作成します。 以下の内容を記述して保存します。(PCの搭載メモリに合わせて 8GB の部分を調整) PowerShellで wsl --shutdown を実行し、Rancher Desktopを再起動して設定を反映させます。 PowerShell notepad .wslconfig もしファイルがまだ存在しない場合、「 新しいファイルを作成しますか? 」と聞かれるので、「 はい 」をクリックしてください。メモ帳が起動します。 開いたメモ帳に、以下の内容をコピーして貼り付けてください。 [wsl2] memory=8GB processors=4 memory=8GB : WSL全体で使用できるメモリの上限を8GBに設定します。PCの搭載メモリの半分程度を目安に、 6GB や 12GB などに調整してください。 この設定が最も重要です。 processors=4 : WSLが使用できるCPUコア数を4に設定します。PCのCPU性能に合わせて調整すると、より快適になります(省略しても構いません)。 この設定を有効にするには、WSLを 完全にシャットダウン する必要があります。 PowerShellのウィンドウに戻り、以下のコマンドを打ち込んでEnterキーを押してください。 PowerShell wsl --shutdown コラム:Codeiumとは… Codeiumは、AIを活用してコーディングを支援するツールです。 無料で始められる 手軽さと 強力なコード補完機能 で、GitHub Copilotの代替としても注目されています。 AIによるコード自動補完 入力中のコードの続きを予測して、関数全体や定型文などを数行にわたって提案してくれます。 AIとのチャット エディタ内でAIチャットが利用できます。コードの解説、リファクタリング、テストコードの生成、デバッグの補助など、コーディングに関する様々な質問や依頼を自然言語で行えます。 70以上の言語に対応 PythonやJavaScriptといった主要な言語はもちろん、C++、Java、Goなど、70種類以上のプログラミング言語に対応しており、幅広い開発プロジェクトで利用できます。 多くのエディタに対応 Visual Studio Codeをはじめ、JetBrains製IDE(IntelliJ IDEA, PyCharmなど)、Vim/Neovim、Jupyter Notebookなど、普段使っている開発環境に拡張機能として簡単に追加できます。 プライバシーとセキュリティ Codeiumは、ユーザーのコードをAIの学習データとして保存しない仕組みを採用しています。そのため、企業の機密情報や個人のプロジェクトでも安心して利用できます。 まとめ お疲れ様でした!今回は、バックエンドとフロントエンドを柔軟に切り替えながら開発できる、再現性の高いDev Container環境が完成しました。 最初は設定ファイルが多くて戸惑うかもしれませんが、一度この環境を構築してしまえば、あとは 設定ファイルをGitで管理するだけ で、チームメンバー全員が数分で全く同じ開発環境を手に入れることができます。 Github に今回紹介した開発構成をプッシュしているのでそちらもご活用ください。 環境差異による不毛なトラブルから解放され、本来集中すべきアプリケーション開発に時間を使えるようになります。ぜひDev ContainerとCodeiumを活用して、快適な開発ライフを送ってください! ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 1人がこの投稿は役に立ったと言っています。 The post 開発環境の作り方|Dev ContainerとCodeiumの活用 first appeared on SIOS Tech. Lab .
アバター
こんにちは、伊藤です。 Microsoft Entra IDでは、CSVファイルによるアカウント作成、削除の一括処理機能がありますが、パスワードの一括リセット機能はありません。 また、管理者がMicrosoft Entra IDのパスワードをリセットする場合、一般的には以下のようにユーザーの概要ページから実行します。しかし、この方法では任意のパスワードを指定できません(オンプレミスADとのアカウント同期とパスワードの書き戻しが有効な場合を除く)。 そこで今回は、これらの課題を解決するため、CSVファイルを使ってMicrosoft Entra IDのユーザーパスワードを一括でリセットするPowerShellスクリプトと、その使い方を紹介します。 本稿で取り上げた課題およびコードは2025年10月段階のものであり、今後のMicrosoft Entra IDの更新により解決されたり、修正が必要になったりする場合があります。 前提条件 ・Microsoft Entra IDテナントと、そのユーザーに対してパスワードリセットを実行できる管理者アカウントを保有していること ・使用するPowerShellにMicrosoft Graph PowerShell SDKがインストールされていること 以下のコマンドでMicrosoft Graph PowerShell SDKをインストールできます。 Install-Module Microsoft.Graph.Users -Scope CurrentUser パスワードリセット用CSVファイルを作成する 一括パスワードリセット用のCSVファイルを作成します。 ユーザープリンシパル名(UserPrincipalName)、パスワード(Password)の列を指定します。 パスワードを指定しない場合は、スクリプトがランダムなパスワードを生成します。 例: UserPrincipalName,Password test01@example.com,P@ssw0rd test02@example.com, PowerShellスクリプトを作成する PowerShellスクリプトファイルを作成します。 -InputFile オプションでCSVファイルを指定し、 -OutputFile オプションで一括パスワードリセット結果のファイルを指定できるようにします。 -OutputFile を指定しない場合は、タイムスタンプ付きのファイルが作成されます。例: reset_results_20250829155001.csv CSVファイルでパスワードを指定したユーザーはそのパスワードに、指定しなかったユーザーはランダムに生成されたパスワードにリセットされます。ランダムパスワードは、英大文字、英小文字、数字、記号がそれぞれ2文字以上含まれる16文字のランダム値を生成します。 ・entraidpasswordreset.ps1 #requires -Modules Microsoft.Graph.Users param( [Parameter(Mandatory = $true, HelpMessage = "ユーザーリストのCSVファイルパスを指定してください")] [string]$InputFile, [Parameter(HelpMessage = "結果を出力するCSVファイルパスを指定してください")] [string]$OutputFile = ".\reset_results_$(Get-Date -Format 'yyyyMMddHHmmss').csv" ) # Microsoft Graphに接続します (未接続の場合) if (-not (Get-MgContext)) { Write-Host "Microsoft Graphに接続します..." -ForegroundColor Yellow # 必要なアクセス許可スコープを指定して接続 Connect-MgGraph -Scopes "User-PasswordProfile.ReadWrite.All" } # 結果を格納するための空の配列を作成 $results = @() # CSVファイルからユーザーリストをインポート try { $users = Import-Csv -Path $InputFile } catch { Write-Host "エラー: 入力ファイルが見つからないか、読み込めません。パスを確認してください: $InputFile" -ForegroundColor Red return } Write-Host "パスワードリセット処理を開始します..." -ForegroundColor Cyan # 各ユーザーに対してループ処理 foreach ($user in $users) { $upn = $user.UserPrincipalName $newPassword = $null $forceChangeOnNextSignIn = $true # 次回サインイン時にパスワード変更を強制 try { # CSVにPassword列が存在し、かつ値が空でないかチェック if ($user.PSObject.Properties.Match('Password') -and -not [string]::IsNullOrEmpty($user.Password)) { # --- パターン1: CSVで指定されたパスワードを使用 --- $newPassword = $user.Password Write-Host "[$upn] CSVで指定されたパスワードを設定します。" } else { # --- パターン2: ランダムなパスワードを生成 --- Write-Host "[$upn] ランダムパスワードを生成します。" $charSets = @{ Upper = 'ABCDEFGHIJKLMNPQRSTUVWXYZ' Lower = 'abcdefghijlkmnpqrstuvwxyz' Number = '0123456789' Symbol = '@#$%^&*-_!+=[]{}|\:'',.?/`~"();<>' } $passwordChars = [char[]]($charSets.Upper.ToCharArray() | Get-Random -Count 2) + [char[]]($charSets.Lower.ToCharArray() | Get-Random -Count 2) + [char[]]($charSets.Number.ToCharArray() | Get-Random -Count 2) + [char[]]($charSets.Symbol.ToCharArray() | Get-Random -Count 2) $remainingChars = [char[]]($charSets.Values -join '') | Get-Random -Count 8 $newPassword = ($passwordChars + $remainingChars | Get-Random -Count 16) -join '' } # パスワードリセットの実行 $passwordProfile = @{ ForceChangePasswordNextSignIn = $forceChangeOnNextSignIn Password = $newPassword } Update-MgUser -UserId $upn -PasswordProfile $passwordProfile -ErrorAction Stop Write-Host "成功: $($upn) のパスワードをリセットしました。" -ForegroundColor Green $results += [PSCustomObject]@{ UserPrincipalName = $upn NewPassword = $newPassword Status = "Success" } } catch { $errorMessage = $_.Exception.Message Write-Host "失敗: $($upn) のパスワードリセット中にエラーが発生しました。エラー: $errorMessage" -ForegroundColor Red $results += [PSCustomObject]@{ UserPrincipalName = $upn NewPassword = "N/A" Status = "Failed - $errorMessage" } } } # 結果をCSVファイルに出力 $results | Export-Csv -Path $OutputFile -NoTypeInformation -Encoding UTF8 # Microsoft Graphから切断します Write-Host "Microsoft Graphから切断します..." -ForegroundColor Yellow Disconnect-MgGraph Write-Host "全ての処理が完了しました。結果は '$($OutputFile)' を確認してください。" -ForegroundColor Cyan このスクリプトは、ユーザーが次回サインインする際にパスワードの変更を強制します。 もしパスワード変更を強制したくない場合は、スクリプト内の以下の行を見つけ、値を $true から $false に修正してください。 変更前: $forceChangeOnNextSignIn = $true # 次回サインイン時にパスワード変更を強制 変更後: $forceChangeOnNextSignIn = $false # 次回サインイン時にパスワード変更を強制しない PowerShellスクリプトを実行してユーザーパスワードを一括リセットする PowerShellスクリプトを実行します。 例: > .\entraidpasswordreset.ps1 -InputFile .\reset_users.csv -OutputFile .\reset_users_result.csv Microsoft Graphに未接続の場合はログイン画面が表示されます。Microsoft Entra IDのユーザーに対してパスワードリセットを実行できる管理者アカウントでログインします。 Microsoft Graphに接続後はパスワードリセット処理が実行されます。 パスワードリセットに成功した場合は「成功: <ユーザープリンシパル名>のパスワードをリセットしました。」と表示されます。 パスワードリセットに失敗した場合は「失敗: <ユーザープリンシパル名>のパスワードリセット中にエラーが発生しました。」と表示されます。 全ての処理が完了すると、一括パスワードリセット結果が出力用のCSVファイルに書き込まれます。このファイルには、ユーザープリンシパル名、新しいパスワード、そして処理結果(成功の場合は「Success」、失敗の場合は「Failed – <エラーの詳細>」)が記録されます。 例: "UserPrincipalName","NewPassword","Status" "pwreset-test01@example.com","deko89IFLEU","Success" "pwreset-test02@example.com","H7T*#t9smrahS@3U","Success" "pwreset-test03@example.com","N/A","Failed - [Request_BadRequest] : The specified password does not comply with password complexity requirements. Please provide a different password." パスワードリセットの失敗例 パスワードリセットに失敗した場合のよくある原因を以下に示します。 Microsoft Graphに接続できない Microsoft Graphに接続できなかった場合は以下のエラー文が表示されます。 Authentication needed. Please call Connect-MgGraph. ユーザーがMicrosoft Entra IDテナント内に存在しない Microsoft Entra IDテナント内に存在しないユーザープリンシパル名を指定すると、対象ユーザーが存在しないためエラーになります。この場合は以下のエラー文が表示されます。 [Request_ResourceNotFound] : Resource '<指定したユーザープリンシパル名>' does not exist or one of its queried reference-property objects are not present. リセットしようとしたパスワードが、Microsoft Entra IDのパスワードポリシーに違反している パスワードを指定してリセットした場合、Microsoft Entra IDのパスワードポリシーによりパスワードのリセットに失敗する場合があります。この場合は以下のエラー文が表示されます。 [Request_BadRequest] : The specified password does not comply with password complexity requirements. Please provide a different password. パスワードポリシーを無視してパスワードをリセットしたい場合は、ユーザーのパスワードポリシーを一時的に変更してパスワードをリセットすることも可能です。その場合は、Microsoft Graphに接続する箇所およびユーザー情報を更新する箇所を修正してください。 <省略> # Microsoft Graphに接続します (未接続の場合) if (-not (Get-MgContext)) { Write-Host "Microsoft Graphに接続します..." -ForegroundColor Yellow # 必要なアクセス許可スコープを指定して接続 Connect-MgGraph -Scopes "User.ReadWrite.All,User-PasswordProfile.ReadWrite.All" } <省略> # パスワードリセットの実行 $passwordProfile = @{ ForceChangePasswordNextSignIn = $forceChangeOnNextSignIn Password = $newPassword } Update-MgUser -UserId $upn -PasswordPolicies "DisableStrongPassword" -ErrorAction Stop Update-MgUser -UserId $upn -PasswordProfile $passwordProfile -ErrorAction Stop Update-MgUser -UserId $upn -PasswordPolicies None -ErrorAction Stop <省略> Microsoft Entra IDの運用上パスワードを無期限にしたい場合は、パスワードリセット処理後のパスワードポリシー( -PasswordPolicies )を None から "DisablePasswordExpiration" に修正してください。 まとめ 今回は、CSVファイルを利用してMicrosoft Entra IDのユーザーパスワードを一括リセットするPowerShellスクリプトを紹介しました。 Microsoft Entra IDのアカウント管理に活用していただけると幸いです。 参考 参考 Microsoft Graph PowerShell を使用してパスワードを管理する – Microsoft 365 Enterprise 参考 セルフサービス パスワード リセット ポリシー – Microsoft Entra ID 参考 PowerShell を使用してランダムな文字列を生成する方法 Delft スタック ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Microsoft Entra IDのユーザーパスワードを一括リセットする first appeared on SIOS Tech. Lab .
アバター
はじめに 今回から複数の記事にまたがって KubernetesでDBを管理するために役立つKubeBlocksというソリューションについて解説します。KubeBlocksがどんなソリューションであるか理解するとともにKubernetesでのDB管理の重要性について理解していただけると幸いです。 DBaaSとは Kubeblocksの解説に入る前に、まず「DBaaS」と、それをKubernetes上で実現するメリットについて整理します。 DBaaS(Database as a Service)とは、クラウド上で提供されるデータベース管理サービスです。 従来のデータベース管理はデータベースサーバーのセットアップからパッチ適用、バックアップ、監視といった運用タスクを手動で行う必要がありました。DBaaSを利用することで、それらの操作を簡易化・自動化することが可能になります。 従来のDB管理とDBaaSの比較 KubernetesでDB管理することの重要性 DBをKubernetesで管理することによって大きく3つの利点があります。 運用プラットフォームの統一 Kubernetesにアプリケーションをデプロイして、外部でDBを管理している場合、運用するプラットフォームが分断されて運用コストが上がってしまいます。アプリケーションがデプロイされているKubernetes上でもDBを管理することで運用がシンプルになり、運用コストを抑えることができます。 高度なDB構成を簡易に構築 Kubernetesのオーケストレーション機能を活用することで、冗長性や可用性を考慮した高度なDB構成を簡易に構築することが可能です。 また、DBの運用作業を自動化することが可能で、構築から運用まですべての管理を効率化することができます ベンダーロックインの回避 特定のクラウドベンダーのDBaaSを利用すると、その特定のシステムの仕様に深く依存することになり、将来的に別の環境に移行する際の障壁が高くなります。 KubernetesでDB管理する場合、YAMLファイルといった統一的なファイルを利用することで別環境でも同一のDB構成を簡単に構築することが可能です。 KubeBlocksの概要 KubeBlocksはデータベース用のオープンソースKubernetesオペレーターです。 KubeBlocksの構造(参照:https://kubeblocks.io/docs/preview/user_docs/overview/introduction) KubeBlocksを導入することによってKubernetesクラスタ上に、DBaaSを構築することが可能です。 KubeBlocksの大きな特徴として、特定のDBに依存しない汎用的なDBオペレーターになっています。これにより、データベースのデプロイ、スケーリング、バックアップといった複雑な運用タスクが自動化されます。さらに、PostgreSQLやMySQLなど様々な種類のデータベースを、統一されたYAML記法で管理できるため、複数DBの運用が非常にシンプルかつ効率的になります。   MySQLクラスターを構築するYAMLファイルの例 apiVersion: apps.kubeblocks.io/v1 kind: Cluster metadata: name: test-mysql namespace: demo spec: terminationPolicy: Delete componentSpecs: - name: mysql componentDef: "mysql-8.0" serviceVersion: 8 . 0 . 35 disableExporter: false replicas:   2 resources: limits: cpu: '0.5' memory: 0 . 5Gi requests: cpu: '0.5' memory: 0 . 5Gi volumeClaimTemplates: - name: data spec: storageClassName: "" accessModes: - ReadWriteOnce resources: requests: storage: 20Gi PostgreSQLクラスターを構築するYAMLファイルの例 apiVersion: apps.kubeblocks.io/v1 kind: Cluster metadata: name: test-pg namespace: demo spec: terminationPolicy: Delete clusterDef: postgresql topology: replication componentSpecs: - name: postgresql serviceVersion: 16.4.0 disableExporter: true replicas: 2 resources: limits: cpu: "0.5" memory: "0.5Gi" requests: cpu: "0.5" memory: "0.5Gi" volumeClaimTemplates: - name: data spec: accessModes: - ReadWriteOnce resources: requests: storage: 20Gi KubeBlocksには「kbcli」というコマンドラインツールが備わっています。これを利用することでKubeBlocksのリソースの操作をより簡単に行うことが可能です。 「kbcli」で出来る操作としてDBクラスタのバックアップの作成、kbcliの追加機能の管理、データベースクラスタのライフサイクル管理、kubeBlocks自体の管理などがあります。 KubeBlocksに対応しているDBソリューションに関してはシリーズ第2回となる次のブログ記事で、具体的な一覧と共に詳しく解説します。 KubeBlocksでDBクラスターを構築した際の構成例が以下になります: KubeBlocksの構成例(参照:https://kubeblocks.io/docs/preview/user_docs/overview/introductio) デフォルトでは、KubeBlocks Control Planeと呼ばれるKubeBlokcsの管理を行うノードとKubeBlocks Data Planeと呼ばれるDBがデプロイされるノードに別れます。これにより高可用性を保持することが可能になります。 さらに、データベースクラスターの各レプリカをAvailability Zones(AZ)に分散させることで、災害復旧能力も高めることが可能です。 KubeBlocksの主要機能 様々な種類のDBクラスターのプロビジョニング・削除・起動・停止・再起動 幅広いDay-2 オペレーション 水平スケーリング 垂直スケーリング DBクラスターが使用しているPVCの拡張 バックアップ・リストア DB構成の変更 DBインスタンスの移行 ローリングアップデート Prometheusと連携した監視 他類似OSSDB管理ソリューションとの比較 Kubernetes上でデータベースを管理するためのオペレーターはいくつか存在しますが、ここでは代表的なオープンソースのオペレーターであるKubeDB, Percona Everest, StackGresとKubeBlocksを比較し、それぞれ特徴と最適なユースケースを探ります。 OSSDB管理ソリューションの比較 この比較表から分かるように、各オペレーターには得意分野があります。 KubeDB KubeDBは、非常に多くのデータベースをサポートする汎用性の高いオペレーターです 。運用機能も豊富で、GitOpsとの連携も可能です 。ただし、オープンコアモデルを採用しており、バックアップや監視などの多くの高度な機能は有償のエンタープライズ版でのみ利用可能という点に注意が必要です 。 Percona Everest Percona Everestは、Perconaが提供するデータベース(PostgreSQL, MySQL, MongoDB)に特化しています 。最大の特徴は、Perconaの強力な監視ツール「PMM (Percona Monitoring and Management)」と深く連携し、クエリ分析など高度な監視を容易に実現できる点です 。直感的なWeb UIも提供されており、CLI操作に不慣れなユーザーでも扱いやすいのが魅力です 。 StackGres StackGresは、対応データベースをPostgreSQLに絞ることで、その運用を極限まで自動化・最適化することに特化したオペレーターです 。高可用性を実現するPatroniや接続プーリングを行うPgBouncerが標準で統合されており、150以上の拡張機能が利用可能です 。PostgreSQLをメインで利用する開発チームにとって、最も高機能な選択肢の一つと言えるでしょう。100%オープンソースであることも大きな特徴です 。 おわりに 本記事では、Kubernetes上でDBaaSを実現するソリューションとして、オープンソースの汎用データベースオペレーター「KubeBlocks」を解説しました。KubeBlocksは、特定のデータベースに依存しない高い汎用性を持ち、多種多様なデータベースを統一された手法で効率的に管理できる非常に強力なツールです。 多様なデータベースを運用している環境 運用をシンプルに統一したいチーム 上記のようなニーズを持つチームにとって、KubeBlocksは最適な選択肢の一つとなるでしょう。今後もKubeBlocksについての解説ブログを掲載していくのでよろしくお願いします。 参考文献 KubeBlocks公式ドキュメント: https://kubeblocks.io/docs/preview/user_docs/overview/introduction KubeDB公式ドキュメント: https://kubedb.com/ Percona Everest公式ドキュメント: https://www.percona.com/software/percona-everest StackGres公式ドキュメント: https://stackgres.io/features/ kbcliコマンドリファレンス: https://kubeblocks.io/docs/preview/cli/kbcli ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post KubeBlocksとは?KubernetesでDBを管理する新常識 first appeared on SIOS Tech. Lab .
アバター
OSS よろずチームの神﨑です。 RHEL 10 同梱版の Podman の変更点について簡単にまとめていきたいと思います。 Podman のインストールと起動確認 AWS の RHEL10 のインスタンスで検証しています。 1.インストール # dnf install podman # podman version Client: Podman Engine Version: 5.4.0 API Version: 5.4.0 Go Version: go1.23.10 (Red Hat 1.23.10-1.el10_0) Built: Wed Jun 25 00:00:00 2025 Build Origin: Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla> OS/Arch: linux/amd64 2.コンテナイメージ導入 (httpd) # podman search httpd # podman pull registry.access.redhat.io/ubi10/httpd-24 3. コンテナの起動 実行例 # podman run -d -p 8080:8080/tcp --name my-rootless-httpd registry.redhat.io/ubi10/httpd-24 Podman に関する変更点 RHEL 公式ドキュメントを確認したところ以下の記述がありました。 containers.conf ファイルの読み取り専用となる システム接続とファームの情報が containers.connections.json に移動しました。 CNI ネットワークスタックのサポート終了と netavark への移行 containernetworking-plugins パッケージが削除され、CNI がサポートされなくなります。 runc コンテナランタイムの削除 デフォルトのコンテナランタイムが crun になります。 slirp4netns ネットワークモードが非推奨となる ルートレスコンテナのデフォルトネットワークモードが pasta になります。 RHEL 10 ホストでの RHEL 7 コンテナの非サポート 詳細は、 Red Hat Enterprise Linux Container Compatibility Matrix  を参照してください。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post RHEL 10 同梱版の Podman についての調査 first appeared on SIOS Tech. Lab .
アバター
Webサイトやアプリ開発の現場で、「デザインシステム」という言葉を耳にする機会が増えていませんか?「なんだか難しそう…」「自分には関係ないかも」と感じている方もいるかもしれません。 しかし、デザインシステムは、開発の効率を上げ、チームのコミュニケーションを円滑にし、プロダクトの品質を一貫して高く保つための、非常に強力な武器になります。 この記事で「良さそう、面白そう」と思っていただければ幸いです。 デザインシステムとは? 「デザインシステム」って、そもそも何でしょうか? その定義は場合によって異なり、ひとつに定めるのは、難しいです。 そこで、ザックリ「狭義の…」「広義の…」と2つに分けて解釈を試みます。 狭義のデザインシステム:再利用可能な「部品集」 狭義のデザインシステムは、 デザインの具体的な構成要素やルールをまとめたもの を指します。これは、デザイナーやエンジニアが直接的に利用する「部品」や「説明書」の集まりと考えると分かりやすいでしょう。 UIコンポーネント : ボタン、フォーム、アイコン、カードなど、繰り返し使えるデザインの部品。 デザイントークン : 色、タイポグラフィ(フォントサイズや種類)、スペーシング(間隔)などを管理する変数。これにより、デザインの変更が一括で容易になります。 スタイルガイド : ブランドのロゴの使用法や、デザインの原則などを定めたルールブック。 ドキュメンテーション : 各コンポーネントの使い方や、デザインの意図を解説した文書。 これらは、Figmaのようなデザインツールや、Storybookのような開発者向けのコンポーネントライブラリとして具体的に存在します。 一言でいうと :「デザインと開発で使う、再利用可能な『レゴブロック』と『その組み立て方』のセット」です。 広義のデザインシステム:一貫性を生み出す「文化」と「プロセス」 広義のデザインシステムは、単なる部品集にとどまらず、 製品開発に関わる人々の協力体制や思想、ワークフロー全体 を包含します。 思想と原則 : なぜそのデザインなのか?という根本的な考え方や、チームが共有する価値観(例:「シンプルであること」「アクセシビリティを重視すること」など)。 コミュニケーション : デザイナー、エンジニア、プロダクトマネージャーなどが円滑に協力するためのコミュニケーションの仕組みや文化。 ガバナンス : デザインシステムを誰が、どのように更新し、管理していくかという運用ルール。 ワークフロー : デザインシステムを実際の製品開発に組み込み、継続的に改善していくプロセス。 こちらは、ツールとして存在するだけでなく、チームの文化や働き方そのものに根付いています。 一言でいうと :「良い製品を効率的に作り続けるための『共通言語』であり、チームの『文化』」です。 上記はあえて2つに分類しましたが、実際のデザインシステムは広義と狭義の中間にあることが多いかと思います。 また、デザインシステムは、一度作って終わりではありません。プロダクトやチームの成長に合わせて、継続的に育てていくものです。 なぜ、いま「デザインシステム」なのか? 「車輪の再発明」を減らす パソコンとスマートフォンは、多くのひとの仕事や生活のツールとして実用化し、コモディティ化と言ってよい段階と捉えています。 わたしたちが、新たなアプリケーション、ウェブサイトを構築する際、多くの場合に既存のデザインシステムが参考になります。 SmartHRのデザインシステムにて述べられている「“車輪の再発明”を減らす」という考え方です。 https://smarthr.design/introduction/operate-policy 巨人の肩の上に立つ ありがたいことに、世界の大企業や政府を始めとする、さまざまな団体の知見を活用することができます。 公開された各デザインシステムは、日々進化していますが、その多くが高い品質に達しています。 生成AI時代のUIの土台 「生成AI」によって、コンピューターを利用するためのインターフェースは、見直されていくかもしれません。 今後、AIによってUIの生成が自動化されても、その基盤となる一貫したルールやコンポーネントは必要となるでしょう。 事例紹介:世界の優れた公開デザインシステム 品質、汎用性、応用性が高く、Figmaファイルも公開されているデザインシステムを、UIデザイナーの視点でピックアップして、紹介します。 政府系 行政は対象者が多様なため、特にアクセシビリティを重視していることが特徴かと思います。 文字やボタンなどの要素は大きく、余白も十分。 イギリス政府「GOV.UK Design System」 https://design-system.service.gov.uk/ https://www.figma.com/community/file/946837271092540314/gov-uk-design-system シンプル、アクセシブル、スタイリッシュ、が実現されています。 スタイルとしては、ボタンの形状が角丸ではなく四角いのも特徴。 「Cookie banner」がコンポーネント化されているのもヨーロッパらしいです。 抽象面では、Principles(原則)も秀逸で、ポスターもあります。 https://www.gov.uk/guidance/government-design-principles https://github.com/alphagov/govdesign/blob/main/Poster_GovernmentDesignPrinciples.pdf アメリカ政府「U.S. Web Design System (USWDS)」 https://designsystem.digital.gov/ https://www.figma.com/@uswds 文字サイズ定義の最小がイギリス政府のものが16pxに対して、こちらは13pxです。 UI要素全般的に、イギリス政府に比べると小さい設計です。 これは、大きな国土、多くの人口、多様性、という背景から、訴訟社会、ローコンテクストな傾向にあるため、さまざまなシーンで説明的になる。つまり文章が長く、文字が多くなるのでしょう。 多くの情報が表現できることと、アクセシブルであることのバランスを定着させた事例と捉えています。 デジタル庁(日本) https://design.digital.go.jp/ https://www.figma.com/@digitalagencyjp イギリス政府のデザインシステムと同様に、シンプルで明快な印象のスタイルです。 UIコンポーネントの名称は「検索ボックス」「パンくずリスト」「日付ピッカー」のように、平易な表現となっています。 近い将来、各省庁をはじめ、多くの各行政機関のサイトが、このデザインシステムに沿って構築、運用されることを、期待しています。 日本の企業 SmartHR https://smarthr.design/ https://www.figma.com/community/file/978607227374353992 フルセットのデザインシステムです。 デザインシステムの構想、構築、運用を教えてくれる書籍「ちいさくはじめるデザインシステム」も出版されています。 https://bnn.co.jp/products/9784802512480 デザインシステムを学習、検討するなら必見です。 Ubie「Ubie Vitals」 https://vitals.ubie.life/ https://www.figma.com/design/ejIFAbw12HtoEZXcn01G5C/Ubie-UI https://www.figma.com/@ubie デザイン原則では「気軽」「かんたん」「誠実」「スッキリ」と謳われています。 その原則がドキュメントにも現れており、簡潔で把握しやすいです。 シンプルであるとともに、ライディングガイドライン、コンポーネント、GitHubでのコード公開など、ドキュメントの構成が行き届いています。 ライティングガイドラインには医療機関での問診の文例があり、アイコン集には形状の異なる複数の薬剤など「医療」という特定の分野に焦点あわせて設計された事例としても参考になります。 「Ubie Vitals」という名前は、医療用語の「バイタルサイン」に由来していると考えられ、デザインシステムの重要性と、医療分野へ注力していることが表されていると思います。 プラットフォーマー Google「Material Design」 https://m3.material.io/ https://www.figma.com/@materialdesign Android OS、Googleの各サービスが基本的にこれに則っており、一番利用されているUIかもしれません。 最も影響力のあるデザインシステムと言ってもよいでしょう。 Material DesignをReactで実装する際は、MUIが便利です。(MUIはMaterial Designのバージョン2を基にしています。) https://mui.com/ Apple「ヒューマンインターフェイスガイドライン(HIG)」 https://developer.apple.com/jp/design/human-interface-guidelines/ https://www.figma.com/@apple 「無料で公開されている資料」ではありますが、オープンソースではありません。 基本的には、iPhoneやMacなど、Apple製品向けアプリケーション開発を行う際に参照するドキュメントです。 「デザインシステム」という言葉が広く使われるようになったのは2010年代ですが、Appleは1980年代からHIGを定めています。 ユーザー体験を重視し、パソコンやスマートフォンを絶対的な価値に高めたメーカーが、どのような考え方でUI構築をしているのかを知ることができます。 スマートウォッチや、MR(複合現実)ヘッドセットのUIも含まれているのも特徴です。 IT分野、業務向け 各政府や、Google、Appleなどのデザインシステムが主に消費者向けなのに対し、IBM、GitHub、Atlassianの例は、複雑で大量の情報を扱うための効率性や機能性を追求した専門家向けです。 IBM「Carbon」 https://carbondesignsystem.com/ https://www.figma.com/@50ffba2e_c3b3_4 AI生成のコンテンツであることを示す「AI Label」コンポーネントも用意されています。 GitHub「Primer」 https://primer.style/ https://www.figma.com/community/file/854767373644076713 「Product UI」「Brand UI」に分けて設計されており、どちらも公開されています。 Atlassian https://atlassian.design/ https://www.figma.com/@atlassian 今回は、デザインシステムの基本的な捉え方から、公開されている優れた事例までを紹介しました。 まずは今回紹介したデザインシステムを実際に触ってみることから始めてみませんか?公開されたドキュメントを眺めるだけでも、UIデザインの新たな発見があるはずです。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 良いプロダクトは「システム」でできている。デザインシステムとは何か? first appeared on SIOS Tech. Lab .
アバター
こんな方へ特におすすめ 勤怠管理システムへの申請、特に細かな作業時間の入力が面倒な方 タスクごとにどのくらいの時間がかかっているか、感覚でしか分からない方 簡単にPythonのアプリを開発したい方 概要 こんにちは。サイオステクノロジーのはらちゃんです!今回4本目のブログ執筆です。 今回は私が作成したストップウォッチアプリの紹介と、その開発過程、そして皆さんの勤怠管理や作業効率向上に役立つヒントをお伝えします。 なぜ自作ストップウォッチアプリが必要だったのか? 私の職場では、勤怠報告で作業の種類ごとに工数を確認する必要がありました。 「〇〇プロジェクトの設計」「△△タスクのコーディング」「定例会議」など、作業ごとに時間を測りたい──。 そんな想いから自分で作って自由にカスタムできるアプリを作ろうと考えました。 簡単!ストップウォッチの作り方 以下のような単純な機能をもつアプリを作っていこうと思います。 デスクトップに表示されます 機能としては上から ラベルに入力 タイマー表示 開始、停止ボタンのクリック タイマー個数の増減ボタンのクリック が行えます。 前提条件 VSCodeのインストール Pythonの開発環境 ステップ1:ホストOSの準備 まず、コンテナーのGUIをPC本体の画面に映し出すための「Xサーバー」というソフトをインストールします。これは初回のみ必要な作業です。 Xサーバーをインストールする。 Windowsの場合: VcXsrv をインストールして起動します。 Macの場合: XQuartz をインストールして起動します。 Display settings: 「 Multiple windows 」を選択して「次へ」。 Client startup: 「 Start no client 」を選択して「次へ」。 Extra settings: 「Disable access control」 に 必ずチェック を入れて「次へ」。 「完了」をクリックしてVcXsrvを起動します。 このような設定画面が起動します。 ステップ2:ストップウォッチアプリの実装 このPythonコードをコピーしてファイルに保存するだけですぐに動かすことができます。 stopwatch.py import tkinter as tk import time class StopwatchApp: def __init__(self, parent): # Frameを作成し、親ウィジェット(parent)に配置 self.frame = tk.Frame(parent) self.frame.pack(side=tk.LEFT, padx=15, pady=15) # --- ストップウォッチの状態を管理する変数 --- self.running = False self.start_time = 0.0 self.elapsed_time = 0.0 # --- ラベル編集部品 --- self.label_var = tk.StringVar() self.label_var.set("タイマー") self.label_entry = tk.Entry(self.frame, textvariable=self.label_var, font=("Arial", 10), justify="center", width=8) self.label_entry.pack(pady=(0,2)) # --- 画面の部品(ウィジェット)を作成 --- self.time_label = tk.Label(self.frame, text="00:00", font=("Arial", 40, "bold")) self.time_label.pack(pady=4) self.toggle_button = tk.Button(self.frame, text="Start", width=13, command=self.toggle) self.toggle_button.pack(pady=4) self.update() def toggle(self): """ボタンが押されたときの処理""" if self.running: # ストップ処理 self.running = False self.toggle_button.config(text="Start") else: # スタート処理 self.running = True self.toggle_button.config(text="Stop") self.start_time = time.time() - self.elapsed_time def update(self): """時間を計算して表示を更新する処理""" if self.running: self.elapsed_time = time.time() - self.start_time self._display_time() self.frame.after(10, self.update) def _display_time(self): """経過時間を見やすい形式に変換してラベルに表示(時間:分)""" hours = int(self.elapsed_time // 3600) minutes = int((self.elapsed_time % 3600) // 60) time_string = f"{hours:02}:{minutes:02}" self.time_label.config(text=time_string) # --- アプリケーションの実行 --- class StopwatchManager: def __init__(self, root): self.root = root self.stopwatches = [] self.frame = tk.Frame(root) self.frame.pack() # ボタン配置 btn_frame = tk.Frame(root) btn_frame.pack(pady=4) self.add_btn = tk.Button(btn_frame, text="○", font=("Arial", 12), width=4, command=self.add_stopwatch) self.add_btn.pack(side=tk.LEFT, padx=4) self.remove_btn = tk.Button(btn_frame, text="×", font=("Arial", 12), width=4, command=self.remove_stopwatch) self.remove_btn.pack(side=tk.LEFT, padx=4) # 初期2つ self.add_stopwatch() self.add_stopwatch() def add_stopwatch(self): sw = StopwatchApp(self.frame) self.stopwatches.append(sw) self.update_window_size() def remove_stopwatch(self): if self.stopwatches: sw = self.stopwatches.pop() sw.frame.destroy() self.update_window_size() def update_window_size(self): width = max(205 * len(self.stopwatches), 205) self.root.geometry(f"{width}x200") # --- アプリケーションの実行 --- if __name__ == "__main__": root = tk.Tk() root.title("StopWatch") root.resizable(False, False) root.attributes("-topmost", True) manager = StopwatchManager(root) # 初期ウィンドウサイズ root.geometry("410x200") root.mainloop() ステップ3:実行 ターミナルで以下のコマンドを入力するとアプリが起動します。 bash python3 stopwatch.py 実行できないときは… 解決策1:ライブラリのダウンロードする Pythonには「 Tkinter 」というGUI(画面付きアプリ)を作るためのライブラリが標準で付属しているため、追加のインストールなしですぐに開発を始められます。 しかし、Linuxで操作している場合は手動でのダウンロードが必要です。 bash sudo apt update sudo apt install python3 python3-tk 解決策2:ファイアウォールの設定を確認する VcXsrvを初めて起動したとき、Windows Defenderファイアウォールが警告画面を表示したはずです。 ここで「 アクセスを許可する 」を選択しないと、通信がブロックされてしまいます。 Windowsの検索バーで「 ファイアウォール 」と検索し、「 Windows Defender ファイアウォールによるアプリの許可 」を開きます。 「設定の変更」をクリックし、「別のアプリの許可」をクリックします。 「参照」からVcXsrvの実行ファイル(通常は C:\Program Files\VcXsrv\vcxsrv.exe )を選択して追加します。 一覧に追加された「vcxsrv」の「 プライベート 」と「 パブリック 」の両方のチェックボックスをオンにして「OK」をクリックします。 まとめ 今回は、ストップウォッチのアプリ開発を通して、PythonとTkinterを使えば、日常のちょっとした不便を解消するアプリを自作できる楽しさを学んでいきました。 Github でも、私の開発コードを公開しているので、自由にコードを書き替えて使ってみてくださいね。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 1人がこの投稿は役に立ったと言っています。 The post 勤怠管理の仕方|Tkinterで自作ストップウォッチ first appeared on SIOS Tech. Lab .
アバター
OSSよろずサポート担当の神﨑です。 今回は Dify についてソースコード、ドキュメント、検証を行った際の知見についてすでに公開されている弊社の記事と重ならない範囲で軽くまとめていきます。 Dify について Difyの概要や全体像については、 弊社エンジニアの解説記事 がありますので、ご参照ください。 Dify の呼称について 上記記事に掲載されていない一口メモとして Dify の読み方について説明します。 Dify のことを筆者は最近まで「ディファイ」と呼んでいましたが、正式な呼称は「ディフィ」となっております。 参考: https://xtech.nikkei.com/atcl/nxt/column/18/03236/061200004/ Dify + Amazon Bedrock について 弊社では AzureAI を利用した Dify の記事が数多く公開されていますが、今回は AWS の Amazon Bedrock という LLM で検証しました。 Dify で Amazon Bedrock を設定するやり方についても、 弊社エンジニアの解説記事 をご確認ください。 弊社で公開しているチャット bot やワークフロー、 RAG を作成してみましたが、問題なく動作しました。 アプリケーションを作成するうえでの注意点 Amazon Bedrock 上で有効化したモデル以外を選択した場合、LLM ノードにおいてエラーが出力されてしまうため有効化したモデルを正しく選択する必要があることにご注意ください。 Dify のエラー処理 Dify の各ノードで出力されるエラーについてまとめていきます。 参考: エラー処理 – エラータイプ概要 チャットフロー/ワークフロー システムエラー サービスが正しく起動していない、ネットワーク問題など 操作エラー ノードの設定や操作に失敗した際のエラー コードノード コードエラー(CodeNodeError) 開発者の設定したコード内にエラーがある場合に発生するエラー サンドボックスのネットワーク問題(System Error) ネットワークのトラフィックや 接続問題によって発生するエラー ネスト制限エラー(DepthLimitError) ノードのネスト構造が 5層以上の場合に発生するエラー 出力検証エラー(OutputValidatioのnError) 出力変数の型が一致しない場合に発生するエラー LLM ノード 変数が見つからない(VariableNotFoundError) 指定された変数が見つからない場合に発生するエラー コンテキスト構造の無効 (InvalidContextStructureError)   不正なデータ構造 (文字列以外) を受け取った場合に発生するエラー 無効な変数タイプ(InvalidVariableTypeError) システムプロンプトの形式が一般的なテキストや Jinja syntax でない場合に発生するエラー モデルが存在しない(ModelNotExistError) LLM ノードにモデルが設定されていない場合に発生するエラー  LLMの認証が必要(LLMModeRequiredError) 選択されたモデルに API キーが設定されていない場合に発生するエラー プロンプトが見つからない(NoPromptFoundError) LLM ノードのプロンプトが空の場合に発生するエラー HTTPノード 認証設定エラー(AuthorizationConfigError) 認証情報が設定されていない場合に発生するエラー ファイル取得エラー(FileFetchError) ファイル変数が取得できない場合に発生するエラー 不正なHTTPリクエストメソッド(InvalidHttpMethodError) リクエストメソッドが GET、HEAD、POST、PUT、PATCH、DELETE のいずれにも該当しない場合に発生するエラー レスポンスサイズ超過(ResponseSizeError) HTTPレスポンスコードエラー(HTTPResponseCodeError) レスポンスコードが 200系以外(例:400、404、500など)の場合に発生するエラー ※例外処理が有効であれば、これらのステータスコードによるエラーが報告される ツールノード ツール実行エラー(ToolNodeError) ツール自体の実行に問題があった場合に発生するエラー ツールパラメータエラー(ToolParameterError) ツールノードが要求するパラメータと異なる値が入力された場合に発生するエラー ツールファイル処理エラー(ToolFileError) ツールノードの処理に必要なファイルが見つからない場合に発生するエラー ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Dify のチュートリアルを終えての知見 (出力されたエラーなど) first appeared on SIOS Tech. Lab .
アバター
プリザンター® Pleasanter® は株式会社インプリムの登録商標です。 はじめに 今回は、9/19(金)に名古屋でオフライン開催された「 プリザンターハンズオンセミナー 」に参加してまいりましたので、そのレポートをさせていただきます。 本セミナーは、特にプリザンターを使ったことがない方や、使い始めたばかりの初心者の方向けの内容として構成されており、その基本操作を実際に手を動かしながら体験できる貴重な機会でした。 アイキャッチは当日いただいたアンブレラマーカー、クリアファイル、ステッカーです。 プリザンター® Pleasanter® は株式会社インプリムの登録商標です。 イベントの概要 本セミナーは名古屋にてオフライン形式で開催されました。 開催日時:2025年9月19日(金) 16:30〜18:00 会場:愛知県名古屋市中村区太閤1丁目20-13 秀幸ビル 6階 601号 (オフライン開催) 主催:株式会社インプリム 共催:プレシャスト株式会社 費用:無料 定員:15名(先着順) 60日間無料で全機能を試せるデモ環境 を使ってのハンズオンセミナーでした。 Pleasanter(プリザンター)とは Pleasanterはノーコードで業務アプリを作成できるプラットフォームです。Excelのような親しみやすい操作感で、プログラミングの知識がなくても簡単に業務アプリを作成することができます。顧客管理やプロジェクト管理、日報の管理などの散在しがちな情報を一元化して管理ができることが大きな特長です。 システム導入においても柔軟性が高く、クラウドでの利用はもちろん、インターネットに接続できないオンプレミス環境への導入にも対応しています。 Pleasanterの特徴的な機能 Pleasanterは、業務効率化と情報セキュリティを両立させる多様な機能を備えています。 進捗の可視化 標準機能としてガントチャートやカンバン機能なども搭載されており、業務の進捗状況の可視化、チーム内での情報共有を効率化することができます。 豊富なテンプレート 顧客情報、FAQ、資産管理など、幅広い業務に対応した業務アプリが多数用意されています。 通知・リマインド アプリケーション内の更新情報をメール通知したり、タスクの期日前にリマインド通知を送る設定も可能です。 アクセス制御 個人情報などの機密性の高い情報を、特定の担当者のみが閲覧・編集できるようにアクセス制御が可能です。 プリザンターでできること 成果物の紹介 今回のハンズオンでは案件管理で用いるアプリをプリザンターで作成しました。 ハンズオンでの成果物 今回主に作成したのは「フォルダ」と「テーブル」です。 「フォルダ」は皆さんが普段PCで使っているフォルダをイメージしていただけるとわかりやすいと思います。Pleasanterではテーブルや他のフォルダを格納しツリー構造でデータを管理します。 このフォルダの中にテーブルを作成することができます。テーブルは2種類あり、タスク管理などの期限の管理を行う「期限付きテーブル」と、資産管理などの情報の管理に使用する「記録テーブル」の二つがあります。テーブルの中には「レコード」を登録することができ、各タスクや記録の内容はこのレコードを登録することで管理されます。   今回のハンズオンでは「営業部」という名前のフォルダを作成し、その直下に「商談」という期限付きテーブルと「顧客マスタ」という記録テーブルを作成しました。作成した各テーブル内にレコードを作成し、商談情報や顧客情報を管理できるようにしました。 さらに、実践的な機能として、レコードへの画像の添付、テーブルに親子関係を持たせてのデータ連携、集計やフィルタの設定といった、実際の業務で役立つ操作も実施しました。 参加しての感想と所感 使用した感想としては、フォルダやテーブルの作成、テーブルの管理などの操作が直感的に分かりやすく、技術的な知識がない方でも操作しやすいと感じました。 個人的に便利だと感じたのは、テーブルの設計やレコードの内容を変更した際に更新を忘れるとダイアログが出るため、更新忘れがなく便利だと感じました。 セミナー全体を通して、進行のテンポが適正で、戸惑うことなく自分のペースで手を動かしやすかった点も、主催者様のご配慮を感じるポイントでした。 プリザンターのセミナーは、今回の名古屋開催のように各地で随時開催されております。ご興味をお持ちの方は、ぜひ参加されてみてはいかがでしょうか。 セミナー情報など 参考文献 Pleasanter Pleasanterの活用シーン Pleasanter導入事例 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 【セミナーレポート】プリザンターハンズオンセミナー@名古屋に参加してきました! first appeared on SIOS Tech. Lab .
アバター
~史上最大級のnpm自己増殖型ワーム攻撃「Shai-Hulud」とその防御策~ 2025年9月15日、npmリポジトリに対する史上最大級のソフトウェアサプライチェーン攻撃「Shai-Hulud」が発見されました。この攻撃は、わずか1週間で20種類以上の悪意あるOSSパッケージを利用し、200万回以上ダウンロードされた大規模なものです。特にフィンテック企業(コイン取引所、銀行、証券など)が攻撃の対象とされることが多いとされています。 Shai-Huludは、従来の攻撃とは異なり、新しい自己増殖型マルウェア(ワーム)として自己拡散を続けます。攻撃は多段階で実行され、まずフィッシングによって開発者のGitHubやnpmトークンなどの認証情報を盗みます。開発者が感染パッケージをインストールし`postinstall`スクリプトが実行されると、悪意のあるコードが注入されます。 このコードは、環境内の機密データ(GitHubのPAT、SSHキー、AWS、GCP、Azureなどのクラウドプロバイダーのキー)を徹底的にスキャン(クレデンシャルハーベスティング)します。盗まれたデータは複数回エンコードされ、「Shai-Hulud」という名前のパブリックGitHubリポジトリなどに流出します。 最も危険な特徴は、ワームの拡散メカニズムです。有効なnpmトークンを発見すると、それを利用してメンテナが管理する他のパッケージの悪意あるバージョンを公開し、感染をエコシステム全体に広げる自己再生的なサイクルを生み出します。これは、npmエコシステムにおける最初の成功した自己増殖型ワームの一つであり、極めて深刻な脅威をもたらしています。 コミュニティベースのOSSは、その公開性や複雑な依存関係、セキュリティテストの不十分さ、コミュニティ内の信頼の悪用などから、サイバー攻撃の格好の標的となっています。 今回の事件では、多くのJFrogユーザー企業がこのリスクを防げたと報告されています。JFrog Platformは、ソフトウェアサプライチェーンのセキュリティガバナンスを全体的に守る統合プラットフォームであり、以下の主要な機能で防御策を提供します。 1. Curation機能: 悪意のあるパッケージがサプライチェーンに入る前にダウンロードを阻止する即時のガバナンスを提供します。 2. JFrog Xray: 現在の開発環境および本番環境のパッケージをリアルタイムスキャンし、「悪意度スコア」を付与して早期に脅威を発見・対策します。 3. Artifactoryのリモートリポジトリ機能: 外部パッケージリポジトリからのキャッシュを管理し、悪意あるアーティファクトの侵入を防ぎます。 もし影響を受けたパッケージをインストールしていた場合、GitHub、NPM、AWS、GCP、Azureなどで使用していたアクセストークンを直ちに回転させることが必須です。JFrogはこの脅威に対する研究を継続しています。 本記事の詳細は こちら からご確認ください ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 注意喚起:史上最大なNpmソフトウエアサプライチェーン攻撃:Shai-Hulud first appeared on SIOS Tech. Lab .
アバター
ここでは、連載形式で公開してきた「Git & GitLab入門」シリーズの記事へのリンクとともに、各回の概要を整理します。 Gitの基本とGitLab / GitHubについて バージョン管理の基盤となるGitの基本概念(リポジトリ、コミットなど)を解説し、そのツールであるGitと、プロジェクトをホストするGitLab/GitHubとの関係性を整理した入門連載の第1回です。 Git & GitLab 入門 (1) ~Git マスターへの道~「Git の基本と GitLab/GitHub」 Git操作入門 GitとVS Codeのインストールやユーザー設定といった環境構築から、ローカルリポジトリ上での変更・ステージング・コミットというバージョン管理の初歩的な操作手順を解説しています。 Git & GitLab 入門 (2) ~Git マスターへの道~「Git操作入門」 Git操作チーム利用コマンドや ロールバック チーム開発で必要となる履歴表示(git log)や差分確認(git diff)、タグ付け(git tag)、バージョン管理対象外の設定(.gitignore)といった操作と、状況に応じて使い分ける必要があるコミットを取り消すコマンド(git revert、git reset、git restore)について解説しています。 Git & GitLab 入門 (3) ~Git マスターへの道~「Git操作チーム利用コマンドや ロールバック」 リモートリポジトリとローカルリポジトリ リモートリポジトリの役割を解説し、SSHキーの登録、プロジェクトの作成、クローン、そしてローカルの変更をリモートへ反映させるadd/commit/pushといったリモートリポジトリとローカルリポジトリの連携操作を解説しています。 Git & GitLab 入門 (4) ~Git マスターへの道~「リモートリポジトリとローカルリポジトリ」 Git のブランチについて Gitのブランチの基本概念と、Git FlowやGitHub Flowなどの主要なブランチ戦略を解説し、チーム開発におけるマージリクエスト(プルリクエスト)の作成からコンフリクトの発生と手動による解消手順までを解説しています。 Git & GitLab 入門 (5) ~Git マスターへの道~「Git のブランチについて」 GitLabの画面説明とよく利用される機能説明 GitLabが提供する「プロジェクト」、CI/CD、セキュリティ機能、Issue管理やマージリクエストといったDevSecOpsライフサイクル全体をカバーする統合プラットフォームとしての主要な機能を、外部ツールとの連携を重視するGitHubとの違いを交えながら解説しています。 Git & GitLab 入門 (6) ~Git マスターへの道~「GitLabの画面説明とよく利用される機能説明」 GitLabのプロジェクトについて GitLabにおけるグループとプロジェクトの関係や、リポジトリとの違いを解説しています。また、マージリクエストやCI/CDを含むプロジェクトの統合的な機能を説明し、ユーザー招待や保護ブランチ、Wikiの設定といった開発を始めるための具体的な初期準備手順を解説しています。 Git & GitLab 入門 (7) ~Git マスターへの道~「GitLabのプロジェクトについて」 GitLabのCICD設定 継続的インテグレーション・継続的デリバリー(CI/CD)の概要を解説し、Kubernetes上にGitLab Runnerをセットアップして連携させた上で、.gitlab-ci.ymlを用いてコンテナイメージのビルド、プッシュ、デプロイメントまでを一貫して自動化するパイプラインの構築手順を解説しています。 Git & GitLab 入門 (8) ~Git マスターへの道~「GitLabのCICD設定」 コードレビューの進め方 GitLabのマージリクエスト(MR)をコードレビューの場として活用する方法を解説しており、レビュアーとレビューイ双方の視点から、レビューを円滑に進めるための具体的な手順(MR設定、コメント、承認、提案の適用)を解説しています。 Git & GitLab 入門 (9) ~Git マスターへの道~「コードレビューの進め方」 GitLabでDevSecOps 開発スピードと安全性を両立する「DevSecOps」の概念と、GitLabがCI/CDパイプラインへのセキュリティスキャン統合を通じてこれを実現し、Hilti社やCarfax社などの具体的な企業事例における開発効率化やセキュリティ向上といった導入成果を解説しています。 Git & GitLab 入門 (10) ~Git マスターへの道~「GitLabでDevSecOps」 この連載を通じて、Git/GitLabを利用した個人・チーム開発のプロセスを体系的に理解することができます。Gitの基本操作はもちろん、CI/CDやDevSecOps機能を組み込んだGitLabの基礎を学ぶことができます。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Git & GitLab 入門 ~Git マスターへの道~「まとめ」 first appeared on SIOS Tech. Lab .
アバター
はじめに 昨今、生成AIが流行っているのは言うまでもありません。ChatGPTから始まり、そしてRAG(Retrieval Augmented Generation)と呼ばれる技術が注目され、さらにAIエージェントなんていうのも出てきています。そして、今、最も熱いのはMCP(Model Context Protocol)でしょう。 今回は、そんなMCPのテクノロジーとMoodle(オープンソースの学習管理システム)を組み合わせたMCPサーバーを作成しましたので、その紹介をしたいと思います。以下のGitリポジトリにてソースコードを公開しています。 https://github.com/ntakei-sti/moodle-mcp-server このMCPサーバーは、勉学に励む学生を優しく支えるAIツールです。 ざっくりいってしまうと、例えば下図のようにチャット形式のアプリにこのMCPサーバーを組み込むことで、学生がチャット形式で質問した内容に応じて、Moodleの情報を取得して、回答することができます。 例えば、このチャットみたいに、ちょっと弱気な発言をすると、過去の成績を鑑みて、オススメの教材を提案して励ましてくれたり、締切間近の宿題を忘れないように教えてくれたりします。 MCPサーバーとは? MCPとは、Model Context Protocolの略で、今流行りのAIエージェントに簡単に機能を追加するためのプロトコルです。 AIエージェントに関する詳しい説明は以下の記事を参考にしてください。 https://tech-lab.sios.jp/archives/42867 そして、このMCPというプロコトルに準拠して作成されたサーバーがMCPサーバーです。 では、このMCPサーバーの機能を理解するために、「MCPがない世界」と「MCPがある世界」を比較してみましょう。 MCPがない世界 MCPがない世界では、他のAIエージェントAでとても役立つ機能を使っていたとして、それをいざAIエージェントBで使おうとした場合、AIエージェントB向けにその機能を実装し直す必要があります。 というのは、今まではLLMアプリ(DifyやClaudeなど)はそれぞれ独自の実装方式を持っており、またAIエージェントが使うツールもそれぞれ独自の実装方式をもっており、それぞれの実装方式に合わせて、ツールの方を改修する必要がありました。 例えばAIエージェントAではクラウドストレージにアクセスして、ファイルの一覧や中身を取得する機能があったとしても、AIエージェントBではそのクラウドストレージにアクセスする方法が異なっている場合、AIエージェントB向けにクラウドストレージにアクセスする機能を実装し直す必要があります。 MCPがある世界 MCPがある世界では、AIエージェントAで実装した機能をそのままAIエージェントBでも利用することができます。なぜなら、MCPに準拠したインターフェースを通じて、異なるAIエージェント間で機能を共有できるからです。 ここでは、「MCPサーバーがない世界」で「ツール」と言われていたものは「MCPサーバー」と呼ばれるようになりました。当然「サーバー」と呼ばれるくらいなので、それにラクセスするクライアントである「MCPクライアント」も必要になります。 MCPクライントとMCPサーバーを用意し、その間の通信をMCPに準拠したものにして、MCPサーバー側ではインターネットやクラウドストレージなど各種リソースにアクセスして、MCPクライアントに結果を返すようにします。 このようにして、MCPサーバーを用意することで、異なるAIエージェント間で機能を共有できるようになります。 今回の記事では、MCPの話が本筋ではないので、MCPに関する詳しい説明は割愛します。MCPに関する詳しい説明は以下のYouTubeを参考にしてください。 https://www.youtube.com/live/f7x6flxAfak?si=XDNt7xYWWpaZVHkP Moodleとは? Moodle(ムードル)は、学校や企業の学習をオンラインで運営するための「学習管理システム(LMS)」です。オープンソースで無償利用でき、ブラウザさえあれば受講から課題提出、採点、成績管理まで一通り行えます。 主な登場人物は管理者・教師・学習者の3つになります。 管理者はサイトやユーザーを統括したり、Moodleの基本的な設定(権限管理やメールサーバーなどの設定)を行います。 教師はコース(科目)を作って教材やテストを配置し、学生への各種伝達、課題の提出管理や採点を行います。 学習者は学生のことで、教師からの指示に基づいて、課題などの受講・提出・確認を行います。 ざっくりこんな流れ このMCPサーバーの処理の流れをざっくり説明します。 ① 認証 ユーザーがIdPで認証します。このIdPはKeyCloakやOktaなどのOpenID Connectに対応したものの利用を想定しています。 ② 質問 LLMアプリ(DifyやClaudeなど)で質問します。このとき①で取得したIDトークンをHTTPヘッダー Authorization にセットして、LLMアプリに渡します。 ③ ツール取得 MCPのプロトコルに則り、MCPクライアントからMCPサーバーに対して、利用可能なツールの一覧を取得します。 ④ ツール選定 ③で取得したツール一覧をAzure OpenAI ServiceなどのLLMに渡し、質問に対して適切なツールを選定します。 ⑤ ツール返却 LLMから返却されたツールをLLMアプリが受け取ります。 ⑥ ツール呼び出し LLMアプリがMCPクライアントを通じて、MCPサーバーに対してツールを呼び出します。このとき、②で取得したIDトークンをもとに、MCPサーバーに対して、ユーザー情報を渡します。 ⑦ API実行 MCPサーバーはユーザー情報やコース情報などをもとに、MoodleのREST APIを呼び出して、必要な情報を取得します。 MCPサーバーの基本機能 今回作成したMCPサーバーは、MoodleのREST APIを利用して、Moodleの情報を取得する機能を持っております。具体的には以下の機能を提供しています。 ■  成績が低い課題のコースに関するファイル一覧を取得 ユーザーの履修コースのうち、成績の回答率が 一定値を下回るコースに添付されたファイルを列挙します。 ■ 未提出の課題の取得 ユーザーの未提出と判定される課題を検索して返します。 ■ ユーザーが履修しているコース一覧の取得 ユーザーが履修しているコースの一覧を取得します。 ■ コース検索 全コースからキーワード検索を行います。表示名(displayname)や概要(summary)も出力に含めます。 ■ 締め切り間近の課題取得 ユーザーの未提出と判定される課題のうち、締め切りが近いものを検索して返します。 MCPサーバーの詳細機能 MCPサーバーのより詳細な機能について説明します。 get_resources_under_specific_grade ユーザーの履修コースのうち、成績の回答率が環境変数 COMPLETION_THRESHOLD を下回るコースに添付されたファイルを列挙します。 ユーザー名は REMOTE_USER 環境変数、または X-Remote-User ヘッダー、あるいは ID トークンで指定します。 get_my_unsubmitted_assignments ユーザーの未提出と判定される課題を検索して返します。課題の提出判定には 環境変数 mod_assign_get_submission_status を優先利用し、 ユーザー名は REMOTE_USER 環境変数、または X-Remote-User ヘッダー、あるいは ID トークンで指定します。 get_my_enrolled_courses ユーザーが履修しているコース一覧を返します。 ユーザー名は REMOTE_USER 環境変数、または X-Remote-User ヘッダー、あるいは ID トークンで指定します。 find_my_courses_by_keyword(keyword) core_course_search_courses を利用して全コースからキーワード検索を行います。表示名(displayname)や概要(summary)も出力に含めます。 get_upcoming_deadlines 環境変数 UPCOMING_DEADLINES_DAYS 日以内に締切が来る課題を集約して返します。 mod_assign_get_assignments を優先して使い、 フォールバックで gradereport から締切を探します。 ユーザー名は REMOTE_USER 環境変数、または X-Remote-User ヘッダー、あるいは ID トークンで指定します。 システム構成 このMCPサーバーで構成することの出来るシステム構成の例をいくつか紹介します。 信頼できるネットワーク内にMCPクライントとMCPサーバーがある場合 この場合、MCPクライアントとMCPサーバーは同じ信頼できるネットワーク内にあるため、つまり、このMCPサーバーにアクセスできるのは、LLMアプリのみのため、HTTPヘッダー X-Remote-User を使ってユーザー名を渡すことができます。 後述するIDトークンを使う場合と比べて、LLMアプリの実装が簡単になります。 信頼できるネットワーク外にMCPクライントとMCPサーバーがある場合 この場合、MCPクライアントとMCPサーバーは同じ信頼できるネットワーク内にはないため、つまり、このMCPサーバーにアクセスできるのは、不特定多数のユーザーが利用する可能性があるため、HTTPヘッダー X-Remote-User を使ってユーザー名を渡すことはできません。 この場合、IDトークンを使ってユーザー名を渡す必要があります。MCPサーバーはIDトークンを検証し、ユーザー名を取得します。 MCPクライアントとMCPサーバーが同じアプリケーションサーバー上にある場合 この場合、MCPクライアントとMCPサーバーは同じアプリケーションサーバー上にあるため、通信方式としてSTDIOを用います。環境変数 REMOTE_USER を使ってユーザー名を渡すことができます。 起動方法 このMCPサーバーはPythonで作成されており、 pip コマンドでインストールして利用します。 事前準備 以下のコマンドを実行して、必要なライブラリをインストールしてください。 $ git clone https://hogehoge.git $ cd moodle-mcp-server $ ppip install -r requirements.txt 環境変数の設定 このプロジェクトは環境変数で各種挙動を制御します。 .env  ファイルを作成するか、シェルの環境変数として設定してください。通信方式(MCP_TRANSPORT)により必要な環境変数が異なります。 共通 MOODLE_API_URL (必須): Moodle サイトのベース URL(例: < https://moodle.example.com >) MOODLE_WSTOKEN (必須): Moodle の Webservice トークン COMPLETION_THRESHOLD (任意): 成績の「回答率」閾値(デフォルト 80) UPCOMING_DEADLINES_DAYS (任意): get_upcoming_deadlines が参照する日数ウィンドウ(デフォルト 7) MCP_TRANSPORT (任意): 通信方式。 sse (既定)または stdio SSE モード(MCP_TRANSPORT=sse)もしくはStreamable HTTPモード(MCP_TRANSPORT=streamable-http)で主に使用する変数 MCP_SERVER_HOST (任意): サーバのバインドアドレス(デフォルト 0.0.0.0 ) MCP_SERVER_PORT (任意): サーバのポート(デフォルト 8000 ) ACCEPT_REMOTE_USER_HEADERS (任意): true で X-Remote-User ヘッダを優先(デフォルト true ) Bearer トークン検証を使う場合に必要: OIDC_METADATA_URL : OpenID Provider のメタデータ URL(必須) OIDC_AUDIENCE (任意): 期待する audience OIDC_USERNAME_CLAIM (任意): ユーザー識別子に使うクレーム名(デフォルト sub ) STDIO モード(MCP_TRANSPORT=stdio)で使用する変数 REMOTE_USER (必須): 実行中プロセスで扱う Moodle の username 注意: ACCEPT_REMOTE_USER_HEADERS を有効にする場合、 リモートヘッダは信頼できるプロキシからのみ渡す  ようにしてください。 例: `.env` ファイルテンプレート(SSEもしくはStreamable HTTP) MOODLE_API_URL=https://moodle.example.com MOODLE_WSTOKEN=your_moodle_ws_token COMPLETION_THRESHOLD=80 OIDC_METADATA_URL=https://idp.example.com/.well-known/openid-configuration OIDC_AUDIENCE=your-client-id OIDC_USERNAME_CLAIM=preferred_username ACCEPT_REMOTE_USER_HEADERS=true UPCOMING_DEADLINES_DAYS=7 MCP_TRANSPORT=sse MCP_SERVER_HOST=0.0.0.0 MCP_SERVER_PORT=8000 例: `.env` ファイルテンプレート(STDIO) MOODLE_API_URL=https://moodle.example.com MOODLE_WSTOKEN=your_moodle_ws_token REMOTE_USER=your-username MCP_TRANSPORT=stdio 起動 以下のコマンドを実行して、MCPサーバーを起動します。 $ python moodle_mcpserver.py 動作確認 MCP Inspectorというツールを使うと簡単に動作確認ができます。MCP InspectorはMCPサーバーに対して、MCPのプロトコルに則った通信を行うことができるツールです。動作するためにはNode.jsの環境が必要です。 以下のコマンドでMCP Inspectorを起動します。 $ npx @modelcontextprotocol/inspector STDIOで動作確認する場合 まず基本的な設定を行います。 ① Transportで `stdio` を選択します。 ② Commandに `python ` を選択します。 ③ Commandにmoodle_mcp_server.pyのパスを入力します。 ④ `MOODLE_API_URL` 、 `MOODLE_WSTOKEN` 、 `REMOTE_USER` の環境変数を設定します。 MCPサーバーに接続します。 `Connect` ボタンを押します。   ツールの一覧を取得して実行します。 `Tools` タブを選択し(①)、 `List Tools` ボタンを押します(②)。ツールの一覧が取得されます(③)。ツールを選んで、 `Run Tool` ボタンを押すと、ツールが実行されます(④)。   ツールの実行に成功すると、以下のように結果が表示されます。 Stremable HTTPもしくはSSEで動作確認する場合 まず基本的な設定を行います。 ① Transport Typeは、 `Streamable HTTP` もしくは `sse` を選択します。 ② Transport Typeが `Streamable HTTP` の場合、 `http://[MCPサーバーのホスト名]/mcp` を入力します。Transport Typeが `sse` の場合、 `http://[MCPサーバーのホスト名]/sse` を入力します。 ③ HTTPヘッダを追加します。 `ACCEPT_REMOTE_USER_HEADERS` を `true` に設定している場合、 `X-Remote-User` ヘッダーを追加します。IDトークンを使う場合、 `Authorization` ヘッダーを追加します。両方とも値はMoodleのユーザー名です。 ⑤ `Connect` ボタンを押します。 後の手順は、STDIOで動作確認する場合と同様です。 より実践的なシステムを構築 簡単な動作確認が出来たところで、このMCPサーバーを動かすための、より実践的なシステムを構築してみましょう。以下の図がそのシステム構成です。 LLM アプリとして Dify を利用します。Dify は MCP に対応しているため、MCP クライアントとして動作します。 Dify 自体には認証機能がないため、別途チャット UI を提供するアプリケーションサーバーを用意します。ここでは Streamlit を利用します。Streamlit は OpenID Connect に対応しているため、KeyCloak でユーザーを認証した後に ID トークンを取得できます。 ユーザーが認証を終えると、取得した ID トークンが Streamlit に渡され、Streamlit 側でトークンの検証を行い、Moodle のユーザー名を取得します。そのうえで Streamlit から Dify に対して API を呼び出します。Dify は公開 API を提供しており、そこに質問を送ることで回答を得ることができます。この際、ID トークンから取得したユーザー名を API のパラメーターとして渡すことで、Dify がユーザー名を認識できるようにします。 Dify は MCP クライアントとして、MCP サーバーに対して Moodle の情報を取得するためのツール一覧の取得やツール実行を行います。ここから先は MCP のプロトコルに従って通信が進みます。 では構築手順を説明していきます。 KeyCloakの設定 クライアントを作成するために、KeyCloakの管理コンソールにログインし、 `Clients` メニューから、 `Create client` ボタンを押します。   `Client ID` に任意の名称を入力し、 `Next` ボタンを押します。   `Client authentication` を `ON` (①)、 `Authorization` を `OFF` (②)にしてクライアントシークレットによる認証を有効にします。認可コードフローに対応するために、 `Standrd flow` にチェックを入れます(③)。最後に `Next` ボタンを押します(④)。   Valid redirect URIsに `http[s]://[Streamlitのホスト名]/oauth2callback` を入力し(①)、 `Save` ボタンを押します(②)。   クライアントシークレットを確認するために、 `Credentials` タブを選択します(①)。 `Secret` の値を控えておきます(②)。後でStreamlitの設定で利用します。 Streamlitの設定 Streamlitでは、KeyCloakなどのOpenID Connectに対応したIdPを利用して、ユーザー認証を行い、DifyのAPIを呼び出す必要があります。このアプリケーションは、以下のGitHubリポジトリで公開していますので、Cloneして利用してください。 https://github.com/ntakei-sti/streamlit4dify Cloneしたら、まず、 `.env` を以下のように設定します。 `DIFY_API_URL` はDifyのAPIエンドポイントを指定します。 `DIFY_API_KEY` はDifyのAPIキーを指定します。 `OIDC_USERNAME_CLAIM` はKeyCloakのユーザー名に対応するクレーム名を指定します。KeyCloakのデフォルトでは `preferred_username` ですが、環境によって異なる場合がありますので、適宜変更してください。 DIFY_API_URL=http[s]://<Difyのホスト名>/v1/chat-messages DIFY_API_KEY=<DifyのAPIキー> OIDC_USERNAME_CLAIM=<KeyCloakのユーザー名に対応するクレーム名>   次に、 `secrets.toml` を以下のように設定します。 `redirect_uri` はKeyCloakのクライアント設定で指定した `Valid redirect URIs` を指定します。 `cookie_secret` は任意の文字列を指定します。 `client_id` はKeyCloakのクライアントIDを指定します。 `client_secret` はKeyCloakのクライアントシークレットを指定します。 `server_metadata_url` はKeyCloakのメタデータURLを指定します。 [auth] redirect_uri = "http[s]://<Streamlitのホスト名>/oauth2callback" cookie_secret = "<任意の文字列>" client_id = "<KeyCloakのクライアントID>" client_secret = "<KeyCloakのクライアントシークレット>" server_metadata_url = "http[s]://<KeyCloakのホスト名>/realms/<レルム名>/.well-known/openid-configuration"   Streamlitアプリケーションを起動します。 $ streamlit run app.py Dify設定 まず、DifyのマーケットプレイスからMCPプラグインをインストールします。Difyの管理コンソールにログインし、 `Plugins` メニューから、 `Agent Strategies` のプラグインをインストールします。   そして、ワークフロー内でMCPプラグインを利用するように設定します。 `Agent` というブロックが追加出来るようになっているので、これをワークフローに追加します。   `Agentic Strategy` は `Function Calling (Support MCP Tools)` を選択します(①)。 `MCP SERVERS CONFIG` は、以下のように設定します(②)。 {   "server_name1": {   "transport": "sse", "headers": { "X-Remote-User": 🏡Start/{x}sys.user_id }, "url": "http[s]://<MCPサーバーのホスト名>/sse" } }   `INSTRUCTIONS` は以下のように設定します(③)。このシステムメッセージを定義することにより、ユーザーの弱気な発言を拾って、Moodleの情報を取得して、優しく励ますことができます。 あなたはmoodleからいろんな情報を取得する賢いエージェントです。 ユーザーが、「成績が出なくて困った」などの類の弱気な趣旨の質問をした場合には、ツールget_resources_under_specific_gradeを呼んでください。その回答は、成績が思わしく無いコースの資料ですので、それらの資料を優しく提案してあげてください。 MCPサーバーの設定 MCPサーバーを起動します。起動するための環境変数の説明は説明済みですので割愛します。今回の構成では、通信方式をSSE、MCPサーバーはDifyからのみアクセスされることを前提として、 `ACCEPT_REMOTE_USER_HEADERS` を `true` に設定します。以下は `.env` ファイルの例です。 MOODLE_API_URL=<MoodleのURL> MOODLE_WSTOKEN=<MoodleのWebサービスのトークン> COMPLETION_THRESHOLD=80 MCP_TRANSPORT=sse ACCEPT_REMOTE_USER_HEADERS=true MCPサーバーを起動します。 $ python moodle_mcp_server.py 動作確認 Streamlitのアプリケーションにアクセスします。KeyCloakのログイン画面が表示されるので、ユーザー名とパスワードを入力してログインします。   KeyCloakのログイン画面が表示されるので、ユーザー名とパスワードを入力してログインします。   ログインに成功すると、チャット画面が表示されます。チャット画面で質問を入力して、 `Send` ボタンを押します。 まとめ いかがでしたでしょうか?勉学に励む学生を優しく包むAIって素敵ですね。ときに厳しく、そして特に優しく、学生を支えるMoodle対応のMCPサーバーをぜひご活用ください。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 生成AIの学術利用を加速する!!勉学に励む学生を優しくサポートするMoodle対応のMCPサーバーを作りました!! first appeared on SIOS Tech. Lab .
アバター