OmniAICreator/Qiita-1.07M huggingface dataset:
Dify v1.1.0: カスタムメタデータによるナレッジベース検索の精密フィルタリング

> 著者：Yawen、Difyプロダクトチーム
> 本日、Dify v1.1.0をリリースします。メタデータをナレッジフィルターとして活用することで、精密なデータフィルタリングとアクセス制御を実現し、検索精度・セキュリティ・効率性を向上。効果的な検索拡張生成（RAG）管理に不可欠な機能です。

本回、メタデータフィルタリング機能を搭載したDify v1.1.0のリリースをお知らせします。この新機能により、カスタムメタデータ属性を活用したナレッジベースの関連データ検索精度が大幅に向上。従来ユーザーは特定条件での絞り込みができず、大規模データ全体を検索する必要がありましたが、メタデータによるタグ付けと分類で検索効率と精度が改善されます。特に大量情報の管理が求められる検索拡張生成（RAG）システムにおいて重要な進化です。

## メタデータフィルタリングの仕組み
メタデータとは「データに関するデータ」を指します。主要データを説明する追加の文脈や属性を提供し、より精密な検索と取得を可能にします。例えば文書管理システムでは、文書名・作成者・作成日などがメタデータに該当します。この構造化された情報により、システムは特定基準に基づいた結果のフィルタリングが可能になり、取得コンテンツの関連性が向上します。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924419/0cbbaf89-19f7-444d-b0cc-51c809fb102f.png)

## メタデータフィルタリングのメリット

メタデータフィルタリングは、関連文書の迅速な特定と無関係な結果の排除による検索精度向上、権限管理強化によるデータセキュリティの向上、クエリ範囲の最適化による検索パフォーマンス改善という3つの主要メリットを提供します。特に企業環境では、大規模文書リポジトリを直感的にナビゲートできることでユーザー体験が向上します。

下図はアクセス制御の比較を示しており、メタデータフィルタリングによるきめ細かい権限管理の仕組みを説明しています。privacylevel、uploader、update_dateの3つのフィルタリング基準を適用した例では、privacylevelの調整により「RAG 2.0ロードマップ」へのユーザーアクセスを制御できます。これにより管理者は特定情報の取得範囲を精密に管理でき、データアクセスの安全性と効率性を両立できます。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924419/dffa4c95-8eba-4695-9d1d-96dcec2e2d74.png)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924419/818225e0-5ee1-4000-950e-83bcb0a1ae0f.png)

要約すると、メタデータは文脈レイヤーとアクセス制御を追加することで、より知的で安全かつ効率的な情報検索を実現するインテリジェントフィルターとして機能します。ナレッジのプライバシー保護と関連性維持が不可欠な検索拡張生成（RAG）システムにおいて、特に重要な役割を果たします。

## メタデータをナレッジフィルターとして活用する方法

### ステップ1：ナレッジベース文書へのメタデータ追加

ナレッジベース内の文書にメタデータを追加・管理できます。各文書には作成時にファイル名・アップローダー・アップロード日などの基本メタデータが自動付与されます。ユーザーは新規メタデータフィールドの手動追加、フィールド名とデータタイプの設定、既存文書の一括編集が可能です。このタグ付けプロセスにより構造化情報が付加され、後の検索・管理が容易になります。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924419/69e96225-1db3-4496-aa5a-a1e6d3ed31ba.png)

### ステップ2：アプリケーションでのメタデータフィルタリング設定

チャットボットのコンテキスト設定や、チャットフローおよワークフローのナレッジ検索ノードでメタデータフィルタリングを設定可能です。自動モードではユーザークエリからフィルタリング条件を自動抽出、手動モードでは文字列・数値・時間の各データタイプに基づき条件を設定し、複数条件間の論理関係（AND/OR）を指定できます。

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924419/c221e20c-5da2-4453-8f49-70d72665599c.png)

### 3種類のメタデータと活用事例

当社がサポートする文字列・数値・時間の3タイプメタデータは、実際のユースケースに応じて柔軟に活用できます。主な活用事例をご紹介します：

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924419/484a1ec4-31e1-40b7-a19f-b85eb310a274.png)

* **文字列メタデータ - 文脈関連性向上**
「プロジェクトレポート」検索時に「マーケティング」や「研究開発」タグで部門別フィルタリングし、無関係情報を排除

* **数値メタデータ - アクセス制御強化**
プライバシーレベルの数値閾値を設定し、権限のないユーザーが機密文書にアクセスできないよう制限

* **時間メタデータ - バージョン管理**
更新日時によるフィルタリングで最新版文書を優先表示。同一アップローダーの複数バージョン文書を比較検索するテストにも活用可能

