OmniAICreator/Qiita-1.07M huggingface dataset:
【AWS構築】IAMのスイッチロールをハンズオンする

# 目的
AWSのIAM周りを理解する。
特に、「スイッチロール」


## スイッチロール
重要度⭐⭐⭐⭐⭐⭐

:::note
スイッチロールとは
AWSのIAMユーザーがAWSアカウント内のIAMロールに切り替えて、一時的にそのロールの権限を受け継ぐ。
アカウントを跨いだスイッチロール等も可能
:::

⭐スイッチロールを実際の設定を交えて、理解していく。

### ①：IAMユーザー作成
スイッチロールの起点（切り替え元）となるIAMユーザーを作成する。

AWSコンソールで「IAM」と検索し、「ユーザー」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801383/811f7f9e-b681-4140-987f-5b8a58514786.png)

「ユーザーの作成」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801383/ac2064cb-926d-44ee-bdb9-c6b71e6d89ca.png)

ユーザー名を任意で入力して作成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801383/0d3880cb-9d62-4e9d-8558-145d5d258a04.png)



## ②：IAMロール作成
スイッチロール先となるIAMロールを作成する。
本来はIAMロールで何を許可するか・どのサービスを許可するかなどを定義しますが、今回は割愛します。

適当なロールを作成しました。
ポリシーはAdmin権限を付与してます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801383/57cdc8fb-ed48-4e26-8ecd-0c7ade5ab750.png)

## ③：ロールの信頼関係の設定
重要度⭐⭐⭐⭐⭐

:::note
ロールの信頼関係とは？
どのエンティティがロールへのスイッチを可能とするかを定義するルール
:::

「信頼関係」タブの中で確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801383/d4183821-50f7-47d3-b9d7-b410fe350810.png)

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "ec2.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```

ほとんどバケットポリシーと同じ形式です。
Allowで明示的に許可してPrincipalでサービス・ARN等を指定。
"Action": "sts:AssumeRole"　は、IAMロールを引き受ける（スイッチする）ための操作を許可するものです。（ヘルメットをかぶるためのおまじないみたいもの）

今回は先ほど作ったユーザにのみ、このロールを引き受ける権利を与えたいのでIAMユーザーのプリンシパルを指定します

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "<ARN>"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

ARNはコンソール上で確認＆コピペ可能
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801383/108cb0ae-0847-47c5-b126-c3a48ce897ca.png)


## ④：スイッチロール実行
先ほど作成したユーザーで、AWSコンソール画面にログインします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801383/3093b763-2abe-4731-bb9f-444c9b9ce9df.png)

IAM画面を開くと、このユーザーには権限持たせてないため、IAMの情報などは取得できないことが分かります。

では右上のユーザ設定から『ロールの切り替え』を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801383/7c884521-ed88-46f6-905e-cc7576f90196.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801383/74096e73-b69e-4cdf-94b6-9c57bfcc4583.png)
・アカウントID:スイッチ先のIAMロールが存在するアカウントID
・IAMロール：ロール名

を入力してスイッチします。

成功するとコンソール画面に戻るので右上のユーザー画面を確認すると
・スイッチしたロールとして、ログインできているのが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801383/a9f6654b-cd6a-43ef-aea5-d8785f5a1195.png)

さらに、IAM関連の情報も確認できていることが分かります。


## ⑤：細かいスイッチロール設定

### セッション期間
スイッチロール後のセッションを保持する時間を変更できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801383/136ba9ab-04d6-48a8-be53-9accfaa8940b.png)

###
DockerでJenkinsを構築する備忘録


```
# Docker imageをpull
docker pull jenkins/jenkins:lts-jdk21

# 起動
docker run -p 8080:8080 -p 50000:50000 --restart=on-failure jenkins/jenkins:lts-jdk21
```
起動すると以下メッセージ
```
*************************************************************
*************************************************************
*************************************************************

Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:

※※※※ ここにパスワード ※※※※
4de94f5a2312450db31e4ffc4426287a

This may also be found at: /var/jenkins_home/secrets/initialAdminPassword

*************************************************************
*************************************************************
*************************************************************
```

起動後以下にアクセス
```
http://localhost:8080/
```
アクセスすると以下の画面が表示される
ここに先ほどメモしたパスワードを入力して[continue]を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3692471/cf9b1828-784c-4086-99cf-3398a00ef935.png)

押下後以下の画面
![スクリーンショット 2025-04-11 9.36.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3692471/a0f097b1-7cf8-4ad5-9793-b36b75055695.png)

左を選択(右を選ぶとプラグインを選択できる)
![スクリーンショット 2025-04-11 9.38.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3692471/c6f1d0e7-81f0-40f3-ba25-af57173f900b.png)

インストール後自動的に以下の画面へ遷移
![スクリーンショット 2025-04-11 9.40.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3692471/c1579b72-266c-49ca-a38d-f0bb3c92df57.png)

入力後、Save and continueを押下すると以下画面へ
![スクリーンショット 2025-04-11 9.42.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3692471/339c28b2-4146-45b5-a5f5-9e7d05f5c17b.png)

以上
![スクリーンショット 2025-04-11 9.43.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3692471/6813e6c1-d6bb-4c3c-995c-4320ed309f9f.png)
【統計検定3級】グラフの種類

# グラフの種類
## 棒グラフ
値の大小を比較する際に用いる

## 折れ線グラフ
値の時間的・空間的変化を表す際に用いる

## 円グラフ
カテゴリ全体に対する割合を表す際に用いる

## 帯グラフ
カテゴリ全体に対する割合を表す際に用いる
複数のグループの比較や年次的な推移を調べる際に用いる

## 幹葉図（みきはず）
幹（カテゴリ）と葉（具体的な値）を図化したもの。

### 例：身長の分布

| カテゴリ | 値 |
| -- | -- |
| 140 | 141, 147 |
| 150 | 153, 153, 157, 159 |
| 160 | 160, 162, 165, 165, 167, 168 |
| 170 | 170, 173, 177 |
| 180~ | 183, 187|

縦横を逆転させるとヒストグラムのようになる

## レーダーチャート
複数の値をまとめて表す際に用いる
例：5教科の成績表
自分の成績と平均点を1つのチャートにまとめて表示できる

## 複数グラフの組み合わせ
複数のグラフを組み合わせることで、関連性のある項目を1つのグラフで表現することができる
例：雨温図 - 月次の平均気温（棒グラフ）と降水量（折れ線グラフ）を組み合わせる

## 積み上げ棒グラフ
値の大きさと割合を同時に表現できる
複数並べることで時間的変化を表現することができる

# 誤解を招きやすいグラフ表現
4000～5000の値を取るデータで、4000～5000のメモリで棒グラフを表示する。
差異は大きく見えるが、実際には0～5000の数値内では20%の誤差に収まるなど。
excalidraw+excalidraw-room構築

# excalidrawを自前サーバーでリアルタイム共有込で走らせたかった
……でも何かどこにも情報無かったので……(探し方が悪い？)
※ 本記事に記載のIPアドレス・ドメイン名はすべて架空の例です。
実際の環境に合わせて適宜置き換えてください。

# 前提
docker
docker compose
git
Apache(SSL済)←リバプロ用

# ディレクトリ構成
/work (以下でのroot)
/work/docker-compose.yml
/work/excalidraw(git cloneの結果)

# とりあえずgitから本体取得

```
/work$ git clone https://github.com/excalidraw/excalidraw.git
```
# /excalidraw/Dockerfileに追記(いらないかも)
他のARG追加してる辺りに

```
ARG VITE_APP_WS_SERVER_URL
ENV VITE_APP_WS_SERVER_URL=$VITE_APP_WS_SERVER_URL
```


# /docker-compose.yml 作る
```
version: "3.8"
services:
  excalidraw:
    container_name: excalidraw-web
    build:
      context: ./excalidraw
      dockerfile: Dockerfile
      args:
        VITE_APP_WS_SERVER_URL: wss://hogefuga.com //←大事
    ports:
      - "9247:80"
    restart: unless-stopped
  excalidraw-room:
    container_name: excalidraw-room
    image: excalidraw/excalidraw-room:latest
    ports:
      - "9248:80"
    restart: unless-stopped
```

# buildする
```
/work$ docker compose build --no-cache
```

# 上げる
```
/work$ docker compose up -d
```

# Apacheでリバプロ

```
<VirtualHost *:443>
    ServerName hogefuga.com

    SSLEngine on
    SSLCertificateFile /path/to/key/fullchain.pem
    SSLCertificateKeyFile /path/to/key/privkey.pem
    
    # WebSocket routing (socket.io)
    RewriteEngine On
    RewriteCond %{HTTP:Upgrade} =websocket [NC]
    RewriteRule ^/socket.io/(.*) ws://xxx.xxx.xxx.xxx:9248/socket.io/$1 [P,L]
    RewriteCond %{HTTP:Upgrade} !=websocket [NC]
    RewriteRule ^/socket.io/(.*) http://xxx.xxx.xxx.xxx:9248/socket.io/$1 [P,L]

    ProxyPassReverse /socket.io/ http://xxx.xxx.xxx.xxx:9248/socket.io/

    # App itself
    ProxyPass / http://xxx.xxx.xxx.xxx:9247/
    ProxyPassReverse / http://xxx.xxx.xxx.xxx:9247/

    Header always set X-Frame-Options "SAMEORIGIN"
</VirtualHost>
```

# やったー！
稼働確認動いたやったー！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669756/d642a8a5-eaba-4562-8eae-70ebc179823e.png)
【BigQuery】縦持ちデータを横持ちデータに変換するPIVOT演算子

みなさん、こんにちは！
Accessのクロス集計表をBigQueryで実現する要件があり、どうやって実現するか困っていたところ、BigQueryにはPIVOT演算子があることが分かり、無事解決できたのでご紹介します。

PIVOT項目を静的に指定する方法と、動的に指定する方法の２通りについて記述しています。

## 縦持ちの「店別売上データ」から、"静的"に横持ちの「店別売上データ_PIVOT」に変換　
店CD、店名毎に、期をPIVOT項目として売上げを集計する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956386/2b6ec58f-2d84-4b0c-b658-8866761074db.png)

## PIVOT演算子の文法
```ruby:qiita.rb
FROM
[テーブル or サブクエリ]
PIVOT(
[集約関数] [, ...]
FOR [入力項目]
IN ([PIVOT項目] [, ...])
)
```
[テーブル or サブクエリ]：PIVOT前のテーブル名、または、サブクエリを記載
[集約関数]：SUMやCOUNT等の集約関数を記載
[入力項目]：列を作る際の元となる項目を記載
[PIVOT項目]：列として出力する項目を記載

## SQL
実際にSQLを作成し実行してみます。
今回は総計も出力したいので、サブクエリを使用しました。

```ruby:qiita.rb
CREATE OR REPLACE TABLE `店別売上データ_PIVOT` AS
SELECT
*
FROM
(
SELECT
`店CD`,
`店名`,
SUM(`売上`)OVER(PARTITION BY `店CD`,`店名`) AS `総計`,
`期`,
`売上`
FROM `店別売上データ`
)

PIVOT(
SUM(`売上`) FOR `期` IN (
'Q1','Q2','Q3','Q4'
　)
)
ORDER BY `店CD`
;
```

## 実行結果
想定通りの結果が得られました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956386/41373041-db50-4698-9552-fd7cfb61a260.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956386/59d92597-95b7-494b-a49e-a4c4f66354bc.png)

## 縦持ちの「店別売上データ」から、"動的"に横持ちの「店別売上データ_PIVOT」に変換　
先ほどの例はPIVOT項目が期だったので、Q1からQ4と静的に指定を行えましたが、日付等の可変の項目をPIVOT項目とし、PIVOT変換する方法をご紹介します。
PIVOT項目を可変とするため、データから日付情報を取得し、「EXECUTE IMMEDIATE FORMAT」を利用して実現します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956386/60396bba-2874-4f62-9d1d-680bf77d4b0f.png)

## SQL
実際にSQLを作成し実行してみます。
```ruby:qiita.rb
---配列定義
DECLARE daily_labels ARRAY<STRING>;

--日付を配列に設定
SET daily_labels = (
　SELECT ARRAY_AGG(i.`日付`)
　FROM (SELECT DISTINCT `日付` FROM `店別売上データ` ORDER BY 1) AS i
);

--配列をUNSET展開しながらIN句に設定する文字列を生成する
EXECUTE IMMEDIATE FORMAT("""
　CREATE OR REPLACE TABLE `店別売上データ_PIVOT` AS
　SELECT
　*
　FROM
　(
　SELECT
　`店CD`,
　`店名`,
　SUM(`売上`)OVER(PARTITION BY `店CD`,`店名`) AS `総計`,
　`日付`,
　`売上`
　FROM `店別売上データ`
　)
　PIVOT(
　SUM(`売上`) FOR `日付` IN %s) ORDER BY `店CD`;
""", (SELECT CONCAT("(",STRING_AGG(CONCAT("'",dailys,"'"),","),")") FROM UNNEST(daily_labels) AS dailys))
```

## 実行結果
想定通りの結果が得られました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956386/0873ce9c-664f-4821-9dc5-0bce4f4dd85c.png)

## まとめ
今回の要件は、動的に横持ちのテーブルに変換する必要があったため、「PIVOT演算子」と「EXECUTE IMMEDIATE FORMAT」を使用して、無事解決することが出来ました。

また、「PIVOT演算子」と逆で、横持ちを縦持ちに変換する「UNPIVOT演算子」というのもあるらしいので、試してみたいと思います。
社内セキュリティ都合でHyper-VのDefaultSwitch に接続したVMに接続できない仕様を回避する

CML2を利用したいが仮想基盤のリソースの利用はスタンプラリーをしなくてはいけない、許可が出るかわからない点を相談したらHyper-Vなら利用OKとのことで、Hyper-Vの有効化とインストールをしたらアクセスできなかったのでどうにかする話。


構成
・Windows 11(貸与PC)
・Hyper-V
・WSL2

社内セキュリティのためか、VPN経由社内のアドレスかローカルホストのアドレスしか接続できない仕様となっており、Hyper-VのDefaultSwitchに接続したVMは通常DHCPでアドレスを払い出されるが、IPの払い出しはされない状態。
固定IPアドレスを設定すれば、DefaultSwitch の内部から外にはアクセスできる。
WSL用のSwitchに接続しても同様。
Hyper-V SwitchManagerの外部接続を利用すると、ローカル（192.168.x.x/24 の自宅セグメント）のIPが割り当てられるが、Windows 11 からはアクセス不可。

WSL2でにはlocalhost:<ポート番号> でアクセス可能。

アクセスするためにはWSLg のfirefox からアクセスすれば、利用可能。→利用がめんどくさいのと、ローカル（自宅サーバ）にアクセスできる状態のため、利用したくない。
Hyper-V WSL間のフォワーディングについて：https://zenn.dev/gekal/articles/connect-wsl-and-hyperv-network-forwarding

そのため、WLS2でnginx をリバースプロキシ（パススルー）を実施することで、Windows 11のブラウザからアクセスできるようにした。


実施内容
nginxディレクトリ（docker のbind mount用）を作成し、その中にnginx.conf ファイルを作成。

```nginx/nginx.conf
user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}

stream {
    # HTTP (ポート80) passthrough
    server {
        listen 80;
        proxy_pass 172.19.68.183:80;
    }

    # HTTPS (ポート443) passthrough
    server {
        listen 443;
        proxy_pass 172.19.68.183:443;
    }

    # Cockpit (ポート9090) passthrough
     server {
        listen 9090;
        proxy_pass 172.19.68.183:9090;
    }   
}
```

docker でポートフォワーディング用のコンテナを作成する
```docker
sudo docker run -d -p 80:80 -p 443:443 -p 9090:9090 -v ./nginx:/etc/nginx nginx
```
EC-CUBE 4.0系でflex.symfony.comのDNSが解決できなかった

## 概要

EC-CUBE 4.0系のプロジェクトで `htmlpurifier-bundle` をインストールしようとしたところ、以下のエラーが発生しました。

```
[Composer\Downloader\TransportException]
The "https://flex.symfony.com/aliases.json" file could not be downloaded: php_network_getaddresses: getaddrinfo failed: nodename nor servname provided,
or not known
failed to open stream: php_network_getaddresses: getaddrinfo failed: nodename nor servname provided, or not known
```

## 原因

とりあえずググってみたところ、以下の Issue を発見。

🔗 https://github.com/symfony/flex/issues/909


## 解決法

Issueの通り、以下のコマンドを実行したら無事解決しました。

```bash
composer update symfony/flex --no-plugins --no-scripts
composer require exercise/htmlpurifier-bundle:^1.0
# → 成功！
```

感想
AIくんに聞いても「あなたのDNSの設定が間違えています。」としか言わなかった…。
やっぱり最終的にトラブルを解決できるのは、人間のエンジニアなんだなと実感しました。
Get Started with Einstein AI for Service Cloud



https://trailhead.salesforce.com/content/learn/projects/customer-service-replies-and-work-summaries/get-started-with-einstein-ai-for-service-cloud





# エラー

+ [We can’t find an email and case with the subject, ‘​​Order Status Water Bottle’.](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000Mabb10AB)
XIAO ESP32C6で(GROVE緑LED)Lチカして遊ぶ。


いろいろ、注意
----

- 過去ログを見て!!!


目的
----