詳細な操作手順については、[ナレッジベース｜Dify](https://docs.dify.ai/ja-jp/guides/knowledge-base)ドキュメントをご参照いただき、ぜひDify.AIでお試しください！
metabaseのv0.52系からv0.53系のバージョンアップで、APIの変数の指定方法が変わった

## 対象のAPI エンドポイント
`/api/card/${card-id}/query/${export-format}`

# 結論
1. 変数の指定の方法が、クエリーパラメーターから、bodyに変更。
2. パラメータが2つ追加(format_rows, pivot_results)

## 具体的に
### v0.52系
```
POST https://$domain/api/card/$card-id/query/json?parameters=[{ "target": ["variable", ["template-tag", "${変数名}"]],"type": "category", "value": "${変数の値}"}]
Content-Type: application/json
x-api-key: $x-api-key
```

### v0.53系
```
POST https://$domain/api/card/$card-id/query/json
Content-Type: application/json
x-api-key: $x-api-key
{
  "format_rows": false,
  "pivot_results": false,
  "parameters": [
    {
      "type": "category",
      "target": ["variable", ["template-tag", "${変数名}"]],
      "value": "${変数の値}"
    }
  ]
}
```

## 気をつけること
1. クエリの変数にデフォルト値が設定されてると、今までのクエリパラメータ方式の変数が渡らずデフォルト値でAPIが実行され、成功(200)する
1. クエリに変数のデフォルト値が設定さず、必須にしてると、失敗(400)する
【PHP＆JS】$_POSTの制限＆ajaxとfetchのデータ形式

**背景**
PHPファイルで`$_POST['']`を使い、フロント側からのデータを取ろうとした。`fetch`でも使てみようかと思って使ってみたら、データはうまく取れなかった。調べたら、`$_POST`は決めたデータしか取れないということが分かった。

結論から言うと、`$_POST`は`application/x-www-form-urlencoded`や`multipart/form-data`で送られたデータしか取得できない。
`jQuery`はデフォルトで`application/x-www-form-urlencoded 形式`のデータを送信している。`$_POST`で受け取ることができる。
```ajax.javascript
$.ajax({
    url: "https://example.com/page/function/function.php",
    type: "POST",
    data: { id: id, password: password },
    dataType: "json",
    success: function(response) {
        console.log(response);
    }
});
```
一方、下記は`Content-Type: application/json` を指定しているため、データは**JSON 形式**で送信され、`$_POST`で受け取れない。
```fetch修正前.javascript
fetch('https://example.com/page/function/function.php', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({ id: id, password: password })
})

```
***解決方法①***　**JS**ファイルを直す。
`$_POST`で受け取れる形にする。
```fetch修正後.javascript
fetch('https://example.com/page/function/function.php', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: new URLSearchParams({
        id: id,
        password: password
    })
})
```
***解決方法②***　**PHP**ファイルを直す。
`file_get_contents("php://input")`と`json_decode`を使い**JSON**を受け取る。
```fetch修正後.php
<?php
$data = json_decode(file_get_contents("php://input"), true);
$id = $data['id'] ?? null;
$password = $data['password'] ?? null;
?>
```
ROSがシリアルポートの入力を読み込まない



ROSでデバイスの入力を取得する時に、以下のようなエラーが出てました。
```
$ Cannot open /dev/ttyS0: Permission denied
```

シリアル通信の権限が許可されていないようです。


## 原因

LinuxはUSBなどハードウェア機器を表すファイルは`/dev`に保存されています。
`/dev/ttyS0`はttyS0というデバイスのことを保存しており、権限不足のため、このデバイスにアクセスできないわけです。


## 解決方法

権限を付与するだけで治ります。

```
sudo chmod 666 /dev/ttyS0
```

再起動ごとに実行する必要があります。

## 参考文献

- [Linuxディレクトリ構造](https://qiita.com/nys9302/items/a8ddeedd3cd9d0deb332)

- [Serial port terminal: cannot open /dev/ttyS0: Permission denied](https://askubuntu.com/questions/210177/serial-port-terminal-cannot-open-dev-ttys0-permission-denied)
ROSがシリアルポートの入力を読み込まない


ROSでデバイスの入力を取得する時に、以下のようなエラーが出てました。
```
$ Cannot open /dev/ttyS0: Permission denied
```

シリアル通信の権限が許可されていないようです。


## 原因

LinuxはUSBなどハードウェア機器を表すファイルは`/dev`に保存されています。
`/dev/ttyS0`はttyS0というデバイスのことを保存しており、権限不足のため、このデバイスにアクセスできないわけです。


## 解決方法

権限を付与するだけで治ります。

```
sudo chmod 666 /dev/ttyS0
```

再起動ごとに実行する必要があります。

## 参考文献

- [Linuxディレクトリ構造](https://qiita.com/nys9302/items/a8ddeedd3cd9d0deb332)

- [Serial port terminal: cannot open /dev/ttyS0: Permission denied](https://askubuntu.com/questions/210177/serial-port-terminal-cannot-open-dev-ttys0-permission-denied)
Rails の cookies に signed というのがあったので試した

# Rails の…

cookies に `signed` というのがあるらしいので，確認してみた

[6.1 暗号化cookieと署名済みcookie](https://railsguides.jp/action_controller_overview.html#%E6%9A%97%E5%8F%B7%E5%8C%96cookie%E3%81%A8%E7%BD%B2%E5%90%8D%E6%B8%88%E3%81%BFcookie)

> Railsでは、機密データの保存用に「署名付きcookie（signed cookie）」と「暗号化cookie（encrypted cookie）」を提供しています。



## setup

```
$ devcontainer up --workspace-folder .
$ devcontainer exec --workspace-folder . rails s -b 0.0.0.0
```

## teardown

```
$ docker compose -f .devcontainer/compose.yaml stop
```

## 空のコントローラー作る

```rb
$ edit app/controllers/home_controller.rb
$ cat app/controllers/home_controller.rb
class HomeController < ApplicationController
  def index
    render plain: 'hello'
  end
end 
$ edit config/routes.rb
>> get '/' => 'home#index'   
```

リクエスト `localhost:3000` をすると，開発者ツールのネットワークを確認しても cookie 関連のデータが無いことがわかる．

## cookies を設定してみる

```diff_ruby
$ edit app/controllers/home_controller.rb
$ cat app/controllers/home_controller.rb
class HomeController < ApplicationController
  def index
+   cookies[:something] = 'someone'
  
    render plain: 'hello'
  end
end
```

リクエスト `localhost:3000` をすると，レスポンスに `Set-Cookie` ヘッダに値が入っていることがわかる

```
Set-Cookie: something=someone; ...
```

## cookies.encrypted を設定してみる

```diff_ruby
$ edit app/controllers/home_controller.rb
$ cat app/controllers/home_controller.rb
class HomeController < ApplicationController
  def index
+   cookies.encrypted[:John] = 'Doe'
-   cookies[:something] = 'someone'
  
    render plain: 'hello'
  end
end
```

リクエスト `localhost:3000` をすると，リクエストに `Cookie` ヘッダ，レスポンスの `Set-Cookie` ヘッダに値が入っていることがわかる

```
Set-Cookie: John=uhB...--npG...--R9N...; ...
```

## cookies.encrypted を読んでみる

```diff_ruby
$ edit app/controllers/home_controller.rb
$ cat app/controllers/home_controller.rb
class HomeController < ApplicationController
  def index
+   puts cookies.encrypted[:John]
-   cookies.encrypted[:John] = 'Doe'
  
    render plain: 'hello'
  end
end
```

リクエスト `localhost:3000` をすると，値が取り出せていることがわかる．
(rails s したコンソールで確認する

## Refs

https://qiita.com/coe401_/items/ad7dc2f3e319c5beaf40

https://api.rubyonrails.org/v8.0/classes/ActionDispatch/Cookies/ChainedCookieJars.html#method-i-encrypted

https://railsguides.jp/action_controller_overview.html#cookie
# Optimizing SQL Queries for Better Performance

When dealing with databases, slow queries can become a major bottleneck in application performance. Optimizing SQL queries ensures faster execution, better resource management, and improved user experience. In this article, we’ll go over key strategies to optimize SQL queries efficiently.

## 1. Use Indexing
Indexes significantly improve query performance by allowing the database to find rows faster. Use indexes on frequently searched columns, but avoid excessive indexing as it may slow down insert and update operations.

```sql
CREATE INDEX idx_users_email ON users(email);
```

## 2. Avoid SELECT *
Fetching unnecessary columns increases memory usage and slows down queries. Instead, specify only the required columns:

```sql
SELECT name, email FROM users WHERE status = 'active';
```

## 3. Use Joins Efficiently
When working with multiple tables, using the correct type of JOIN can make a big difference. Prefer INNER JOINs over OUTER JOINs unless all data is required.

```sql
SELECT users.name, orders.amount
FROM users
INNER JOIN orders ON users.id = orders.user_id;
```
<a href="https://myballancenow.org/" rel="follow"> MyBalanceNow </a>
## 4. Optimize WHERE Clauses
Place indexed columns in the WHERE clause and avoid functions on columns as they prevent index usage.

```sql
-- Avoid this (index won't be used)
SELECT * FROM users WHERE LOWER(email) = 'example@email.com';

-- Use this instead
SELECT * FROM users WHERE email = 'example@email.com';
```

## 5. Limit Results When Possible
Fetching too many rows slows down queries. Use LIMIT to retrieve only necessary data:

```sql
SELECT * FROM orders ORDER BY created_at DESC LIMIT 100;
```

## Conclusion
Optimizing SQL queries is essential for database performance and scalability. By indexing correctly, avoiding unnecessary column retrieval, using efficient joins, optimizing WHERE clauses, and limiting results, you can significantly improve quer
RAG（Retrieval-Augmented Generation）の落とし穴とその対策


RAG（Retrieval-Augmented Generation）は、大規模言語モデル（LLM）と情報検索を組み合わせることで、正確で最新の情報を生成できる強力な手法です。しかし、適切に設計しないと**検索精度の低下、生成内容の誤り、パフォーマンス問題**などの課題が発生します。本記事では、RAGを導入する際の落とし穴と、それを回避するための具体的な対策を詳しく解説します。

---

## **1. 検索精度の低さ**
### **落とし穴**
RAGでは、ユーザーの質問を埋め込み（ベクトル化）し、類似度検索によって関連する情報を取得します。しかし、**埋め込みモデルの選定が不適切、検索アルゴリズムの最適化不足、データのフォーマット不備**などがあると、適切な情報が検索されず、回答の精度が低下します。

### **対策**
✅ **埋め込みモデルの適切な選択**
- 一般的なQAシステムには `all-MiniLM-L6-v2` や `msmarco-distilbert-base-v4` を使用。
- 高精度な検索が必要な場合は `text-embedding-ada-002`（OpenAI）を利用。

✅ **クエリ拡張（Query Expansion）を活用**
- ユーザーの質問が短すぎると、適切な検索結果を得られない。
- **類義語を追加**することで検索範囲を広げる。

✅ **検索手法の最適化**
- FAISSの`IndexFlatIP`（内積類似度）を使うことで、コサイン類似度に最適化。
- 再ランキング（Re-ranking）手法を用いて、検索結果を適切に並び替える。

✅ **データの正規化とフォーマット統一**
- FAQデータは `Q: ... A: ...` のような形式に統一。
- 長すぎる文書は分割し、適切なスニペットを検索対象にする。

---

## **2. 生成AIのハルシネーション（誤情報の生成）**
### **落とし穴**
検索で適切な情報を取得できても、LLMが**事実と異なる情報を追加してしまう**（ハルシネーション）ことがあります。特に、検索結果が不十分な場合、LLMは「最もらしいが正しくない」情報を補完しようとします。

### **対策**
✅ **「検索結果のみを使って回答する」制約を追加**
- プロンプトエンジニアリングで、「提供された情報以外を基に回答しない」と指示。
```plaintext
あなたはFAQボットです。以下の情報のみを使って質問に回答してください。
それ以外の情報を加えたり、事実を推測したりしないでください。
```

✅ **検索結果のスコアを用いたフィルタリング**
- 関連度の低い文書は使用せず、閾値を設定（例: 類似度スコア0.7以上のものだけ採用）。

✅ **検索結果の多様性を確保**
- ユーザーの質問に対し、複数のソースから情報を取得。
- 特定の1つの文書だけに依存しない。

✅ **ファインチューニングを行う場合は正しいデータセットを使う**
- 誤情報を含むデータでファインチューニングすると、ハルシネーションが増える。
- 教師データには「信頼性の高い情報」を厳選する。

---

## **3. パフォーマンスの問題（検索速度・応答速度）**
### **落とし穴**
- 検索対象のデータが膨大になると、検索速度が低下する。
- LLMへのAPIリクエストが多くなると、処理時間が長くなる。

### **対策**
✅ **インデックス最適化（FAISSのHNSW, IVFなどを活用）**
- `IndexFlatL2` ではなく、`IndexIVFFlat` や `HNSW` を使用すると検索速度向上。
- 検索対象データが10万件以上なら、クラスタリング（IVF）を適用。

✅ **キャッシュを活用（Redisなど）**
- 同じ質問に対する検索結果をキャッシュし、繰り返し検索を防ぐ。
- LLMの出力もキャッシュしてAPIコールを減らす。

✅ **非同期処理（Async）を導入**
- Pythonの`asyncio`を活用し、並列処理で検索と生成を同時に実行。
```python
import asyncio

async def retrieve_documents():
    # 検索処理（非同期）
    pass

async def generate_response():
    # LLMへのリクエスト（非同期）
    pass

async def main():
    results = await asyncio.gather(retrieve_documents(), generate_response())
    return results
```

---

## **4. セキュリティとプライバシーのリスク**
### **落とし穴**
- RAGの検索対象に**機密データが含まれると、誤って外部に情報が漏れるリスクがある。**
- LLMが機密情報を保持してしまう可能性もある。

### **対策**
✅ **検索対象データのフィルタリング**
- 機密情報（個人情報、取引データなど）が含まれる場合は、検索対象から除外。
- **データマスキング（PII Masking）** を適用。

✅ **アクセス制御と監査ログの導入**
- RAGシステムを社内専用環境で運用し、外部アクセスを制限。
- APIリクエストのログを監査し、不審なクエリを検出。

✅ **LLMの出力を監視し、機密情報をブロック**
- 生成された回答をフィルタリングし、個人情報が含まれていないか検出。
```python
if "機密情報" in generated_response:
    raise Exception("機密情報が含まれています！")
```

---

## **まとめ**
RAGは強力な手法ですが、適切に設計しないと **検索精度の低下、誤情報の生成、処理速度の問題、セキュリティリスク** などの課題に直面します。

### **効果的なRAGシステムを構築するためのポイント**
1. **適切な埋め込みモデルと検索アルゴリズムを選定する**
2. **ハルシネーションを防ぐために検索結果を適切にフィルタリングする**
3. **検索速度を最適化し、非同期処理やキャッシュを活用する**
4. **機密情報の取り扱いを徹底し、セキュリティ対策を行う**

これらのポイントを押さえることで、より信頼性の高いRAGシステムを構築できます。
Springにおけるバリデーションエラーの処理と解決策

## はじめに
Spring Bootを使ったWebアプリケーション開発において、フォーム入力値のバリデーションは欠かせません。
しかし、バリデーションの実装によっては意図しない例外が発生しエラーハンドリングが適切に行われないことがあります。
本記事では、Spring Bootで発生したバリデーションエラーに関する問題とその解決策を紹介します。

## 発生した問題
バリデーションルールを設定したフォームで、特定の条件を満たさない入力が行われた際に、想定外の例外が発生するように処理していました。その際に、適切なエラーハンドリングが行われないケースがありました。

#### 具体的には、
- @Validを使用してバリデーションを実施しているが、エラーメッセージが適切に表示されない。
- ConstraintValidatorを実装したクラス内で RuntimeExceptionをスローすると、Springの@ExceptionHandlerで適切に処理されない。
- エラー時に、想定していたカスタム例外ではなく ValidationException に変換されてしまう。

## 原因
**この問題の原因として、以下の点が挙げられます。**

- ConstraintValidator内でRuntimeExceptionをスローしていた。
- ConstraintValidatorはConstraintViolationExceptionを利用する前提のため、RuntimeExceptionをスローするとValidationExceptionに変換され、カスタム例外で処理できなくなっていた。

## 解決策

**1. ConstraintValidator内でRuntimeExceptionをスローしない**

適切なエラーハンドリングを行うために、ConstraintValidatorContextを使用してbuildConstraintViolationWithTemplateを使う。

```Sample.java
@Override
public boolean isValid(CustomForm form, ConstraintValidatorContext context) {
    if (form.getField() == null || form.getField().isEmpty()) {
        context.disableDefaultConstraintViolation();
        context.buildConstraintViolationWithTemplate("入力値が不正です")
               .addConstraintViolation();
        return false;
    }
    return true;
}
```

**2.  @ExceptionHandlerでValidationExceptionを適切に処理する**

ValidationExceptionを捕捉し、適切なリダイレクトやエラーメッセージの表示を行う。

```Sample.java
@ExceptionHandler(ValidationException.class)
public String handleValidationException(ValidationException ex, RedirectAttributes redirectAttributes) {
    redirectAttributes.addFlashAttribute("errorMessage", ex.getMessage());
    return "index";
}
```

## 他の方法
- **Spring の @Validated を使用する**
コントローラーで @Validated を使用し、BindingResult でバリデーションエラーを処理する。

- **カスタムアノテーションを作成する**
より細かいバリデーションを行いたい場合は、独自のバリデーションアノテーションを作成する。
## まとめ
今回は、ConstraintValidatorがあるところでRuntimeExceptionの例外をスローすると、本来のConstraitValidator側で処理しきれずRuntimeExceptionになっていたようです。
今回はアノテーションで処理せずカスタムバリエーションを使用したかったので少し悩みました。
Spring Booのバリデーションエラーの処理では、ConstraintValidator内でRuntimeExceptionをスローしないことが解決の鍵でした。ご参考になれば幸いです。
【推論#01】ONNXモデルって何？CPUでもできるAI推論の基本をわかりやすく解説

**前書き**
- 推論に興味がわいたので、手を出してみようと思い備忘録として記事を書いています
- 専門家ではないので、誤った情報を書いている可能性があります
- おそらく複数の記事にまたがるので、本記事は #推論01 とします

## そもそも「推論」とは
ざっくりと言ってしまえば、**「何かの情報をもとにして結論を出すこと」**

### もっと具体的にいうと
- **人間の場合の推論**
  例えば、「空が暗くなってきた」→「雨が降りそうだな」って考える
  つまりは観察（空が暗い）から、結論（雨が降りそう）を導き出しすこと

- **AIや機械学習での推論**
  学習済みのモデルに入力データを与えて、**答えや予測を出すこと**が「推論」
  例えば、猫か犬かを判定するAIモデルがあったとして、「これは猫の画像ですよ〜」って答えてくれるイメージ

---

### 機械学習の流れの中では
1. **学習（トレーニング）**：データを使ってAIモデルを鍛える
2. **推論（インファレンス）**：鍛えたモデルで、未知のデータに対して予測や判断をする

---

### 補足
- 英語では「**Inference（インファレンス）**」という
- AIがリアルタイムで動くとき、実際に何か判断している部分が「推論エンジン」とか呼ばれることもある

---
## 用語と基本構造を理解する
ポイントとなるのは主に以下の５つ
- モデル
- 推論
- フレームワーク
- モデル形式
- 全体構造と流れ

ざっくりとそれぞれ項目ごとにまとめていく

---

## １．モデルとは？

> モデル = 「学習済みのAIの知識」を詰め込んだファイル（もしくは構造）

### イメージ
- 人間でいうと「経験や知識」
- 入力（例：画像）を受け取り、出力（例：猫と判断）を返す
- 中には多数の「**重み（重みづけ）**」や「**層（layer）**」が入っている

---

## ２．推論とは？

> 推論（Inference）＝ 学習済みモデルを使って「答えを出す」処理

### イメージ
- すでに学習済みのモデルに画像を渡して、
  - 「これは猫」
  - 「これはクルマ」
  - 「この数字は“5”」
- という風に「予測」させる

---

## ３．フレームワークとは？

> モデルを作ったり動かすための「道具・ライブラリ」

### 主な例

| フレームワーク名 | 用途 |
|------------------|------|
| **PyTorch** | 学習・推論どちらも対応。人気No.1 |
| **TensorFlow** | Google製の学習フレームワーク |
| **ONNX Runtime** | 推論専用。特にONNX形式に特化（軽量） |

### 補足：推論エンジンとは？
- モデルをCPUやGPUで実際に動かすための仕組み・ライブラリ
- フレームワークで作成したモデルを「動かす役目」をしてくれる

---

## ４．モデル形式とは？

> モデルを保存する「ファイルの形式」のこと

### よくある形式とその特徴

| 形式 | 元 | 用途 | 拡張子 |
|------|----|------|--------|
| `.pt`, `.pth` | PyTorch | 学習・保存 | 学習向け |
| `.pb` | TensorFlow | 保存 | モデルの保存 |
| `.onnx` | ONNX形式 | **汎用的な推論**に使える | 推論向け・軽量 |

### ONNX形式のメリット
- いろんなツールで共通して扱える
- 軽い、最適化しやすい
- CPU/GPU/アクセラレータでも動かせる

---

## ５．全体の構造と流れ

```text
Step 1: モデルを用意（学習済みのONNXファイルなど）
    ↓
Step 2: 入力（画像など）をモデルに渡す
    ↓
Step 3: モデルが推論（予測）を実行
    ↓
Step 4: 出力結果を受け取る（例：猫 98%）
```

---
## まとめ（超ざっくり）

| 用語 | 意味 |
|------|------|
| モデル | AIの判断ロジック（中に重みなどが入ってる） |
| 推論 | モデルに入力を渡して答えを出してもらう |
| フレームワーク | モデルを作ったり使ったりする道具 |
| ONNX | モデルの共通ファイル形式 |
| 推論エンジン | モデルをCPU/GPUで動かすソフト（ONNX Runtimeなど） |

---

次回([推論#02](https://qiita.com/Reotech/items/b9f3fa8a6435b660836a))はメジャーなモデルについて記事を書こうと思います
CompTIA Security+ の受験記

# はじめに

2025年03月に、CompTIA Security+（SY0-701）に一発合格できましたので、受験を検討されている方に向けて簡単に受験記を残します！

# 筆者はどんな人？

- 情報系大学卒
- SIer勤務の社会人歴7年目
    - 1~3年目: ネットワーク機器の保守・運用
    - 3年目以降: セキュリティサービスに関する研究開発など
- 受験歴
    - 2018年10月: 基本情報技術者試験 合格
    - 2022年10月: 応用情報技術者試験 不合格
    - 2023年04月: 応用情報技術者試験 不合格
    - 2024年03月: 情報セキュリティマネジメント試験 合格
    - 2024年10月: 情報処理安全確保支援士試験 合格
    - 2025年03月: CompTIA Security+ 合格🆕


# 学習方法

先人の方々と同様にTACのWeb模擬試験コース（リテイクチケット付）を申し込んで学習しました。
この模試を繰り返し取り組み、分からない点を解消していけば合格することは難しくないと思います。
特にパフォーマンスベースドテストは入念に学習することをお勧めします。

https://ec.tac-school.co.jp/products/course.php?category_id=29119

TAC以外の補助教材としてUdemyで以下のコースを購入しました。
試験範囲の用語を理解する一助になるかと思います。
（一方で繰り返しにはなりますが、試験の合格を目指すだけであればTACの模試だけでも問題ないと思います）

https://www.udemy.com/course/comptia-701/?couponCode=ST11MT170325G2

続いて、受験までのスケジュールと学習の記録を以下に記します。

## スケジュール

- 2025-02-25: TAC e受付申し込み
- 2025-02-28: 会員証到着・学習開始
- 2025-03-15: 受験

## 学習記録

### 模擬試験 第1回

| 実施回数 | 実施時間 | 得点 | 
| ---- | ---- | ---- |
| 1回目 | 00:43:22 | 73 / 90 | 
| 2回目 | 00:14:09 | 88 / 90 |
| 3回目 | 00:27:33 | 88 / 90 |

### 模擬試験 第2回

| 実施回数 | 実施時間 | 得点 | 
| ---- | ---- | ---- |
| 1回目 | 00:33:47 | 73 / 90 | 
| 2回目 | 00:15:55 | 90 / 90 |

### パフォーマンスベースドテスト対策

| 実施回数 | 実施時間 | 得点 | 
| ---- | ---- | ---- |
| 1回目 | 00:01:57 | 8 / 10 | 

# 受験当日

今回は新宿のテストセンターで受験しました。
試験時間は90分で問題数は最大で90問とのことでしたが、私が受験した試験においては77問だったかと思います。
簡単な問題については1問あたり10秒程度で回答し、多少悩む問題については後から見返せるようにフラグを付けて解き進めました。
全ての問題を一通り回答した後に、フラグを付けた問題（約10問）を解きなおし、残り時間40分くらいの時点で試験を終了しました。
試験を終了すると直ちに画面上に結果が表示され、780点で無事に合格することができました。

# おわりに

簡単ですが今回はCompTIA Security+の受験記でした！
この記事の執筆と並行してSecurity+の上位資格にあたるCySA+の学習を進めつつあるので、順調にいけば次はCySA+の受験記を投稿できればと思います！
物分かりの悪い生徒と例え話の上手な教授


生徒「先生、AIって何ですか？」

教授「良い質問ですね。AI（人工知能）というのは、人間のように考えたり学んだりするコンピューターの技術のことなんですよ。」

生徒「え？コンピューターって、ただ計算するだけじゃないんですか？」

教授「確かに、昔のコンピューターは計算するだけでした。でも、今のAIは『考える』ことができるんです。例えば、あなたが料理のレシピを覚えていく過程を想像してみてください。最初は料理を一から学ぶけど、だんだんと簡単な料理から難しい料理へと進めるようになりますよね？AIも同じように、データを使って少しずつ『賢くなる』んですよ。」

生徒「なるほど。でも、AIが賢くなるってどういうことですか？」

教授「いいですね。AIはデータを使って学習するんです。例えば、AIにたくさんの写真を見せて、その中から猫を見つけるように教えると、AIは猫を認識する能力を身につけます。最初は間違えるかもしれませんが、だんだんと精度が上がっていきます。これを教師あり学習と言うんですよ。」


---

生徒「でも、AIは本当に人間みたいに考えるんですか？」

教授「それはね、完全には人間のように考えるわけじゃないんです。AIは人間の脳を真似て作られたニューラルネットワークという仕組みを使っているんですが、それでもまだまだ『人間らしさ』には程遠いんです。」

生徒「じゃあ、AIは頭がいいわけじゃないんですね？」

教授「そう言えるかもしれませんが、AIは特定のタスクで非常に優れた能力を発揮するんですよ。たとえば、膨大なデータを素早く処理したり、パターンを見つけたりするのは得意です。だから、医療分野や金融分野ではすでに活躍しているんです。」


---

生徒「AIにはどんな種類があるんですか？」

教授「良い質問ですね。AIにはいくつかの種類があります。まず、特化型AI（Narrow AI）というのは、特定の仕事だけをこなすAIです。たとえば、音声認識や画像認識などですね。」

生徒「それって、なんか便利そうですね！」

教授「そうなんです！そして、汎用AI（AGI）というのは、人間のようにいろんなことができるAIを指します。でも、これはまだ研究段階です。未来の話ですね。」

生徒「すごい！じゃあ、AIが進化していったら、もっと便利になるんですね！」

教授「その通りです。しかし、進化すると同時に、注意が必要な点も増えてくるんですよ。」


---

生徒「どうして注意が必要なんですか？」

教授「AIが進化すればするほど、バイアス（偏見）や不正確な判断をするリスクも増えてくるんです。例えば、AIが学ぶデータに偏りがあると、それを元に不公平な判断をしてしまうことがあります。」

生徒「それって、怖いですね…」

教授「はい、だからこそAIにはしっかりとしたルールやガイドラインが必要なんです。たとえば、AI倫理という分野が今注目されています。」


---

生徒「じゃあ、AIって未来にどうなっていくんですか？」

教授「AIの未来は、非常に興味深いものです。例えば、パーソナルアシスタントとして、もっと賢くなり、個々の生活に合わせてサポートしてくれるAIが登場するでしょう。また、医療の分野では、AIが病気を診断したり、適切な治療法を提案したりすることが期待されています。」

生徒「それなら、AIってすごいですね！」

教授「ええ、しかし、AIの進化には責任を持った使い方が大切です。人間とAIがうまく協力できる未来を目指して、みんなで考えながら進んでいく必要があります。」


---

生徒「AIってすごいけど、注意も必要なんですね。」

教授「その通り！AIが進化することで、私たちの生活はもっと便利になり、いろんな問題も解決できるようになるでしょう。ただ、そのためにはAIをどう使うか、私たち人間の責任が問われる時代になるでしょう。」

生徒「わかりました！AIの未来、楽しみですね！」

教授「うむ、私も楽しみにしていますよ。」
AIの仕組みから最前線の技術、未来への展望まで

近年、AI（人工知能）は急速に進化し、私たちの生活や仕事に大きな影響を与えています。本記事では、AIの基本概念から最新の技術動向、倫理的課題、そして未来の可能性について、わかりやすく解説します。


---

1. AIとは？基本概念を理解する

AI（Artificial Intelligence）は、「人間の知的活動をコンピューター上で再現する技術」です。AIにはさまざまな種類があり、大きく以下の3つに分類できます。

1. 特化型AI（Narrow AI）

画像認識や翻訳、音声アシスタントなど、特定のタスクに特化したAI。現在のほとんどのAIはこれに該当。



2. 汎用AI（AGI: Artificial General Intelligence）

人間と同等、もしくはそれ以上の知能を持ち、多様なタスクをこなせるAI。まだ研究段階。



3. 超知能AI（ASI: Artificial Super Intelligence）

人間の知能を超えたAI。理論的には可能とされるが、実現の見込みは不明。





---

2. AIの仕組みと主要技術

(1) 機械学習（Machine Learning）

AIがデータからパターンを学習し、予測や判断を行う技術。代表的な手法には以下がある。

教師あり学習（例：スパムメール判定）

教師なし学習（例：顧客のクラスタリング）

強化学習（例：囲碁AI AlphaGo）


(2) 深層学習（Deep Learning）

機械学習の一種で、ニューラルネットワークを多層構造にしたもの。画像認識、音声認識、自然言語処理などに活用される。

例：GPT-4（OpenAI）、Gemini（Google DeepMind）、Claude（Anthropic）


(3) 生成AI（Generative AI）

文章、画像、音楽などを自動生成するAI。

ChatGPT（テキスト生成）

SORA（動画生成）

Midjourney, Stable Diffusion（画像生成）



---

3. 最新のAI技術とトレンド

近年のAIの進化は目覚ましく、特に以下の分野で急速に発展しています。

(1) マルチモーダルAI

画像・音声・テキストなど、複数の情報を統合して理解するAI。

例：GPT-4 Turbo（OpenAI）、Gemini 1.5（Google DeepMind）


(2) AIの自律性の向上

AutoGPTやAgentGPTのように、自己判断で複数のタスクを遂行するAIエージェントが登場。


(3) AIとロボティクスの融合

TeslaのOptimusやBoston DynamicsのAtlasなど、AIを活用した自律型ロボットが開発中。


(4) AIの安全性とガバナンス

EUの「AI法」、米国の「AI規制案」など、各国でAIの倫理や規制が進む。



---

4. AIのリスクと課題

(1) バイアスと公平性の問題

AIは学習データの偏りによって差別的な判断をすることがある。（例：採用AIの偏り）

(2) ディープフェイクと情報操作

生成AIを悪用し、フェイクニュースや偽映像が拡散するリスクが高まっている。

(3) AIによる雇用の変化

単純労働だけでなく、ホワイトカラー職でもAIに代替される可能性がある。


---

5. AIの未来と可能性

パーソナルAIアシスタントの進化（生活全般をサポートするAIの普及）

医療AIの発展（診断・創薬・ロボット手術）

宇宙開発への活用（NASAのAI活用による探査機の自律運用）



---

まとめ

AIは今後も急速に進化し、私たちの生活やビジネスに大きな影響を与えます。一方で、リスクや倫理的課題にも注意が必要です。AIの仕組みや最新技術を理解し、上手に活用することが重要です。
連載 [第7回] :AI・機械学習の最新トレンドと実装 | Edge AI vs Cloud AI：どちらを選ぶべきか？

## **🌐 Edge AI vs Cloud AI：どちらを選ぶべきか？ 🤖⚡️**  

こんにちは、AI技術に興味のある皆さん！  
最近、「**Edge AI（エッジAI）**」と「**Cloud AI（クラウドAI）**」という言葉をよく耳にしませんか？  

- **Edge AI** → デバイス上でAIを処理！（ローカル処理）  
- **Cloud AI** → クラウドサーバーでAIを処理！（オンライン処理）  

どちらも強力な技術ですが、「**結局どっちを使うのがいいの？**」と迷う方も多いはず。  

本記事では、**Edge AIとCloud AIの違い・メリット・デメリット・使い分け** をわかりやすく解説します！💡✨  

---

## **📌 Edge AIとCloud AIの基本**  

### **🌟 Edge AIとは？（エッジAI）**  
「**デバイス上でAIを動かす技術**」のこと。  
データをクラウドに送信せずに、**その場で処理** するのが特徴です。  

📌 **使用例**  
✅ スマートフォンの顔認識（iPhoneのFace ID）  
✅ 自動運転車のリアルタイム判断  
✅ 工場の品質検査（カメラ＋AIで不良品を判別）  
✅ スマート家電（音声認識や画像解析）  

🎯 **「リアルタイム処理が必要な場面」に最適！**  

---

### **☁️ Cloud AIとは？（クラウドAI）**  
「**クラウド上でAIを処理する技術**」のこと。  
大量のデータをクラウドに送信し、**強力なサーバーでAIを実行** するのが特徴です。  

📌 **使用例**  
✅ ChatGPTのような大規模言語モデル（LLM）  
✅ Google Photosの画像検索（クラウドで顔やモノを認識）  
✅ AIを活用したビッグデータ分析  
✅ クラウドベースの音声アシスタント（Alexa, Google Assistant）  

🎯 **「膨大なデータを処理する場面」に最適！**  

---

## **🎯 Edge AI vs Cloud AIの比較表**  

|  | **Edge AI** | **Cloud AI** |
|---|---|---|
| **処理場所** | デバイス上 | クラウドサーバー |
| **リアルタイム性** | 高い（遅延なし） | 低い（ネット接続が必要） |
| **データの安全性** | 高い（ローカル処理） | 低い（データ送信が必要） |
| **コスト** | デバイス性能に依存 | サーバー利用料がかかる |
| **スケーラビリティ** | 低い（デバイスごとに処理能力が異なる） | 高い（大規模データ処理が可能） |
| **主な用途** | 自動運転・IoT・スマートデバイス | 大規模AIモデル・クラウドサービス |

---

## **📌 Edge AIのメリット・デメリット**  

### ✅ **メリット**  
✔ **リアルタイム処理が可能（遅延ゼロ！）**  
✔ **データのプライバシー保護（ローカル処理のみ）**  
✔ **通信コストがかからない（オフライン動作OK！）**  
✔ **低消費電力（クラウドのサーバーコスト不要）**  

### ❌ **デメリット**  
❌ **デバイス性能に依存（高性能なチップが必要）**  
❌ **大規模データ処理が苦手（計算リソースに限界あり）**  
❌ **モデルのアップデートが難しい（デバイスごとに更新が必要）**  

---

## **☁️ Cloud AIのメリット・デメリット**  

### ✅ **メリット**  
✔ **大規模なAIモデルを使える（GPT-4.5, Claude 3 など）**  
✔ **計算リソースが豊富（超高性能サーバーが使える）**  
✔ **データの統合・学習が簡単（機械学習の継続的なアップデートが可能）**  

### ❌ **デメリット**  
❌ **インターネット接続が必要（通信遅延が発生する可能性あり）**  
❌ **データのプライバシーリスク（クラウド上に情報を送る必要がある）**  
❌ **コストがかかる（クラウド利用料、APIコール課金）**  

---

## **🚀 どちらを選ぶべき？【用途別おすすめ】**  

### **1️⃣ リアルタイム処理が必要なら… → Edge AI**  
📌 例：自動運転、監視カメラ、スマートデバイス  
✅ **理由：** オフラインでも即時処理できるから！  

### **2️⃣ 大規模なAIモデルを活用するなら… → Cloud AI**  
📌 例：ChatGPT、画像生成AI（DALL·E）、データ分析  
✅ **理由：** 膨大なデータを処理し、高性能な計算が必要だから！  

### **3️⃣ ハイブリッド型もアリ！**  
最近は、**「Edge AI + Cloud AI」** を組み合わせたシステムも増えています。  

📌 例えば…  
✅ **スマートフォン** → 顔認識（Edge AI）＋ クラウドでデータ同期（Cloud AI）  
✅ **監視カメラ** → 異常検知（Edge AI）＋ クラウドでデータ分析（Cloud AI）  

🎯 **「リアルタイム処理」と「クラウドの高性能計算」を組み合わせるのが最適！**  

---

## **📝 まとめ**  

✔ **Edge AI → 「リアルタイム処理」「データの安全性」を重視するなら◎**  
✔ **Cloud AI → 「高性能な計算」「大規模データ分析」が必要なら◎**  
✔ **ハイブリッド運用も可能 → 「両方のメリットを活かす」**  

AI技術は日々進化しており、これからもEdge AIとCloud AIの境界が曖昧になっていくでしょう。  
「**自分のプロジェクトにどちらが適しているのか？**」を考えながら、最適な選択をしてください！🚀✨  

---

## **🔜 次回予告：「ChatGPT・Gemini・Mistral AIのカスタマイズ方法【実践ガイド】」**  

📢 Edge AIを実際に動かしてみたい方は、次回の投稿をお楽しみに！  
フォロー＆コメントでリクエストもお待ちしています！👋😃
連載 [第6回] :AI・機械学習の最新トレンドと実装 | Stable Diffusion・Midjourney・DALL·E 3の違いを徹底解説！

## **🎨 Stable Diffusion・Midjourney・DALL·E 3の違いを徹底解説！🖼️✨**  

こんにちは、AIアートに興味のある皆さん！  
最近、**AI画像生成** の技術が急速に進化し、**「テキストを入力するだけで高品質な画像を生成」** できるツールが続々と登場しています。  

特に人気のあるのが、  
- **Stable Diffusion** 🏞️（オープンソース、カスタマイズ可能！）  
- **Midjourney** 🌅（美しいアートスタイルが得意！）  
- **DALL·E 3** 🎭（精密な画像生成が可能！）  

ですが…「どれを使えばいいの？」と迷っている方も多いはず！  

今回は、これら3つの画像生成AIの**違い・特徴・用途別のおすすめ** をわかりやすく解説します！💡🚀  

---  

## **🎨 まず、AI画像生成って何？**  

AI画像生成とは、**「テキストの指示（プロンプト）」** を入力すると、AIがそれに基づいた画像を作り出す技術です。  
例えば、「夕焼けの海に浮かぶネオンの街」と入力すると…  

🔹 **AIがそのイメージを理解し、画像をゼロから生成！**  

この技術は、イラスト制作、広告デザイン、ゲーム開発など、**さまざまな分野で活用** されています。  

では、Stable Diffusion・Midjourney・DALL·E 3のそれぞれの特徴を詳しく見ていきましょう！ 👇  

---  

## **🖼️ Stable Diffusion：完全カスタマイズ可能なオープンソース！**  

### ✅ **特徴**  
✔ **完全無料＆オープンソース**（誰でも使える！）  
✔ ローカルPCで動作可能（GPUが必要）  
✔ **プロ向けの細かい調整が可能**（モデルのカスタム、LoRA、ControlNetなど）  
✔ **プライバシーを重視**（データが外部に送信されない）  

### ⏳ **向いている用途**  
✅ **イラスト・アート制作（独自スタイルの画像を作れる）**  
✅ **NSFW（規制のない自由な創作）**  
✅ **ローカル環境での運用（企業向け、データ漏洩防止）**  

### ⚠ **デメリット**  
❌ **セットアップが難しい（初心者にはハードル高め）**  
❌ **高性能なGPUが必要（スペックが低いPCでは動作が重い）**  

💡 **「自分好みの画像を作りたい！」というクリエイターや上級者におすすめ！**  

---

## **🎨 Midjourney：美しいアート生成に最適！**  

### ✅ **特徴**  
✔ **独特の美しいアートスタイル（まるでプロの作品！）**  
✔ **テキスト入力だけで高品質な画像を作成（初心者向け！）**  
✔ **公式のDiscord上で簡単に操作可能**  

### ⏳ **向いている用途**  
✅ **アート・ファンタジーイラスト**（ポスター、ゲーム、コンセプトアート）  
✅ **デザイン系の仕事（広告・ブランディング・ファッション）**  
✅ **SNS・ブログのビジュアル作成**  

### ⚠ **デメリット**  
❌ **商用利用には有料プランが必要（月額10ドル〜）**  
❌ **カスタマイズの自由度が低い（細かい設定はできない）**  
❌ **ローカルで動作しない（必ずオンライン環境が必要）**  

💡 **「美しいアートを手軽に作りたい！」というデザイナー・アーティスト向け！**  

---

## **🎭 DALL·E 3：リアルで精密な画像生成！**  

### ✅ **特徴**  
✔ **ChatGPTとの連携が可能（プロンプト作成も簡単！）**  
✔ **リアルな写真風の画像を生成できる**  
✔ **画像の編集・修正機能（Inpainting）に対応**  

### ⏳ **向いている用途**  
✅ **リアルな商品イメージ・写真風の生成**（広告、Eコマース）  
✅ **精密なデザイン・イラスト制作**（キャラクターやプロダクトデザイン）  
✅ **文章からイメージを作る作業（アイデアスケッチ、ストーリーボード）**  

### ⚠ **デメリット**  
❌ **商用利用には制限がある（OpenAIの利用規約に準拠）**  
❌ **カスタマイズ性が低い（独自モデルの追加は不可）**  
❌ **無料版では生成枚数に制限あり**  

💡 **「プロンプトだけで簡単にリアルな画像を作りたい！」という人におすすめ！**  

---

## **📊 3つのAI画像生成ツールの比較表**  

|  | **Stable Diffusion** | **Midjourney** | **DALL·E 3** |
|---|---|---|---|
| **特徴** | 完全無料・カスタマイズ可能 | 美しいアート向け | 精密な画像生成 |
| **動作環境** | ローカルPC | Discord（オンライン） | OpenAI（オンライン） |
| **カスタマイズ性** | 高い（モデル変更可） | 低い（指定スタイルのみ） | 低い（モデル変更不可） |
| **生成画像の特徴** | 独自スタイル、アニメ調も可能 | アート寄り、美しいビジュアル | リアルで精密な画像 |
| **商用利用** | 可能（ライセンス次第） | 有料プランが必要 | 一部制限あり |
| **向いている人** | クリエイター・上級者 | デザイナー・アーティスト | ビジネス・マーケティング担当 |

---

## **🛠 どれを選ぶべき？**  

**📢 どのツールがベストかは、用途によって変わります！**  

- **💻 自分好みのAIアートを作りたい → Stable Diffusion**  
- **🎨 直感的に美しいイラストを作りたい → Midjourney**  
- **📷 高精度な写真風画像を作りたい → DALL·E 3**  

もし「**どれを使うか迷っている…**」という方は、まず **Midjourney** や **DALL·E 3** を試してみるのがおすすめ！  
「**もっと細かくカスタマイズしたい！**」と感じたら、Stable Diffusionに挑戦するのもアリです！💪✨  

---

## **🎯 まとめ**  

✔ **Stable Diffusion** → **カスタマイズ性◎、プロ向け、ローカル動作OK**  
✔ **Midjourney** → **美しいアート◎、初心者向け、手軽に使える**  
✔ **DALL·E 3** → **リアルな画像◎、精密なデザイン向け**  

---

## **🔜 次回予告：「Edge AI vs Cloud AI：どちらを選ぶべきか？」**  

📢 AI画像生成のプロンプトテクニックを詳しく知りたい方は、ぜひフォロー＆コメントでリクエストしてください！💡✨  

それでは、また次回！👋🚀
AIプロジェクトにおける要件定義の方法：徹底ガイド


## **1. なぜAIプロジェクトの要件定義が重要なのか？**
AIプロジェクトは、従来のシステム開発とは異なり、「データ駆動型」であることが特徴です。そのため、**要件定義を誤ると、AIモデルが期待した性能を発揮できず、ビジネス価値を生まないプロジェクトになってしまう** ことがあります。

**要件定義が甘いと発生する問題**
- AIの目的が曖昧で、業務改善に貢献しない
- 必要なデータが足りず、モデルの精度が上がらない
- 運用フェーズを考慮せず、AIが実際に活用されない

成功するAIプロジェクトのためには、「**要件定義の精度を高めること**」が重要です。本記事では、AIプロジェクトにおける要件定義の進め方を、具体的な手順とポイントを交えて解説します。

---

## **2. AIプロジェクトの要件定義の進め方**
要件定義は、次の6つのステップで進めます。

1. **ビジネスゴールの明確化**
2. **業務プロセスの整理**
3. **データ要件の定義**
4. **モデルの要件定義**
5. **システム連携と運用要件の整理**
6. **評価指標（KPI）の設定**

---

## **3. AIプロジェクトの要件定義ステップ**
### **ステップ1：ビジネスゴールの明確化**
#### **📌 目的**
- AIを導入することで「何を解決するのか」を明確にする
- 経営層や業務担当者と共に、期待する成果を具体化する

#### **✅ 具体的な手順**
1. **現在の業務課題を特定**
   - 例：カスタマーサポートの対応時間が長い → チャットボットで自動化したい
   - 例：マーケティングのターゲティング精度が低い → AIで顧客セグメンテーションを改善

2. **AI導入の目的を定義**
   - 目的は「**コスト削減、売上向上、業務効率化、品質向上**」など、具体的にする
   - 例：「カスタマー対応の時間を30%短縮する」などの定量目標を設定

3. **関係者の意見を収集**
   - 経営層、業務担当者、エンジニア、データサイエンティストが合意形成する

---

### **ステップ2：業務プロセスの整理**
#### **📌 目的**
- AIを導入する業務の流れを整理し、どこに適用するかを決める

#### **✅ 具体的な手順**
1. **業務フローの可視化**
   - フローチャートを作成し、業務の流れを明確にする
   - どの部分をAIが担当し、どこを人間が担当するのか決める

2. **AI導入前後の比較**
   - AI導入後の業務改善イメージをシミュレーションする

3. **業務要件の決定**
   - 例：「問い合わせ分類をAIが行い、オペレーターが対応する流れに変更」

---

### **ステップ3：データ要件の定義**
#### **📌 目的**
- AIが学習・推論に必要なデータを明確にし、データの質・量をチェックする

#### **✅ 具体的な手順**
1. **利用可能なデータの洗い出し**
   - どのデータを使うのか（社内データ、外部データ、オープンデータ）
   - データのフォーマット（CSV、JSON、画像、動画など）

2. **データの前処理要件**
   - 欠損値の処理方法
   - アノテーション（教師データのラベル付け）の有無
   - データのノイズ除去

3. **データ収集・更新の方針**
   - 定期的にデータを収集するのか？
   - AIがリアルタイムで学習する仕組みを作るのか？

---

### **ステップ4：モデルの要件定義**
#### **📌 目的**
- どのようなAIモデルを使うのか、どの程度の精度を求めるのかを定義

#### **✅ 具体的な手順**
1. **モデルの種類を選定**
   - 画像認識？自然言語処理？異常検知？（タスクの種類を明確化）
   - 例：チャットボットなら「GPT系」、異常検知なら「教師なし学習モデル」

2. **モデルの精度要件**
   - 例：「AIの誤検知率を5%以下にする」「F1スコア0.85以上を目指す」

3. **モデルの処理速度要件**
   - 例：「推論時間を1秒以内にする」

4. **カスタマイズの範囲**
   - 事前学習済みモデルを使うか？それともゼロから学習するか？

---

### **ステップ5：システム連携と運用要件の整理**
#### **📌 目的**
- AIモデルをどのようにシステムに統合するか、運用面の要件を決める

#### **✅ 具体的な手順**
1. **システムアーキテクチャの決定**
   - AIモデルはクラウドで動作するのか？オンプレミスなのか？
   - APIで提供するのか？バッチ処理で動かすのか？

2. **運用・保守要件**
   - AIの精度が劣化したときにどう対処するか？
   - モデルの再学習の頻度（例：週1回、月1回）

3. **セキュリティ・ガバナンス**
   - GDPRやCCPAなどの規制対応
   - ユーザーのプライバシーデータの取り扱い方針

---

### **ステップ6：評価指標（KPI）の設定**
#### **📌 目的**
- AIプロジェクトが成功したかどうかを測定する指標を決める

#### **✅ 具体的な手順**
1. **技術的指標**
   - 精度（Accuracy）
   - 適合率（Precision）・再現率（Recall）
   - 推論時間（Latency）

2. **ビジネス指標**
   - コスト削減率
   - 顧客満足度（NPSスコア）
   - 業務時間の短縮率

3. **KPIの設定**
   - 例：「問い合わせ分類の精度を80%以上にする」
   - 例：「AI導入でカスタマー対応時間を20%削減する」

---

## **4. まとめ**
AIプロジェクトの要件定義では、**技術面だけでなく、ビジネス視点、業務フロー、データ品質、運用要件を包括的に検討することが重要** です。適切な要件定義を行うことで、**現場で活用されるAIを開発し、ビジネス価値を最大化** できます。
プログラム入門：VS Code の code コマンドが使えないときの対処法について解決してみた

## **はじめに**

VS Code の `code` コマンドは、ターミナルから VS Code を簡単に起動できる便利な機能です。

:::note warn
**しかし、`code .` を実行した際に「command not found」と表示されることがあります。**
:::

本記事では、その原因と解決策を詳しく解説します。

---

## **問題: ****`code`**** コマンドが見つからない**

ターミナルで `code .` を実行したときに、以下のようなエラーが表示されることがあります。

```
 ~/Desktop/VScode   code .
zsh: command not found: code
```

このエラーは、**VS Code のコマンドラインツール (CLI) がインストールされていない、またはパスが設定されていない** ことが原因です。

---

## **解決策 1: VS Code の CLI ツールをインストール**

VS Code の `code` コマンドを使うためには、CLI ツールをインストールする必要があります。

### **手順:**

1. **VS Code を開く**
2. メニューバーの **View** → **Command Palette...** (`⌘ + Shift + P`)
3. `Shell Command: Install 'code' command in PATH` を検索し、実行
4. ターミナルを再起動し、以下のコマンドで動作確認
   ```zsh
   code --version
   ```

これで `code` コマンドが認識されるようになるはずです。

**実行後の画面**

![Screenshot 2025-03-19 at 12.12.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/989bad39-aa4d-40fa-8ca6-cf031ed4788f.png)

---

## **解決策 2: ****`code`**** コマンドのパスを確認**

`code` コマンドが正しくインストールされているかを確認するには、以下のコマンドを実行します。

```zsh
which code
```

何も表示されない場合は、`code` コマンドがパスに通っていない可能性があります。

**実際のターミナル画面**

![Screenshot 2025-03-19 at 12.23.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/368e93a7-85a1-4fbc-a81b-646eaa9b9dbc.png)


---

## **解決策 3: 手動でパスを設定する**

`code` コマンドの実行ファイルが `/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code` にある場合、`~/.zshrc` にパスを追加して手動で設定できます。

### **手順:**

1. `.zshrc` に以下を追加

   ```zsh
   export PATH="$PATH:/Applications/Visual Studio Code.app/Contents/Resources/app/bin"
   ```

2. 設定を反映

   ```zsh
   source ~/.zshrc
   ```

3. 再度、`code .` が動作するか確認

   ```zsh
   code .
   ```

---

## **解決策 4: ターミナルを再起動する**

上記の設定を適用した後、**ターミナルを閉じて再度開き、試してみてください。**

## **まとめ**

- **VS Code の CLI ツールをインストールする**（一番簡単）
- **`which code`**** でパスを確認**
- **必要なら ****`~/.zshrc`**** に ****`export PATH`**** を追加**
- **ターミナルを再起動して ****`code .`**** を試す**
- **それでもダメなら Homebrew で再インストール**

これで `code` コマンドが動作するはずですので、試してみてください！
Mac Studioでollamaのdeepseek-r1:671bを動かしてみた

# 背景・目的

- Mac StudioのM3 Ultraが発売された。512GBのメモリを積んでいる
- [ollamaのdeepseek-r1:671b](https://ollama.com/library/deepseek-r1:671b)は4bit量子化版で404GBある
- 動くかを試してみた

# 結論

- 動いた
- OLLAMA_KEEP_ALIVEを長くしつつ、GPUが利用可能なメモリサイズの変更が必要だった

# ollamaのdeepseek-r1について

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144584/ce476b8b-785f-4b27-967c-1a3af6fa5340.png)

上記の画像のように、蒸留版(1.5b ~ 70b)と蒸留なしのモデルが提供されている。
512GBのメモリを積んだMacなら671bのモデルを動かせるのでは？と思い試してみた。

# 初期設定だとエラー

```bash
$ ollama run deepseek-r1:671b
Error: llama runner process has terminated: signal: killed
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144584/790899ad-3447-4bf4-b463-b47ae7efd761.png)

360GB ~ 380GBぐらいまでメモリに乗ったところで、上記のようにプロセスが死んでしまった。

MacのユニファイドメモリはGPUに割り当てられるメモリの最大上限値があるためかと思われる。2/3か3/4か

# 設定を変更して試す

```bash
$ sysctl iogpu.wired_limit_mb
iogpu.wired_limit_mb: 0 
$ sudo sysctl iogpu.wired_limit_mb=450000
Password:
iogpu.wired_limit_mb: 0 -> 450000
```

上記の設定をして動かしてみても、同様のエラーになってしまった。

```bash
time=2025-03-19T11:27:46.038+09:00 level=INFO source=server.go:619 msg="waiting for server to become available" status="llm server loading model"
time=2025-03-19T11:28:57.051+09:00 level=INFO source=server.go:619 msg="waiting for server to become available" status="llm server not responding"
time=2025-03-19T11:29:06.342+09:00 level=ERROR source=sched.go:456 msg="error loading llama server" error="llama runner process has terminated: signal: killed"
```

調べてみたところ、[OLLAMA_KEEP_ALIVE](https://github.com/ollama/ollama/blob/main/docs/faq.md)の時間を長くすれば解決する可能性があるとのことなので以下を設定

```bash
export OLLAMA_KEEP_ALIVE=-1
```


# 動いた

```bash
$ ollama run deepseek-r1:671b
>>> 富士山の高さは？
<think>
嗯，用户问的是“富士山的高さは？”也就是富士山的海拔高度是多少。首先得确认正确的数据，因为可能有不同的资料来源会有细微差别。

日本国土地理院是权威机构，他们的测量结果应该是最准确的。记得之前查过资料，富士山的标高大约是3776米左右。不过最好再核实一下最新的数据有没有变化。

另外要注意的是，有时候不同来源可能会有小数点后的差异或者四舍五入的不同说法，但通常都会以3776米为准。可能还需要提到这是静冈县和山梨县交界处的活火山，以及它是日本最高峰的信息。

用户可能是为了旅游计划、学习地理知识或者写作业需要这个信息，所以回答要简洁明确，同时提供一点相关背景可能会有帮助。
</think>

富士山の標高は**3,776メートル**です。これは日本国内で最も高い山であり、静岡県と山梨県にまたがる活火山（現在は休火山状態）としても知られています。最新の測量データでは小数点以下の数値が付く場合もありますが、一般的には「
3,776m」が公式な数値として広く認知されています🇯🇵🗻
```

動作中のメモリ利用状況は以下

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144584/2b35a758-2988-48b2-a53e-18889a3cb63e.png)

# 参考リンク

https://github.com/ollama/ollama/issues/8571
https://github.com/ollama/ollama/blob/main/docs/faq.md
【備忘録】Jupyter仮想マシンのターミナルでMeCabをインストールしたのに、notebookでMeCabがimportできない問題の原因と解決方法

**MeCabの辞書のパスが見つからない問題は、この記事では解決しません。ご容赦ください...**

【マシン】
Windows

問題はタイトルの通り。

Jupyter のターミナル上でMeCabをインストール完了。
```
$ pip install MeCab
```

そのままターミナルでテストしてみよう。
MeCabを起動して使ってみるぞ。

```
$ Python
> import MeCab
> t = MeCab.Tagger()
> result = t.parse("すもももももももものうち")
> print(result)

すもも  スモモ  スモモ  李      名詞-普通名詞-一般                      0
も      モ      モ      も      助詞-係助詞
もも    モモ    モモ    桃      名詞-普通名詞-一般                      0
も      モ      モ      も      助詞-係助詞
もも    モモ    モモ    桃      名詞-普通名詞-一般                      0
の      ノ      ノ      の      助詞-格助詞
うち    ウチ    ウチ    内      名詞-普通名詞-副詞可能                  0
```

うんうん、ご機嫌な進捗や。

テストもできたことだし、本格的にnotebook上でMeCabをimportして開発していくか。

```
$ import MeCab
ModuleNotFoundError: No module named 'MeCab'
```

**なんでやねん！！！**

ということでいろいろ調べてみたところ、少なくとも私の環境ではJupyterのターミナルで使っているPythonとnotebookで使っているPythonが別々らしい。

```
Jupyterターミナルのコマンドラインにて
$ which Python
alias python='python3'
        ~/anaconda3/bin/python3

一方、notebook上のセルにて
$ import sys
$ print(sys.executable)
/bin/python3
```

である。

<h2>結論: MeCab が動いている Python のパスをJupyter カーネルとしてJupyter に登録した</h2>

<h3>1. ターミナル上で、Pythonのパスを確認</h3>

```
ターミナル上にて
$ which python
```

これで、MeCab が動いている Python のパスが分かります。

<h3>2. Jupyter にその環境をカーネルとして登録</h3>

```
同じくターミナル上にて
$ pip install ipykernel
$ python -m ipykernel install --user --name mecab_env --display-name "Python (MeCab)"
```

これにより、Jupyter Notebook で "Python (MeCab)" というカーネルが選択できるようになります。

<h3>3. Jupyter Notebook でカーネルを変更</h3>
「Kernel」→「Change Kernel」→「Python (MeCab)」を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631758/d8ad9b88-10c4-47d1-9ca3-a21a9d188f74.png)

<h2>本当に使えるようになったか確認</h2>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631758/99f191c2-d6ac-4d82-baa6-17e1cec44e64.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631758/fc8b313e-0916-4d1c-be69-045846629215.png)

**これでOK**
【GitHub Actions × Windows Self-hosted Runner】Git Bashのパス変換でハマった話と解決方法まとめ


## はじめに：この記事でわかること

この記事では、GitHub Actions の Self-hosted Runner（Windows）上で **Git Bash のパス変換による不具合**に遭遇した際の対処方法を、実際の事例ベースでわかりやすく解説します。

「aws s3 cp が突然Segmentation fault！？」「でもLinux runnerでは問題ない…」そんなときの原因とベストプラクティスをまとめました。

---

## 背景と課題：Git Bash の自動パス変換は善か悪か？

Git Bash は Windows 環境でも UNIX ライクな操作を提供してくれる便利ツールですが、一方で **「自動パス変換」という罠**が存在します。

### 例：
```bash
/my/path → C:\my\path 

# 勝手に変換される：
#  (1)ドライブレターC:がつく
#  (2)スラッシュがバックスラッシュに）
```

特に `aws`, `docker`, `kubectl` など **WindowsネイティブのCLI** に引数が渡る場合、この変換が原因で **クラッシュや想定外の動作**を招くことがあります。

---

## 発生した問題・エラーログ：Segmentation faultの正体

### 実際のGitHub Actionsジョブの例：

```yaml
- name: Upload artifacts to S3
  shell: bash
  env:
    ARTIFACT_TOP_PATH: ./tmp
    S3_ARTIFACT_PATH: s3://{target-bucket}/{target-folder}
  run: |
    echo "S3_ARTIFACT_PATH: $S3_ARTIFACT_PATH"
    aws s3 cp $ARTIFACT_TOP_PATH $S3_ARTIFACT_PATH --recursive
```

### エラーログ（一部抜粋）：
```
Segmentation fault      aws s3 cp $ARTIFACT_TOP_PATH $S3_ARTIFACT_PATH --recursive
```

Linux runnerでは発生せず、Windows Self-hosted Runnerでのみ発生 → Git Bashのパス変換が主犯格でした。

---

## 解決方法：MSYS_NO_PATHCONVで自動変換を抑制！

### 対策コード：
```yaml
- name: Upload artifacts to S3
  shell: bash
  env:
    ARTIFACT_TOP_PATH: ./tmp
    S3_ARTIFACT_PATH: s3://{target-bucket}/{target-folder}
  run: |
    export MSYS_NO_PATHCONV=1
    aws s3 cp $ARTIFACT_TOP_PATH $S3_ARTIFACT_PATH --recursive
```

### 解説ポイント：
- `MSYS_NO_PATHCONV=1` を設定することで、Git Bash の「自動パス変換」をオフにできます。
- Git Bash 特有の挙動を無効化し、aws CLI に正しいパスが渡るようになります。

---

## 補足Tips：PATH更新と変換無効化を前処理で自動化

より堅牢な環境整備のため、Windowsランナーかどうかを判定し、PATHを再読み込み＆MSYS_NO_PATHCONVを自動設定する前処理も有効です。

### 実践コード例：
```yaml
- name: Tweaks for Windows Self-Hosted Runners if needed
  shell: bash
  run: |
    echo " === Step 1: Check OS ==="
    if [ "$OS" = "Windows_NT" ]; then
      echo "[IMPORTANT] This is Windows runner. Adding some magic dust now"
      echo " === Step 2: Invalidate Auto PATH translation ==="
      export MSYS_NO_PATHCONV=1
    else
      echo "=== Step [SKIP]: This is not Windows runner."
    fi
```

---

## まとめ：WindowsランナーではMSYS_NO_PATHCONVをデフォルトで使おう！

- Git Bash のパス変換は便利な反面、ネイティブCLIツールと組み合わせるとバグの温床になりやすいです。
- 特に **GitHub Actions の Self-hosted Runner（Windows）** では、`MSYS_NO_PATHCONV=1` をセットしておくのがベストプラクティスです。
- 最初からこの対策を入れておくことで、想定外のクラッシュを未然に防ぐことができます。

---

## 参考リンク
- Qiita記事: [Git Bashでのパス変換問題とMSYS_NO_PATHCONV活用例](https://qiita.com/nannany_stores/items/52c471d7b13bff9b285e)
- AWS re:Post記事：[aws s3 cp が時々セグメンテーション違反をスローする](https://repost.aws/ja/questions/QUFcuXAfemSEutfmYeia60dw/aws-s3-cp-occasionally-throws-segmentation-fault)
【勉強記録】2月の成果


# はじめに
こんにちは。アメリカ在住で独学でエンジニアを目指している taira です。
本日は2月の勉強成果等を記事にしていこうと思います。
2月は勉強時間とても少なく32時間のみでした。

## 2月の目標について
1月の記事に立てた目標についてみていきます。
いつもは毎月の初めに投稿していますが、1カ月ほど日本医一時帰国していたのもあって記事投稿が遅くなりました。

- 一日に1時間は勉強するように努める　未達成
PCを持ち歩く予定だったのですが、一時帰国する前にGitHub Actionsを使用した記事投稿の自動化を思いついたので、友人や妻、両親と出かけたり等いつもできないことに時間を使いました。
あと、脳が勉強モードでないといつも働いているはずの脳みそが動かない感覚でした。不思議ですね。

- 毎日ブログ投稿を続ける　達成
本来はPCを毎日持ち歩いて、記事投稿する予定でしたが前述の通りにGitHub Actionsにより時間が来たら記事投稿、かつXへのpostを行ってくれるように仕組みを作ることができたのが大きいです。

## 2月に新たに始めたこと
- GitHub Actionsを使用してQiitaへの記事投稿とXへの自動ポスト
これについては、自分ナイス思いつきって思いました。おかげさまで日本でとても充実した時間を過ごせましたし、アメリカへ戻ってきてからも、記事を書いてストックしていれば時間になったら自動投稿をしてくれるので、手間がなくなりました。

## 3月の目標
もう3月は始まっているので緩いハードルの目標を設定します

1. 時差ぼけを解消し、一時帰国前の勉強時間に戻す
2. 何か新しい取り組み or マインドセットを生み出す
Rocky8.9にcomposerをインストール

### 概要
サーバー設定する時に、作業者から「Composer」入れておいてもらえます？って言われるようになった💦

**「Composer」は、関数やクラスなど便利な機能がすでに実装されている機能のまとまり（パッケージライブラリ）を管理するためのツール**

みたいです。

### インストールと確認
```
dnf -y install php
dnf -y install php-json
dnf -y install wget
wget https://getcomposer.org/installer -O composer-installer.php
php composer-installer.php --filename=composer --install-dir=/usr/local/bin
composer --version
composer
```

### 備考
「json 拡張機能がありません。」と言われたので、上記で「php-json」をインストールしてます
```
[XXXX@XXXXXXXXXXX ~]# php composer-installer.php --filename=composer --install-dir=/usr/local/bin
Some settings on your machine make Composer unable to work properly.
Make sure that you fix the issues listed below and run this script again:

The json extension is missing.
Install it or recompile php without --disable-json
```
HAProxyで代替画像を返す

DIR
```
/haproxy-docker
├── /haproxy
│   ├── haproxy.cfg                # HAProxy 設定ファイル
│   └── /errors
│       └── placeholder.http       # 代替画像
├── /minio
│   └── data                       # MinIO データ格納ディレクトリ
├── /app
│   └── index.html                 # 簡易アプリケーション
└── docker-compose.yaml            # Docker Compose ファイル

```

```docker-compose.yaml
version: '3.9'

services:
  haproxy:
    image: haproxy:2.8
    container_name: haproxy
    ports:
      - "80:80"
    volumes:
      - ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
      - ./haproxy/errors:/etc/haproxy/errors:ro
    depends_on:
      - minio
      - app
    restart: always

  minio:
    image: minio/minio:latest
    container_name: minio
    command: server /data --console-address ":9001"
    ports:
      - "9000:9000"  # MinIO API
      - "9001:9001"  # MinIO Console
    environment:
      MINIO_ROOT_USER: admin
      MINIO_ROOT_PASSWORD: password123
    volumes:
      - ./minio/data:/data
    restart: always

  app:
    image: nginx:alpine
    container_name: app
    ports:
      - "8080:80"
    volumes:
      - ./app:/usr/share/nginx/html:ro
    restart: always

```

```haproxy/haproxy.cfg
# Global settings
global
    log stdout format raw local0
    maxconn 4096
    daemon

defaults
    log global
    option httplog
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms

# Define frontend
frontend http-in
    bind *:80
    acl is_image path_reg ^/img/.+/.+\.jpg$
    
    # 画像リクエストは MinIO へ
    use_backend minio_backend if is_image
    
    # それ以外はアプリへ
    default_backend app_backend

# Backend for MinIO
backend minio_backend
    server minio_server minio:9000 check
    option httpchk GET /health
    http-check expect status 200

    # minio から 200 以外ならエラーファイルを返す
    errorfile 404 /etc/haproxy/errors/placeholder.http
    errorfile 500 /etc/haproxy/errors/placeholder.http

# Backend for Application
backend app_backend
    server app_server app:80 check

```

```haproxy/errors/placeholder.http
HTTP/1.1 200 OK
Content-Type: image/jpeg
Cache-Control: max-age=3600
```
次に、placeholder.jpg を placeholder.http に埋め込みます。

```bash
# placeholder.jpg をエラー用ファイルに埋め込む
cat /path/to/placeholder.jpg >> ./haproxy/errors/placeholder.http
```
WindowsをMacのように - MacのCMD + バッククォートキーのショートカットをWindowsで使用する方法

長い間、メインの開発環境としてMacを使っていましたが、Windowsを再びメインで使い始めて1年が経ちました。

いくつかのデメリットはあるものの、Windows 11＋WSL（Ubuntu）環境での開発も悪くありません。
もちろん、<kbd>CMD</kbd>キーがないことや、<kbd>Ctrl</kbd>キーを使ったコピー＆ペーストが不便な点は否めません。

しかし、MacにはないWindowsのメリットが気に入っており、逆にWindowsにはないMacのメリットも魅力的です。

またいつかMacを再びメインにして、Windowsをサブにする日も来るでしょう。
メイン環境は状況によって柔軟に変えていけるものと考えています[^1]。

---

前置きが長くなりましたが、僕がMacでよく使うショートカットキー、<kbd>CMD + `（バッククオート）</kbd> は、
同じアプリ内のウィンドウを切り替える機能を持っています。例えばChromeブラウザを2つ開いている場合、このショートカットを押すとChromeのウィンドウ間を切り替えられます。
Macで一番よく使っていたショートカットで、Windowsでも似たような機能をするショートカットを一生懸命検索しましたが見つかりませんでした。

そこで、[AutoHotkey](https://www.autohotkey.com/)[^2] を使って簡単なスクリプトを作成して使用しています。

完璧に動作するわけではなく、個人的には「そこそこ満足できる」レベルの動作ですが、

* Macに慣れているがWindowsも使っている誰かの役に立つように
* [Hackers' Pub](https://hackers.pub)の活性化(?)を願って[^3]

このAutoHotkeyのスクリプトコードを共有します。

```
; Alt + `キーを押したときに実行されるコード
; MacOSのCMD + `(バッククオート)キーと同じ機能（同一アプリ内のウィンドウ切り替え）をWindowsで実現
!`::
{
    focusedWindow := WinExist("A")
    if !focusedWindow
        return

    focusedPID := WinGetPID(focusedWindow)
    focusedPName := WinGetProcessName(focusedWindow)
    focusedClass := WinGetClass(focusedWindow)
    focusedTitle := WinGetTitle(focusedWindow)

    ; Get all windows of the same class and process
    windows := []
    for window in WinGetList()
    {

        if (WinGetPID(window) = focusedPID && WinGetTitle(window) != focusedTitle)
        {
            windows.Push(window)
        }
    }

    if (windows.Length > 1)
    {
        WinActivate(windows[2])

    } else if (windows.Length = 1) {
        WinActivate(windows[1])
    }
}
```

実行方法は上記のコードを任意のahk拡張子のファイルとして保存し、AutoHotkeyで実行するだけです。また、AutoHotkeyを使えばこのスクリプトを実行ファイル（exe）としてコンパイルすることもできます。

追記）以前、[GitHub Gist](https://gist.github.com/rkJun/c578923b6b6843558a8caf48a0aa9cdf)にも共有しています。

お読みいただきありがとうございました。

原文：https://hackers.pub/@arkjun/2025/mac-to-windows-alt-backtick-shortcut-for-windows-japanese

[^1]: 実は、最近1年間は主にWindowsを使用していましたが、その間に時々Macをメインで使うこともありました。

[^2]: AutoHotkey（オートホットキー）: 独自のプログラミング言語(マクロ言語)を用いてコンピュータを制御することができる。「AutoHotkey」という名称から想像できるように、当初はキーボードのホットキー(ショートカットキー)をカスタマイズすることを目的として開発されたが、ユーザーの要望を取り入れる形で開発が進むにつれスクリプト言語と分類されるほどに膨大な機能が実装され、コミュニティも大きなものとなっている。
出典: ウィキペディア (https://ja.wikipedia.org/wiki/AutoHotkey)
[^3]: ActivityPub-enabled social network for hackers
【Cursor】MCPサーバーを立ち上げてFigmaデータからコードを自動生成する

## はじめに

こんにちは、フリーランスエンジニアのRyuです！

Figmaのデータいちいちコピペしてフロント実装するの面倒だな…AIが全部自動で実装してくれないかな…と思ったのでMCPサーバー経由で自動で実装してもらえるようにしてみました。

以下のYoutubeを参考にさせていただきました。
https://www.youtube.com/watch?v=X-aX1TuGP0s

## 手順

### Figmaからアクセストークンを取得

Figma上でアカウントの設定を開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3577451/8e19a27a-0827-40cd-a101-9a3f8768ace8.png)

セキュリティ > 個人アクセストークン から新規トークンを作成し、コピーします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3577451/c069b30f-7d5c-4da8-a7b4-ea08f305b0d8.png)

### CursorでMCPサーバー立ち上げ

ターミナルを開き以下のコマンドを実行します。

```
npx figma-developer-mcp --figma-api-key=【取得したFigmaアクセストークン】
```

するとこのようにMCPサーバーが立ち上がり接続が完了します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3577451/1d8d5535-633c-4a98-8227-ec262c6301f1.png)

立ち上がったらCursorにこのMCPサーバーを登録してあげます。


Setting > MCP > Add new MCP serverから以下で登録

|項目     | 値        |
|------- | ----------|
|Name     | 適当な名前        |
|Type     | sse        |
|Server URL     | http://localhost:3333/sse        |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3577451/6dc90111-c5c2-4755-9fc9-ff877661ec7a.png)

CursorにFigmaのMCPサーバーが登録されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3577451/ed4ccb1c-0d2f-432c-a071-e89e374e42f5.png)


## 試しに

では早速Cursorくんに質問してみましょう！

参考にさせたいFigmaデータを右クリックして選択範囲のリンクをコピーします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3577451/917b043e-b81a-4b85-b331-1815156f8b6f.png)

Cursorにリンクを張り付けて内容を聞いてみる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3577451/b011efa0-97d9-4ac8-b29e-dbf945324af2.png)

**ちゃんと読み込めてる！**

## 最後に

これでFigmaとCursorを連携できたのでガシガシ自動で実装してもらうだけですね！
ただ、連携してるとはいっても微妙に人の手で修正する必要がある場合もあるみたいです。
でもかなり手間が減るのは間違いありません。

便利な機能がどんどん出てきているので、積極的に活用していきたいです。