外部のLEDをGROVEで点滅させる
GROVEの足を少し広げて半田付けする

結果
----

![image_original (82).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/06a36d15-bb98-44d9-b946-9be29b3dc84d.jpeg)


プログラム
----

```c++



/*
  Blink

  Turns an LED on for one second, then off for one second, repeatedly.

  Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO
  it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to
  the correct LED pin independent of which board is used.
  If you want to know what pin the on-board LED is connected to on your Arduino
  model, check the Technical Specs of your board at:
  https://www.arduino.cc/en/Main/Products

  modified 8 May 2014
  by Scott Fitzgerald
  modified 2 Sep 2016
  by Arturo Guadalupi
  modified 8 Sep 2016
  by Colby Newman

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/Blink
*/

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(D9, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(D9, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(D9, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}


```
雪だるま式開発ツール（SnowballDev）

RAGを活用した知識蓄積型のAI駆動開発ツールです。過去のプロジェクト情報や外部知識を取り込み、要件定義から実装までのソフトウェア開発工程を自動化します。

## 概要

このツールは、以下の主要コンポーネントで構成されています：

### RAGエンジン（ナレッジベース）
- Webリソースやコードリポジトリの自動クローリング
- 過去のプロジェクト情報の蓄積・検索
- 類似事例に基づく知識活用

### 要件定義生成器
- 自然言語の要求から構造化された要件を生成
- 過去のプロジェクトから類似要件を検索して活用
- 要件の変更履歴管理と比較機能

### 設計生成器
- 要件からシステムアーキテクチャの設計
- コンポーネント構成、データモデル、依存関係の分析
- シーケンス図などの視覚的設計資料の生成

### コード生成器
- プロジェクト構造とファイル構成の自動生成
- 主要コンポーネント、設定ファイルの実装
- 多言語対応（Python、JavaScript/TypeScript、Javaなど）

### テスト生成器
- ユニットテストと統合テストの自動生成
- コード分析に基づくテストケース設計
- テスト実行と検証機能

## インストール

必要なパッケージをインストールします：

```bash
pip install -r requirements.txt
```

## 使用方法

### ナレッジベース構築（クローリング）

```bash
python app.py crawl --urls https://example.com/docs --repos https://github.com/user/repo
```

### 新規プロジェクト生成

```bash
python app.py generate --name "タスク管理アプリ" --input "ユーザーがタスクを追加、編集、削除できるシンプルなWebアプリ" --type web_app --language javascript
```

### 既存プロジェクトの更新

```bash
python app.py update --name "タスク管理アプリ" --input "カテゴリ機能とタグ付け機能を追加したい"
```

## 仕組み

1. **知識ベースの構築**
   - WebページやGitリポジトリから知識を収集
   - チャンキングとベクトル化による意味検索の実現
   - フィードバックによる知識の質向上

2. **要件定義**
   - 自然言語入力から構造化要件への変換
   - 類似プロジェクトの要件を参考に最適化
   - 要件の更新と変更管理

3. **設計**
   - 要件に基づくアーキテクチャ選択
   - コンポーネント設計とデータモデル定義
   - シーケンス図等の設計図生成

4. **実装**
   - プロジェクト構造と基本コードの生成
   - 機能コンポーネントの実装
   - コード品質検証

5. **テスト**
   - コードに基づくテストケース設計
   - 単体テストと統合テストの生成
   - テスト実行と検証

## プロジェクト構成

```
snowball_dev/
├── coder.py            # メインアプリケーション
├── rag_engine.py       # RAGエンジン（ナレッジベース）
├── requirement_generator.py  # 要件定義生成器
├── design_generator.py      # 設計生成器
├── code_generator.py        # コード生成器（未実装）
├── test_generator.py        # テスト生成器（未実装）
└── requirements.txt         # 依存パッケージ
```

## 必要なパッケージ

- Python 3.8以上
- FAISS
- Sentence Transformers
- BeautifulSoup4
- html2text
- GitPython
- requests
- など

## 今後の開発予定

- コード生成器の完全実装
- テスト生成器の実装
- LLMとの連携強化
- フィードバックループの強化
- UIの提供

## ライセンス

MIT


https://github.com/chnmotoTmz/SnowballDev
Docker Desktopが使えない環境でRauncher Desktopを使ってtestcontainersをMS SQL Serverで試してみたメモ

# 概要
Windows Docker Desktopは個人では無料だが、ある程度の規模の組織だと有料になる。

この時の回避策としては下記のいずれかになる

- WSL2上にDocker CE をインストール [*][*1]
- Rauncher Desktop をインストール [*][*2]

Docker CEはtestcontainersから起動しようとすると`//./pipe/docker_engine`と表示されてうまく動かなかった。なので、`Rauncher Desktop`を使用することとする


# Rauncher Desktopの準備
## インストール
[chocolatey](https://community.chocolatey.org/packages/rancher-desktop)で配布しているのでそれで準備した。10Gb弱となかなか重い。

```
choco install rancher-desktop
```

インストールできたら起動しておく

## タイムアウト設定
SQLServerは結構重いので pull 時間を延ばしておく。 [*](https://java.testcontainers.org/features/configuration/)

```properties:~/.testcontainers.properties
pull.timeout=120
pull.pause.timeout=30
```

[configration](https://node.testcontainers.org/configuration/)

# コード

dbをfunctionsの外で定義している環境を想定。このとき、BeforeAllでコンテナを作っては間に合わない


```ts:test/setupDbContainer.ts
import fs from 'fs';
import { afterAll } from 'vitest';
import { StartedMSSQLServerContainer, MSSQLServerContainer } from '@testcontainers/mssqlserver';
import * as sql from 'mssql';

const mssqlContainer: StartedMSSQLServerContainer = await new MSSQLServerContainer('mcr.microsoft.com/mssql/server:2022-CU13-ubuntu-22.04').withWaitForMessage(/.*Attribute synchronization manager init*/).acceptLicense().withEnvironment({ACCEPT_EULA: 'Y', MSSQL_SA_PASSWORD: 'hoge', MSSQL_PID: 'Developer',MSSQL_COLLATION:'Japanese_CI_AS'}).start();

const connectionString = mssqlContainer.getConnectionUri();
process.env.SQL_CONNECTION_STRING = connectionString;

await sql.connect(connectionString);
await sql.query(fs.readFileSync('./migration.sql','utf8'));

afterAll(async () => {
  await mssqlContainer.stop();
});

```

```ts:vitest.workspace.ts
import { defineWorkspace } from 'vitest/config'
export default defineWorkspace([
 {
  test:{
    env: {TZ:'UTC', SQL_CONNECTION_STRING: ''},
    name: 'integration-test',
    include: ['**/*.db.test.ts'],
    setupFiles: ['test/setupDbContainer.ts'],
    deps: { interopDefault: true },
    environment: 'node',
    // コンテナの起動を含めるためタイムアウトを延長
    hookTimeout: 60000,
    testTimeout: 60000,
    poolOptions: {forks: {singleFork:true}}
}
]);
```
# 実行
[rauncher desktop用の設定](https://node.testcontainers.org/supported-container-runtimes/)を入れて起動する必要がある
`cross-env DOCKER_HOST=unix://${HOME}/.rd/docker.sock TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE=/var/run/docker.sock DEBUG=testcontainers* vitest`


# 参考

[使い捨てテストDB環境のtestcontainersをPostgresql + Honoで試してみたメモ](https://qiita.com/hibohiboo/items/296ec57c19daed007a5b)
[Windowsにゼロから WSL2 + Docker CE + React環境を構築する全手順]
[Rauncher Desktop](https://rancherdesktop.io/)
[Rancher Desktopの使い方｜Docker Desktopとの違いや移行手順を解説][*2]
[sqlserver docker](https://hub.docker.com/r/microsoft/mssql-server)
[sqlserver env](https://learn.microsoft.com/ja-jp/sql/linux/sql-server-linux-configure-environment-variables?view=sql-server-ver16)

[*1]:https://qiita.com/yamazombie/items/4071dfb28e2465da7e3b
[*2]:https://www.kagoya.jp/howto/cloud/container/rancher_desktop/
React公式ドキュメントの理解（UIの記述）

Reactを独学で学ぶ上で、いちばん最初に公式ドキュメントの理解から着手しようと思ったのでアウトプットも兼ねて内容をまとめました。
ここではReact公式ドキュメントの「**UIの記述**」をまとめました。

# こんな人向け
- Reactを触ったことがない人
- Reactに興味があり、学ぼうとしている
- Reactの概念・仕組みを知りたい

# 筆者の状態
- html, css, javaScriptはある程度知っている
- Reactは初心者

## Reactのコンポーネント
Reactアプリケーションはコンポーネントと呼ばれる独立したUIのパーツで構成されています。コンポーネントとはマークアップを添えることができるJavaScript関数です。
※昔はHtmlにJavaSctiptで動的な挙動があれば嬉しいレベルだったのですが、もう現在はそれが当たり前になっています。そこで出てきたのがReactのコンポーネントという仕組みです。
※また、コンポーネントの名前の始まりは「大文字」に限定されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2779353/e7681e5c-2ad5-4ed2-9d51-733fe57f4d3c.png)

## コンポーネントにpropsを渡す
Reactコンポーネントでは、propsを使ってお互いに情報をやり取りします。親コンポーネントは、子コンポーネントにpropsを与えることで、情報を渡すことができます。HTMLの属性と似ていますが、オブジェクト、配列、関数、そしてJSXまで、どんなJavaScriptの値でも渡すことが出来ます。

## コンポーネントを常に純粋に保つ
純関数には以下の特徴があります。
- **自分の仕事に集中する。呼び出される前に存在していたオブジェクトや変数を変更しない**
- **同じ入力には同じ出力。同じ入力を与えると、純関数は常に同じ結果を返す。

■悪い例
```App.tsx
let guest = 0;

function Cup() {
  // Bad: changing a preexisting variable!
  guest = guest + 1;
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup />
      <Cup />
      <Cup />
    </>
  );
}

```
■良い例
既に存在する変数を書き換えるのではなく、propsを渡すようにする。
```App.tsx
function Cup({ guest }) {
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup guest={1} />
      <Cup guest={2} />
      <Cup guest={3} />
    </>
  );
}

```
Geminiで学者を描いてみた。

# 概要

Geminiで学者を描いてみました。

# 実装

プロンプトと実行結果は以下の通りです。

```
炎の本を使う学者を描いてみてください。
```

![炎の本を使う学者_20250411.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/6dfe21c0-2376-4b91-906e-3d15b301af83.png)

```
氷の本を使う学者を描いてみてください。
```

![氷の本を使う学者_20250411.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/5e370410-482d-4203-b69c-cc38868b7015.png)

```
電撃の本を使う学者を描いてみてください。
```

![電撃の本を使う学者_20250411.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/aed641dd-cf29-4f9c-8ffe-3e78d0b24015.png)

いい感じです。プロンプトを工夫すればいろいろ描けそうです。

# まとめ

何かの役に立てばと。
AI系のプレイグランドのまとめ


今までのプレイグランドとは違った制約があるようです。


# 「検証ステップ」は間違った UI で実行されていますか?

+ [「検証ステップ」は間違った UI で実行されていますか?](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000MaDdf)

:::note
新しいユーザーIDを使って新しいUIで最初からやり直し、「確認手順」を完了しました。時間はかかりましたが、問題を解決できてよかったです。 
:::

# fitness_cオブジェクトが欠落

+ [プロンプト ビルダー テンプレート スーパーバッジ ユニット - 開発者組織 フィットネス オブジェクトがありませんか?](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000PXLgR)

Salesforceの社員向け環境だから？

:::note
ケースを作成し、Trailheadのサポート担当者が特別な設定で開発者エディションの組織を作成するのを手伝ってくれました。スーパーバッジのページで組織リクエストを何度か使用しましたが、そのたびにfitness_cオブジェクトが欠落していました。Trailheadのサポート担当者が、組織を作成するためのリンクとログイン/メールアドレスを教えてくれました。そのリンクに従って正しい組織を作成し、スーパーバッジを完了することができました。
:::


# 切断できない

+ [Trailhead support teamの指示のようにプレイグランドを切断できない](https://qiita.com/Keiji_otsubo/items/8e77c888c4610b3b24aa)
+ [Need help to change the default playground](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000SVXQ5)

以下の手順で強制的に切断できる

:::note
Please follow below steps:

+ Open Hands-On Orgs (https://trailhead.salesforce.com/users/profiles/orgs) page
+ Click on Create Playground button (wait 2 to 3 minutes to create playground org)
+ Once it is created, you'll be able to disconnect Datacloud dev org 'epic.xxxx@orgFarm.th' (Org shows Disconnect option)
+ After disconnecting the ''epic.xxxx@orgFarm.th' org, open the Data cloud challenge (https://trailhead.salesforce.com/content/learn/projects/create-a-data-stream-in-data-cloud/create-a-data-stream) and click on Connect Org button at challenge page and reconnect the org and click Yes, Save It button.


Once the org is connected, you'll be seeing Launch button. If Launch button appears, scroll down and click on Verify Step to complete the challenge. 


https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007cllNISAY
:::

### 未解決

+ [アイコンをクリックしてログインを促し、リセット時に設定したパスワードを入力しても機能しません。「パスワードを忘れた場合」のリンクも何も機能せず、使えません。何かご存知の方はいらっしゃいますか？  ](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000TjBwk)
+ [Unable to connect the org](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000SXMTw0AP)


# 接続できていない例

+ [I am working on the "Get Started with Data Cloud and AI" module as part of the "Build an AI Agent with Agentforce" trail, but I seem to be stuck.](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000PYHbP)

:::note
 You can click the Create button by checking the checkbox as shown below.

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/7e748474-555a-4672-b38f-267a4e776465.png)
:::

# This Badge Requires a New Custom Data Cloud and Einstein AI Playground

+ [This Badge Requires a New Custom Data Cloud and Einstein AI Playground](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000PZasG)

:::note
 I just refreshed the page, and I was now able to request a new password. That's so weird. 
ページを更新したら、新しいパスワードをリクエストできるようになりました。変ですね。
:::

Create Playground button not enabled? 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/50188d3d-6811-4858-8cc7-c4047178188c.png)
XIAO ESP32C6でLチカして遊ぶ。(導入編)(Arduino)


目的
----

XIAO ESP32C6は、外人がよく使っているので(ほぼ)外人向け


結果(成功)
----

![image_original (80).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/05a96a58-2521-4225-836c-4f342825eb20.jpeg)

![image_original (81).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/5e30f19b-9413-4eb0-8dfb-06045e9efde5.jpeg)


インストールとコンパイル
----

![o_coq855.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/06e731a4-5f5e-4d58-a37c-ac5765e938d7.jpeg)

![o_coq856.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/01a9e5b1-6aae-4d06-abae-accbf0e8305c.jpeg)

![o_coq857.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/6719fe4d-e9bf-43ef-8ff7-bc52a2985a6d.jpeg)

```

https://espressif.github.io/arduino-esp32/package_esp32_index.json

```



![o_coq858.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/89a7126d-3f26-4235-918c-32f48b66cfcf.jpeg)

![o_coq859.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/cc3a01aa-98ab-43e0-a2d7-9b080fb25b6b.jpeg)

![o_coq860.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/b70f46de-e602-4324-87b7-a2d18da51a8d.jpeg)

![o_coq861.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/a50a9c44-e536-4e16-99f7-f32eff267fbe.jpeg)

```c++



```


![o_coq862.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f680f7bf-bc37-4a91-b944-1125a5985567.jpeg)

![o_coq863.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/96f56af6-b18a-4a62-907c-ef9b417f9ab9.jpeg)

![o_coq864.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/84f8a729-676f-45ec-8f30-178cdab4e91f.jpeg)
Agent2Agent(A2A)の魅力と将来像について

# Agent2Agent（A2A）プロトコルの魅力と将来像

Googleが2025年4月9日に開催された「Google Cloud Next 2025」で発表したAgent2Agent（A2A）プロトコルは、AIエージェント間の相互運用性を実現する画期的なオープンプロトコルです。このプロトコルの魅力と将来像について要約します。

## A2Aの魅力

A2Aプロトコルの最大の魅力は、異なるベンダーやフレームワークで構築されたAIエージェント同士が安全に通信し、情報交換や連携作業を行えるようにする点にあります[1][3]。これにより、企業内のサイロ化されたシステムやアプリケーション間の壁を取り払い、AIエージェントの真の力を引き出すことが可能になります。

A2Aの主な魅力は以下の点にあります：

1. **オープン性と拡張性**: オープンソースとして公開され、コミュニティからの貢献を歓迎する形で開発されています[5]。これにより、幅広い開発者やベンダーが参加し、エコシステムの拡大が期待できます。

2. **エンタープライズ対応**: 既存のITスタックとの統合が容易で、企業レベルの認証と認可をサポートしています[5]。

3. **強力なパートナーシップ**: Atlassian、Box、Cohere、Intuit、Langchain、MongoDB、PayPal、Salesforce、SAP、ServiceNowなど50社以上のテクノロジーパートナーと主要なサービスプロバイダーが参加しており、業界全体での採用が期待されます[9]。

4. **技術的洗練**: Agent Card（エージェントカード）を通じた機能発見や、タスク管理、多様なモダリティ対応など、実用的な機能が実装されています[5]。

## A2Aの将来像

A2Aプロトコルの登場は、AIエージェント技術の次なる重要課題が「相互運用性と連携」であることを示しています[7]。その将来像として以下のようなシナリオが考えられます：

### 1. エージェント協調時代の到来

A2Aは単なる技術仕様ではなく、AIエージェントの協調によって実現する新たな自動化パラダイムの基盤となる可能性を秘めています[7]。複数のエージェントが連携してタスクを完了することで、シームレスなユーザーエクスペリエンスの実現、開発プロセスの簡素化、そして革新的で協調的なAIエコシステムの育成が期待されます[3]。

### 2. 組織変革の触媒

A2Aの興味深い側面は、技術的問題だけでなく組織的課題にも対応している点です。エージェント間の連携を標準化することは、技術的には異なるシステムをつなぐことですが、組織的には異なる機能や部門をつなぐことに相当します[7]。これにより、組織内のコミュニケーションが改善され、部門間のサイロが打破される可能性があります。

### 3. 将来的な普及シナリオ

A2Aの将来については、以下のようなシナリオが考えられます[7]：

- **デファクトスタンダード化**: 広範に採用され、異なるベンダーやプラットフォーム間でエージェントが相互運用するための主要な方法となる可能性。
- **Googleエコシステム標準**: Google Cloud内と密接に連携するパートナーのエコシステム内では広範に採用されるが、それ以外では限定的な採用に留まる可能性。

### 4. 企業価値の創出

A2Aプロトコルにより、AIエージェントが組織全体のアプリケーション環境で連携し、大きな価値を生み出すことが期待されています[9]。複雑な企業ワークフローを自動化し、これまでにない効率性と革新をもたらす未来が描かれています。

## まとめ

A2Aプロトコルは、AIエージェント間の相互運用性という重要な課題に対処する革新的な取り組みです。オープンな標準として設計され、強力なパートナーシップを背景に、企業におけるAI活用の形を大きく変える可能性を秘めています。技術的な連携を超えて、組織変革の触媒となり、AIエージェントの真の力を引き出す基盤として、今後の発展が注目されます。

情報源
[1] Google、AIエージェントの相互運用向けオープンプロトコル「Agent2Agent（A2A）」リリース https://www.itmedia.co.jp/news/articles/2504/10/news098.html
[2] Googleが「Agentspace」発表、AIエージェントで企業内の定型業務 ... https://xtech.nikkei.com/atcl/nxt/column/18/00001/10073/
[3] Googleの新提案「Agent2Agent (A2A)」とは？ AIエージェント連携 ... https://zenn.dev/leohara/articles/a9b71325a028fb
[4] 生成 AI のその先へ : AI エージェントを支えるテクノロジー https://cloud.google.com/transform/ja/more-than-gen-ai-other-ai-ml-technologies-making-ai-agents
[5] Agent2Agent Protocol (A2A)：AIエージェント間の相互運用性を実現 ... https://qiita.com/RepKuririn/items/67bde44b58d6512e9409
[6] AIエージェントが描く2025年の世界 | HUMAN ∞ TRANSFORMATION https://www.ridgelinez.com/hx/contents/transformation-20250123/
[7] Google 発の Agent2Agent（A2A）プロトコル：AIエージェント間 ... https://blog.wadan.co.jp/ja/tech/agent2agent-protocol
[8] Googleが描くAIエージェントの未来と知っておくべき5つのポイント https://chatgpt-enterprise.jp/news/google-ai-agent/
[9] Agent2Agent プロトコル（A2A）を発表：エージェントの相互運用 ... https://cloud.google.com/blog/ja/products/ai-machine-learning/a2a-a-new-era-of-agent-interoperability
Dockerのインストール windows向け

# Docker Desktopのインストール
ではそのDockerをインストールしていきます。WindowsでDockerを使うためにはDocker Desktopを使うのが一番簡単です。
[Docker](https://www.docker.com/ja-jp/)の公式サイトから下記画像のようにWindows版ダウンロード
![2025-04-11_03h22_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4058165/e3134227-1d9c-4bb9-968e-75fb732dec75.png)

ダウンロードしたインストーラーを起動、チェックはこのままにOKを押す
![2025-04-11_03h23_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4058165/29f65260-f5af-434c-a958-5a9deb2328b2.png)

Close and restartを押すとWindowsが再起動されます
![2025-04-11_03h31_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4058165/37b88535-fe07-4e77-ad46-50d18b225bf6.png)

もう一度Dockerを起動してAcceptを押す
![2025-04-11_03h33_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4058165/885e0d2b-2e68-468c-b9f7-20248e147fe2.png)

このままFinish
![2025-04-11_03h33_16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4058165/437495cd-0c5a-40eb-9154-274ebe982a7f.png)

ログインはお好みで、ここではスキップ
![2025-04-11_03h33_28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4058165/affc4a86-c56d-403e-ad51-c5d94a33fe63.png)

この画面はDocker Engineが起動中なのでしばらく待機
![2025-04-11_03h33_42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4058165/de7f24c9-b61e-4628-bc2d-34ff71b2182f.png)

この画面が来たら準備OK
Dockerのインストールは完了となる
![2025-04-11_03h37_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4058165/a3bd74c4-2fdb-4b80-a9e2-0bc48627c895.png)


# Dockerとは？
コンテナと呼ばれるとりあえずの綺麗な動作環境を作るソフトウェアである。例としてここでは水槽とコップで表す。

- 水槽：パソコンやサーバー（ホスト）
まず、大きな水槽を想像してください。これは、あなたのパソコンやサーバーなどの「本体」で、中には水（リソース：CPUやメモリなど）が入っていて、いろんなことに使える。

- コップ：Dockerコンテナ
その水槽の中にコップをいくつか浮かべることができる。このコップがDockerコンテナである。コップの中にも水が入っていて、それぞれ独立した小さな世界になっている。

コップごとに違う飲み物（＝アプリ）が入れられる。

たとえば、1つのコップにはコーヒー（ファイルサーバー）、もう1つにはジュース（Webサーバー）という感じで分けられる。

コップは水槽の水を少しだけ使う（＝ホストのリソースを分け合う）が、お互いの中身は混ざらない。


エンジニアの世界ではコップの中の水を汚す＝環境を汚すなどと例える。

筆者はDockerコンテナを簡単起動できるようにDocker composeをよく利用している。
windows11で、sketchup6 その65

# 概要
windows11に、sketchup6を入れてみた。
rubyで、3Dを書く。
練習問題、やってみた。

# 練習問題
rubyスクリプトでアナログ時計を書け。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/339342cd-deb9-44dd-9cf6-2691702db31b.png)

# サンプルコード

```

require 'sketchup.rb'

class Tokei
	def initialize
		@id = 0
		model = Sketchup.active_model
		entities = model.active_entities
		group_circle = entities.add_group
		circle = group_circle.entities.add_circle [0, 1, 22], [0, 1, 0], 22
		circle_face = group_circle.entities.add_face circle
		circle_face.pushpull -0.1
		depth = 10
		width = 1
		pts = []
		pts[0] = [0, 0, 0]
		pts[1] = [width, 0, 0]
		pts[2] = [width, 0, depth]
		pts[3] = [0, 0, depth]
		group_hour = entities.add_group
		face_hour = group_hour.entities.add_face pts
		face_hour.material = "black"
		face_hour.pushpull 0.015
		trans = Geom::Transformation.translation [-0.5, 0, 21]
		group_hour.transform! trans
		rot = Geom::Transformation.new [0, 0, 22], [0, 1, 0], Time.now.hour * 30.degrees
		group_hour.transform! rot
		depth = 16
		width = 1
		pts = []
		pts[0] = [0, 0, 0]
		pts[1] = [width, 0, 0]
		pts[2] = [width, 0, depth]
		pts[3] = [0, 0, depth]
		group_minute = entities.add_group
		face_minute = group_minute.entities.add_face pts
		face_minute.material = "black"
		face_minute.pushpull 0.015
		trans = Geom::Transformation.translation [-0.5, 0, 21]
		group_minute.transform! trans
		rot = Geom::Transformation.new [0, 0, 22], [0, 1, 0], Time.now.min * 6.degrees
		group_minute.transform! rot
    	depth = 20
		width = 1
		pts = []
		pts[0] = [0, 0, 0]
		pts[1] = [width, 0, 0]
		pts[2] = [width, 0, depth]
		pts[3] = [0, 0, depth]
		group_second = entities.add_group
		face_second = group_second.entities.add_face pts
		face_second.material = "red"
		face_second.pushpull 0.01
		trans = Geom::Transformation.translation [-0.5, 0, 21]
		group_second.transform! trans
		rot = Geom::Transformation.new [0, 0, 22], [0, 1, 0], Time.now.sec * 6.degrees
		group_second.transform! rot
	end
end




```

以上。
pythonのrequests.Sessionのサンプルコードメモ

ネットアクセス系の機能にすごい苦手意識を持っていたのですがどうしても仕事で必要になってしまったため
ChatGTPにrequests.Sessionの使い方について聞いてみた

```ChatGPT.txt
最初にアクセスしたいのは https://a_example.com/protected
ログインが必要な場合は https://b_example.com/login%a_example%com にリダイレクトされる
ログイン後、自動的に元のページ https://a_example.com/protected に戻ってくる

このようなクロスドメインログイン（SSOっぽい）＋リダイレクト構成の場合でも、
requests.Session() を使えば大体は対応できます。
💡 補足
サーバーが 302 や 301 でリダイレクトする場合、requests は自動で追従します。
response.url を見れば、リダイレクト先の現在地がわかります。
CSRF トークンが必要な場合は BeautifulSoup などで HTML から抽出できます。

```


ボク「はぇ～こういうのがリダイレクトとかクロスドメインっていうのか…
言葉だけ知っていも実践で遭遇してそれと分からないのは
なんというかやっぱり素の頭が悪いのか、勉強しかたが悪いの、効率が悪いのか、なんかつらいな」


```testlogin.py
import requests
from bs4 import BeautifulSoup

# セッションを作成（Cookie やリダイレクトの状態を維持）
session = requests.Session()

# 最初のアクセス：保護されたページ
initial_url = "https://a_example.com/protected"
response = session.get(initial_url)

# ここでログインページ（https://b_example.com/login%a_example%com）に自動リダイレクトされる
# レスポンスのURLや内容からログインページかどうかを判断
if "login" in response.url:
    print(f"リダイレクト先: {response.url}")

    # ログインページにある hidden フィールド（例：csrf_token）などを抽出（必要なら）
    soup = BeautifulSoup(response.text, 'html.parser')
    csrf_token = soup.find("input", {"name": "csrf_token"})["value"] if soup.find("input", {"name": "csrf_token"}) else ""

    # 認証情報とCSRFトークンを送信
    login_payload = {
        "username": "your_username",
        "password": "your_password",
        "csrf_token": csrf_token  # 必要に応じて
    }

    # ログイン先URL（通常は response.url）
    login_url = response.url
    login_response = session.post(login_url, data=login_payload)

    # ログイン後、自動的に a_example.com に戻っているかチェック
    if login_response.status_code == 200:
        print("ログイン成功。再度アクセスします。")
        final_response = session.get(initial_url)
        print(final_response.text)  # これが保護されたページのHTML

    else:
        print("ログイン失敗")
else:
    # すでに保護ページにアクセスできた場合
    print(response.text)
```
初学者がCursorを使ってAI全任せの開発をしてみた結果

## はじめに
#### 筆者の紹介
初学者といってもどのくらいのレベルなのかを書いておきます。
・情報系の学部4年生
・簡単なToDoアプリ(React,Vueなし)はつくったことがある

#### きっかけ
プログラミング言語やフレームワークの知識がほぼなくてもCursor使えばアプリ開発できるんじゃね？と思ったから
#### 結論
それっぽいものはできたけど全然ダメでした。

## つくりたいもの
学内のサイトからGoogle拡張機能を使って学校の課題のデータを取得して、ウェブアプリで管理するシステムを作成しようとしました。
技術スタックもAIに考えてもらいました。

フロントエンド: React + TypeScript
バックエンド: Node.js + Express
データベース: SQLite（ローカル開発用）
通知: Electron（デスクトップ通知用）
## 方針
AgentモードでAIが生成したコードをすべてAcceptしました。
使うAIはautoで選択してもらう。
基本AI任せ

## 結果
一日触ってみただけですが、拡張機能とアプリが通信できない、拡張機能にすべての機能が集約される、それっぽいものができて以降は改悪されていく、といった大失敗でした。
## 考察
考えうる失敗した原因を列挙します。


##### 1.ある程度言語やフレームワークに対する知識がないと効率的な開発を行えない。
→AIは一発で正解の機能をつくってはくれないのでバグ修正をしなければならないが、ある程度コードを読む、もしくは出力をみて何が原因かがわからなければ難しい。今回は拡張機能のことを全く知らないのでなぜ通信ができてないのかがすぐにはわからなかったし、AIには修正してもらえなかった。

##### 2.claude-3.7-sonnetの無料版を使い切ってしまい、コードの品質が途中から悪くなった。
→最初はかなりうまくいっていたのに途中から全く進まなくなったのでChatGPTが原因の可能性はある。

##### 3.プロンプト(AIへの指示)が適切でなかった。
→拡張機能にデータ、アプリ側でデータの管理や表示といった機能の分け方をしたかったのだが、途中から拡張機能に機能が集約されて行ってしまった。適切なプロンプトと適切なコードの選択をする必要を感じた。

## Cursorが便利だなと感じたこと
##### コマンドを実行してくれる
設定次第ですが、提案してくれたコマンドを実行してくれます。このおかげで、React等の開発環境の構築がスムーズでした。触れたことがない技術であってもスムーズにセットアップできます。

##### ディレクトリ構成を把握してくれる
初学者にとってどのファイルをどこに置くのか、どうやってパスを通すのかといったことは少しハードルだと思います。今回の開発とは関係ないですが、静的ファイルの配信をするのに数時間詰まったりしました。Cursorを使うと、どのファイルがどこにあるのか把握してくれるので、適切なファイルの場所であったり、適切なパスのコードを生成してくれていました。

##### エディタ内でAIを使える
生成AIを開いたブラウザとエディタの行き来は面倒くさいものです。Cursorであればエディタ単体で作業できるので、よく生成AIとVScodeを使う方であればむしろCursorのほうがいいかもしれません。

## まとめ
何も知らない人が全部AI任せで必ずうまくいくとは限らないように感じました。ですが、個人開発であればいつでもAIに聞けて開発できるのはすごく便利だと感じます。今後は基本、自力で開発しつつ、詰まったときは気軽にAskモードでデバッグしてもらうツールとして活用いていこうかなと考えています。
【完全版】RTX 6000 Ada + CUDA 11.8 + TensorFlow 2.12.0 のGPU対応環境構築手順（Ubuntu）

# 【完全版】RTX 6000 Ada + CUDA 11.8 + TensorFlow 2.12.0 のGPU対応環境構築手順（Ubuntu）

## 概要
NVIDIA RTX 6000 Ada世代のGPUを搭載したLinux（Ubuntu）マシンにおいて、TensorFlow 2.12.0をGPU対応で動作させるための環境構築手順をまとめた。Anaconda環境の構築からTensorFlowによるGPU認識の確認まで、つまずきやすいポイントをすべて含めて記述する。

## 1. Anacondaのインストール

```bash
wget https://repo.anaconda.com/archive/Anaconda3-2022.10-Linux-x86_64.sh
bash Anaconda3-2022.10-Linux-x86_64.sh
```

- インストーラ中の質問には基本的に `Enter` でOK。
- `conda init [no]` の箇所では **必ず "yes"** と入力。

インストール完了後、環境変数を反映：

```bash
source ~/.bashrc
```

`(base)` がプロンプトに表示されれば完了。

## 2. conda環境を作成（例: tf212）

```bash
conda create -n tf212 python=3.9
conda activate tf212
```

## 3. CUDA ToolkitとcuDNNをpipでインストール

```bash
pip install --upgrade pip
pip install nvidia-cudnn-cu11==8.6.0.163 nvidia-cublas-cu11
```

## 4. TensorFlow 2.12.0のインストール

```bash
pip install tensorflow==2.12.0
```

## 5. 環境変数の設定（cuDNNのライブラリパスを通す）

```bash
mkdir -p $CONDA_PREFIX/etc/conda/activate.d
mkdir -p $CONDA_PREFIX/etc/conda/deactivate.d
```

`activate.d/env_vars.sh`:

```bash
echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$CONDA_PREFIX/lib/python3.9/site-packages/nvidia/cudnn/lib' > $CONDA_PREFIX/etc/conda/activate.d/env_vars.sh
```

`deactivate.d/env_vars.sh`:

```bash
echo 'unset LD_LIBRARY_PATH' > $CONDA_PREFIX/etc/conda/deactivate.d/env_vars.sh
```

## 6. GPUの認識確認

```bash
python -c "import tensorflow as tf; print(tf.config.list_physical_devices('GPU'))"
```

出力例：

```python
[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU'), PhysicalDevice(name='/physical_device:GPU:1', device_type='GPU')]
```

これが表示されれば、GPUの利用が可能な状態である。

## 参考コマンド集

### GPUとCUDAの確認：
```bash
nvidia-smi
```

### cuDNNライブラリの場所確認：
```bash
find $CONDA_PREFIX -name "libcudnn.so*"
```

---

## 補足
- RTX 6000 AdaはCUDA 12.1に対応しているが、TensorFlow 2.12はCUDA 11.8がサポート対象。
- conda経由の`cudnn`や`cudatoolkit`パッケージは互換性に注意が必要なため、`pip`インストールのほうが安定するケースがある。
- TensorFlow 2.12以降ではcuDNNとcuBLASが`pip`パッケージに分割されているため、個別にインストールが必要。

## まとめ
本手順に従うことで、CUDA 11.8 + cuDNN 8.6.0 + TensorFlow 2.12.0の構成でRTX 6000 Adaに対応したGPUアクセラレーション環境が構築できる。特にTensorFlow側の仕様変更（cuDNN/BLASの切り離し）とCUDAのバージョン依存関係に注意することが重要である。
競プロ日記#25/04/10

# アルゴ式-[コマの道順](https://algo-method.com/tasks/329)

- dp[][]に対してある（i,j）マスが上からくる場合と左からくる場合で場合分けする
```
for (int i = 0; i < N; ++i) {
    for (int j = 0; j < N; ++j) {
        // 上から来る場合
        if (i - 1 >= 0) dp[i][j] += dp[i-1][j];

        // 左から来る場合
        if (j - 1 >= 0) dp[i][j] += dp[i][j-1];
    }
}
```
- ちなみに高校数学でやった(N+N)!をN!とN!の積を割るパターンもあるが実装が面倒

# アルゴ式-[コマの道順 (壁あり)](https://algo-method.com/tasks/333)
- [コマの道順](https://algo-method.com/tasks/329)を参考にすれば割と簡単に実装できる。
```
for (int i = 0; i < N; ++i) {
    for (int j = 0; j < N; ++j) {
        if (S[i][j] == '.'){
            // 上から来る場合
            if (i - 1 >= 0) dp[i][j] += dp[i-1][j];

            // 左から来る場合
            if (j - 1 >= 0) dp[i][j] += dp[i][j-1];
            }
        
    }
}
```
- S[i][j]が.か#かで場合分けすれば十分

# アルゴ式-[500 円玉貯金](https://algo-method.com/tasks/649)
- 簡単
- iを0からNまでのN+1回for文で回してX + i * increを出力する
``` 
int N,X;
cin >> N >> X;
int incre = 500;

for (int i = 0;i <= N;i++){

    cout << X + i * incre << endl;
}
```
【RSpec×Rails×Devise】記事投稿のテストに失敗した理由、解決方法

## RSpec×Rails×Devise】記事投稿のテストについて

こんにちは。
RSpecで記事投稿機能のテストを行う際に「記事が保存されない…」という壁にぶつかりました。  
結論としては「ログインしていなかったから」でした。
備忘録として残します。

---

## 問題になったテストコード（初期）

```ruby
describe 'POST /articles' do
  it '記事が保存される' do
    article_params = attributes_for(:article)
    post articles_path({ article: article_params })
    expect(response).to have_http_status(302)
    expect(Article.last.title).to eq(article_params[:title])
    expect(Article.last.content.body.to_plain_text).to eq(article_params[:content])
  end
end
```


## テスト失敗時のエラー

```bash
expected: "scj6wuliim"
     got: "tyomvot9zt"
```

→ パラメータで送ったタイトルと、実際に保存されたタイトルが一致していない

---

## ログインが必要

多くのアプリでは、記事の投稿はログインユーザーしかできないようになっている。 
そのため、RSpecでログイン処理を入れておかないと、記事は保存されずにテストは失敗してしまう。

---

## 解決方法：テスト内で `sign_in` を使用

```ruby
describe 'POST /articles' do
  context 'ログインしている場合' do
    before do
      sign_in user
    end

    it '記事が保存される' do
      article_params = attributes_for(:article)
      post articles_path({ article: article_params })
      expect(response).to have_http_status(302)
      expect(Article.last.title).to eq(article_params[:title])
      expect(Article.last.content.body.to_plain_text).to eq(article_params[:content])
    end
  end
end
```

---

## `sign_in` を使うための設定

```ruby
RSpec.configure do |config|
  config.include Devise::Test::IntegrationHelpers, type: :request
end
```

## テスト結果

```bash
2 examples, 0 failures
```

## わかったこと
- `attributes_for(:article)` はただのハッシュ。保存はされない。
- `Article.last` を使うと、保存された最新記事の確認ができる。
- `sign_in user` でログイン状態を再現しないと、投稿系のテストは通らない！
- `rails_helper.rb` の `require 'devise'` を忘れると、`sign_in` が使えない

------
初学者のため、間違えていたらすいません。
引き続き、学習を進めていきます。
git checkout 時に origin が要る/要らない問題

## 初めに

- Gitをチーム開発で1年ほど使用
- コマンド操作には慣れてきたが、`git checkout` 時に `origin` を書く必要がある場合とそうでない場合があり、動作の違いを明確に理解できていなかったため調査しました。

## 概要
Gitではリモートブランチを操作する際に、

```bash
git checkout origin/hotfix/feature-x
```

と書く場合と、

```bash
git checkout hotfix/feature-x
```

とする場合があり、後者だけ成功することがあります。

この違いがなぜ生まれるのか、Gitの内部動作を踏まえて整理しました。

---

## 1. `git checkout hotfix/feature-x` の場合

ローカルにそのブランチが存在しないとき、Gitは以下のように動作します。

:::note info
リモート追跡ブランチ `origin/hotfix/feature-x` が存在する場合、Gitは自動的にローカルブランチを作成し、追跡ブランチとして設定してくれます。
:::

```bash
git fetch origin
git checkout hotfix/feature-x
```

これは裏で以下のような動作をしてくれているのと同じになります。

```bash
git checkout -b hotfix/feature-x origin/hotfix/feature-x
```

出力例：

```bash
branch 'hotfix/feature-x' set up to track 'origin/hotfix/feature-x'.
Switched to a new branch 'hotfix/feature-x'
```

---

## 2. `git checkout origin/hotfix/feature-x` の場合

一方、こちらの書き方は別の意味になります。

```bash
git checkout origin/hotfix/feature-x
```

これはリモート追跡ブランチを**そのままチェックアウトする**という意味であり、編集・コミットができません。

いわば「読み取り専用モード」でのブランチ切り替えです。

また、以下のようなミスも発生しやすいです。

```bash
git checkout origin hotfix/feature-x
# ❌ エラー：Gitは "origin" というリモートと "hotfix/..." を同時に扱えない
```

---

## 3. よく使う正しい書き方まとめ

### ✅ ローカルブランチをリモートから新しく作る場合

```bash
git checkout -b hotfix/feature-x origin/hotfix/feature-x
```

### ✅ Git 2.23 以降の場合（switch 推奨）

```bash
git switch -c hotfix/feature-x --track origin/hotfix/feature-x
```

---


## 4. なぜPushの `origin` と混同しやすいのか？

Gitではよく以下のようなPushコマンドを使います。

```bash
git push origin hotfix/feature-x
```

これは：

> 「このブランチを origin って名前のリモートリポジトリに送ってね！」という意味
> 

一方、以下のような `checkout` の使い方をしようとすると混同しやすくなります。

```bash
git checkout origin/hotfix/feature-x
```

これは：

> 「originリモートにあるブランチを一時的に読み取り専用で見るね！」

---

### 🎯 例えるなら：

- `git push origin ブランチ名`
    → 「**データ送るから受け取ってね、origin先生！**」
    
- `git checkout origin/ブランチ名`
    → 「**origin先生のところにあるメモだけ見せて**」
    
- ❌ `git checkout origin ブランチ名`
    → 「**originって人とブランチ名って人を同時に呼び出す」謎コマンド**
    
    Git「えっ、何？どこ見ればいいの？わかんない…（爆死＼(^o^)／）」

---

## まとめ

- `git checkout ブランチ名` はローカルにブランチがなければ `origin/ブランチ名` を自動で探して作ってくれる
- `git checkout origin/ブランチ名` は読み取り専用で、基本的には作業には不向き
- `git push origin ブランチ名` のような書き方と混同しやすいが、用途が異なる
- `git checkout origin ブランチ名` のような構文は完全にNG（構文ミス）
BCP 47とは

# BCP 47（言語タグ）
- Best Current Practiceの略
- インターネット上での言語識別のためのタグを定義するための企画
- インターネット上の言語コードは、BCP 47がデファクトスタンダード
- 言語コードと国コードをハイフンで組み合わせて使用する
例: zh-TW
- 言語コードと国コードを指定する理由は、一部の国々では複数の公用語が使用されているから
# どうゆう時に使うのか？
例）
アプリでユーザ指定した言語のファイルを、外部サーバからAPI通信で貰う時
→アプリからサーバへ、API通信でファイルが欲しい言語の言語コードを送る
- 日本語の言語コード：jp
- アメリカ英語のファイルが欲しい場合：en-US
  
# Java8のライブラリのLocaleクラス
https://docs.oracle.com/javase/jp/8/docs/api/java/util/Locale.html
- 国に使用する定数（例：JAPAN）や、言語に使用する定数（例：JAPANESE）も定義されている
- Localeオブジェクトを作成する方法は上記の公式ドキュメントに書いてある
- ロケール・データ交換用のLDML (UTS#35「Unicode Locale Data Markup Language」) **BCP 47**互換拡張をサポートする


# 参考サイト
https://labs.gree.jp/blog/2012/11/6439/

https://zenn.dev/sajikix/articles/intl-advent-calendar-24-02

https://docs.hellouniweb.com/docs/developer-guide/sdk-api/lang-code

https://www.samuraiz.co.jp/adobeproduct/jrun/docs/jr4/docs/html/Programmers_Guide/i10n3.html
シャドーAI管理戦略：T部門が牽引する新時代のAIガバナンス


---

# 🕵️‍♂️ **シャドーAIの脅威と可能性：T部門が主導すべき統制戦略とは？**

## 🔍 はじめに：シャドーAIとは？

「シャドーAI」とは、企業内で正式なIT部門やセキュリティチームの監視・管理を受けずに、現場レベル（営業・マーケ・人事など）で独自に導入されるAIツールやサービスを指します。SaaS型の生成AIやChatGPT、翻訳API、画像生成ツールなどがその代表例です。

一見、業務効率の向上をもたらすこれらのツール。しかし、**データ漏洩・セキュリティ脆弱性・倫理的リスク**といった重大な問題を引き起こす可能性も孕んでいます。

---

## 📌 なぜT部門はシャドーAIに注目すべきか？

T（Technology）部門がシャドーAIを軽視した結果、以下のような事態が発生することがあります：

- 社内機密情報が外部APIに流出  
- 法的コンプライアンス違反（GDPRやAI法など）  
- モデルへの偏見学習やAI判断の透明性欠如  
- セキュリティ監査の際に「誰が何を使っているか把握できない」状態に  

**「見えないAI」ほど、潜在リスクが大きい**のです。

---

## 1️⃣ 実例で見る：シャドーAIのリスクと現場での課題

### ✅ ケース1：営業チームが独自に使うChatGPT

ある企業では、営業チームが見積書作成を効率化するためにChatGPTを導入。しかし、提示された顧客名・契約金額などのセンシティブ情報がAPI経由で外部に渡っていたことが後に発覚。

**👉 対応策：**  
T部門は生成AI向けに**プロキシサーバ＋フィルター機構**を設置。特定ワードや個人情報の遮断フィルターを組み込み、安全なやりとりを確保。

---

### ✅ ケース2：マーケティングチームが画像生成AIを導入

画像コンテンツを高速生成する目的で導入された生成AIが、著作権に触れるコンテンツをベースに画像生成していたため、企業が法的リスクに晒された。

**👉 対応策：**  
T部門と連携し、使用するAIモデルを**オープンライセンス素材限定**に切り替え。社内向けに「AI画像ガイドライン」も配布。

---

## 2️⃣ 管理戦略：T部門が主導すべき5つの対策

| 戦略 | 具体的施策 |
|------|-----------|
| **① シャドーAIの可視化** | 社内ネットワーク上でのAI API通信のログ収集・可視化 |
| **② ポリシーとガイドラインの整備** | 「AI使用ガイドライン」やチェックリストの策定 |
| **③ 安全な代替ツールの提供** | 認可済みのLLMやAI API（例：社内版GPT）の導入 |
| **④ 利用者教育の実施** | 各部門向けに「シャドーAIリスク研修」を提供 |
| **⑤ 継続的な監査と改善** | ITガバナンスの一部としてAI活用状況を定期監査 |

---

## 3️⃣ 組織文化としてのAI活用管理

T部門が「AIの使用＝リスク」と見なすのではなく、**安全に活用できる環境づくりを提供すること**が重要です。

Google内部でも、社内開発ツールとAIサービスを組み合わせたハイブリッドなフレームワークを構築しています。その中で、**部門横断のAIガバナンス委員会**を立ち上げ、ビジネスと技術のバランスをとる取り組みが進んでいます。

---

## 🧠 T部門の視点から見た未来への提言

1. **T部門は"守るだけ"でなく"促進者"であれ。**  
2. **AIを制限するより、"正しく導く"視点を持て。**  
3. **ツール導入ではなく、AIリテラシーを育てよ。**

シャドーAIの存在を否定するのではなく、**その利便性とリスクを共に認識し、正しく活用する文化を根付かせる**ことが、今後の競争力の源泉になると考えています。

---

## ✨ おわりに

シャドーAIの時代、T部門の役割はますます重要になっています。ルールを定めるだけではなく、**共にAIを活かす戦略パートナーとしての姿勢**が問われています。

あなたの会社では、シャドーAIにどう向き合っていますか？現場の課題や成功事例があれば、ぜひコメント欄で教えてください！
シャドーAIから始まる“裏イノベーション”：公式ルールの外で育つ新ビジネスモデル



# 🕵️‍♂️ **シャドーAIの可能性：ルールの外で生まれる新ビジネスモデルとは？**

## はじめに：表と裏のAI運用

近年、企業内で公式に承認されていないAIツールやモデルが**“シャドーAI”**として利用されるケースが急増しています。シャドーITのAI版とも言えるこの現象は、表向きにはリスクと見なされがちですが、**創造性と現場の課題解決力**が爆発的に高まる潜在力も持っています。

本記事では、シャドーAIの実態とその中から生まれつつある**新しいビジネスモデル**について、実際の現場経験とともに深く掘り下げていきます。

---

## 1️⃣ シャドーAIとは何か？なぜ生まれるのか？

**シャドーAI**とは、企業のIT部門やデータガバナンス部門の管理下にない形で導入・使用されているAIツールやモデルを指します。主な要因は以下の通り：

- 部門の業務課題を迅速に解決したいニーズ  
- 正式ツールの導入プロセスが煩雑・遅い  
- エンジニア・アナリストの「試してみたい」探究心  
- ChatGPTやBardなどのパブリックAIの普及  

---

## 2️⃣ 新しいビジネスの芽：シャドーAIが生む“実験的価値”

企業が気付かぬ間に、現場社員がシャドーAIを使って**プロトタイプや業務効率化ツールを内製化**している事例は少なくありません。

### 📍 実例：営業部門におけるレコメンドエンジンの試作

ある大手製造業の営業チームでは、IT部門の承認を待たず、外部のLLM APIと社内データを非公式に組み合わせて、**「受注確度予測ツール」**を開発。これが社内で評価され、結果的に正式プロダクトとしてIT部門と共に再構築された──という事例がありました。

> 💡 **ポイント：** シャドーAIは“問題意識”と“行動力”の融合地点に現れる。

---

## 3️⃣ ビジネスモデル化のヒント：組織はどう活用すべきか？

企業がこの“非公式な知恵”を排除するのではなく、**「共創の源泉」**として再定義すれば、新しいビジネスモデルが見えてきます。

### ✅ 考えられるアプローチ：

- **「AIスカウター制度」：** 社員による実験的AI活用を社内ハッカソンやピッチ形式で可視化  
- **「PoCサンドボックス」：** ガバナンスの緩やかな試験環境で安全にシャドーAIを試行  
- **「現場ドリブンAI戦略」：** IT部門と事業部が対等にアイデアを持ち寄る体制づくり  

---

## 4️⃣ 現場で見えてきた課題と対処

| 課題 | 解決策 |
|------|---------|
| データセキュリティ・コンプライアンス違反 | API制御、ローカル実行環境、社内プライベートLLMの整備 |
| 属人化・再現性の欠如 | AI利用のログ収集・自動ドキュメント生成 |
| 知的財産の曖昧性 | シャドーAIプロジェクトの成果物を社内特許化・評価対象とする仕組み |

---

## 5️⃣ シャドーAIが導く未来：分散型イノベーションへ

シャドーAIの可能性は、**“中心からのイノベーション”ではなく、“現場からのイノベーション”**にあります。これはGoogle内部でも、現場エンジニアから生まれた実験的な機能が本番製品に組み込まれることが数多くあるように、企業文化の柔軟さとスピードの鍵を握ります。

---

## おわりに：統制と自由のバランスへ

シャドーAIは、取り締まるべき「脅威」ではなく、うまく組織に取り込めば**極めて高い成長ドライバー**になります。

今後、企業は「禁止」か「黙認」かの二択ではなく、「共創と統制のバランス設計」が求められます。あなたのチームにも、まだ見ぬ“非公式の天才”が眠っているかもしれません。


ご希望があれば、この記事をPDF形式やWeb用にリライトすることも可能です。また「シャドーAIとセキュリティ」や「AI利用ポリシーの設計」のようなテーマでも続編をお作りできますよ！