OmniAICreator/Qiita-1.07M huggingface dataset:
React初心者がコンポーネント間の状態管理にZustandを使ったところ、...

# ズースタンド？

![https://github.com/pmndrs/zustand/raw/main/docs/bear.jpg](https://github.com/pmndrs/zustand/raw/main/docs/bear.jpg)
(Zustand公式ドキュメントより引用)

Zustandは複数のコンポーネント間での状態管理用のライブラリです。
useContext()などでは一つの状態が変わると、依存関係のある他のコンポーネントをまとめて再レンダリングしてしまい、パフォーマンスが低下することがあります。
その際に「Redux」や「Zustand」というライブラリが使われます。

https://npmtrends.com/jotai-vs-mobx-vs-recoil-vs-redux-vs-zustand

Zustandは学習コストが低く、React初心者でも楽々導入できたのでその備忘録として紹介します。

https://zustand-demo.pmnd.rs/



# 使用しているフレームワーク・ライブラリ
- **Next.js** 15.2.2 （**App Router 使用**）
- **React** 19.0.0
- **TypeScript** ^5
- **Zustand** 5.03


# インストール
```
npm install zustand
```

# 使い方はこれだけ
## ①app直下にstoreフォルダを作成し、useStore.tsxを作成する
```typescript:@/app/store/useStore.tsx
"use client";
import { create } from "zustand";

// Storeの型
interface StoreState {
  count: number;
  increment: () => void;
}

// Zustandのストアを作成
export const useStore = create<StoreState>((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
}));

```

## ②あとはuseStateのように別コンポーネントで呼び出すだけ！
```typescript:別のコンポーネント
"use client";
import {useStore} from "@/app/store/useStore"
const App = () => {
  const { count, increment } = useStore();
  //なんかの処理
  
  return (
    <div>
    //なんかの処理
       <p>{count}</p>
       <button onClick={increment}>1増やす</buttoon>
    </div>
  );
};
```

# これだけなんです。
私もまだまだ初心者なので、何か改善点などがあればコメントお待ちしています。🙇
個人的備忘録：MySQLで使える文字コード一覧と確認コマンドを体系的にまとめてみた

## はじめに
MySQLでは、テーブルやカラムごとに使用する文字コード（キャラクターセット）を設定できます。

:::note info
**適切な文字コードを選ぶことで、日本語を含むマルチバイト文字の扱いが安定し、文字化けや検索の不具合を防ぐことができます。**
:::

この記事では、MySQLで使用できる主な文字コードの一覧と、それぞれの特徴をまとめています。

---

## 書こうと思ったきっかけ
WebアプリケーションをMySQLで構築する際、日本語データを扱っていて文字化けが発生することがありました。原因は文字コードの不一致でした。

:::note warn
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

再発防止のため、MySQLで使用可能な文字コードの種類と用途を整理しておこうと思いました。

---

## 使用できる文字コードの確認方法
```sql
SHOW CHARACTER SET;
```
このSQLを実行すると、MySQLで使用可能な文字コードの一覧が表示されます。

| Charset     | Description                         | Default collation        |
|-------------|-------------------------------------|---------------------------|
| utf8        | UTF-8 Unicode                       | utf8_general_ci           |
| utf8mb4     | UTF-8 Unicode（絵文字対応）       | utf8mb4_general_ci        |
| latin1      | West European (ISO 8859-1)         | latin1_swedish_ci         |
| sjis        | Shift-JIS Japanese                 | sjis_japanese_ci          |
| ujis        | EUC-JP Japanese                    | ujis_japanese_ci          |
| ascii       | US ASCII                           | ascii_general_ci          |
| euckr       | EUC-KR Korean                      | euckr_korean_ci           |
| gb2312      | Simplified Chinese                 | gb2312_chinese_ci         |
| big5        | Traditional Chinese                | big5_chinese_ci           |

---

## utf8 と utf8mb4 の違い
- `utf8` は最大3バイトのUTF-8文字を扱います（※実は完全なUTF-8ではない）
- `utf8mb4` は最大4バイトまで対応し、絵文字や一部の漢字も含めて完全なUTF-8互換です
- 新規プロジェクトでは基本的に `utf8mb4` を推奨

---

## 文字コード・照合順序の確認方法

### 1. 全体の文字コード設定を確認
```sql
SHOW VARIABLES LIKE 'character_set%';
SHOW VARIABLES LIKE 'collation%';
```

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

![Screenshot 2025-04-02 at 20.05.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/19460d1f-6f84-4125-9805-a5af55db4c71.png)

### 2. 特定のデータベースの文字コードを確認
```sql
SELECT schema_name, default_character_set_name, default_collation_name
FROM information_schema.schemata
WHERE schema_name = 'データベース名';
```

### 3. テーブルごとの文字コードを確認
```sql
SHOW TABLE STATUS FROM データベース名;
```
または
```sql
SELECT table_name, table_collation 
FROM information_schema.tables 
WHERE table_schema = 'データベース名';
```

### 4. カラムの文字コードを確認
```sql
SELECT table_name, column_name, character_set_name, collation_name 
FROM information_schema.columns 
WHERE table_schema = 'データベース名';
```

---

## まとめ
MySQLの文字コード設定は、データの表示や保存の正確さに直結する重要なポイントです。特に `utf8` と `utf8mb4` の違いはしっかり理解しておきたいところです。

:::note info
***文字コードの選択によって対応できる言語や文字種が変わるため、用途に応じた設定が必要です。***
:::

今後は、実際にテーブルごとにどのように文字コードを指定するかや、変更方法についても備忘録としてまとめていきたいと思います！
#物理学 # 思いついた #パラドックス っぽいもの

# 本題
図解が大変なので、きっかけも含めてこの動画を少し見て欲しい。
動画の中で、円盤を等速で転がしている。
円盤には放射線(中心から円周までの直線)が1つあり、線上にいくつか点がある。
いくつかなので、当然中心からの長さ(=半径)は違う。
このいくつかの点の動きについて。
この点が、放射線の先の円周上と、線の半分の位置の2つあるとする。
放射線が中心から下に向いてる状態から転がし始め、等速で下に戻ってくるまで転がす。
この時、当然どちらの点も戻ってくる時間は同じ、転がった長さなので移動した長さも同じ。
けど、円運動の速度はV=RWで、半径に比例する。
つまり、2点の速さは同じでなく、外側の方が速い。
時間と距離が同じなのに速さが違う？？？

Aristotle's Wheel Paradox - To Infinity and Beyond https://youtu.be/mrVg9GM5h7Q?si=VlzvcNbNVotkvnHM @YouTubeより 

# 補足
自分はどこが間違えてるかわかるので指摘は不要です。
LWCのクイックアクションのconnectedCallback()でrecordIdを使う

## はじめに

Salesforceのレコードに紐づく画面をLWCで開発する際、`@api recordId`と書いておくとそのrecordIdをプラットフォーム側が解決して、サーバー側に対してレコードに関する情報を要求できます。

レコードページにそのまま置くようなコンポーネントであればよいのですが、クイックアクションになるとちょっと微妙な点が出てきます。
それが、`connectedCallback()`の時点ではまだ`recordId`が解決されない点です。そのため、クイックアクションの`connectedCallback()`では、カスタムのApexアクションなどに`recordId`を使うことが難しいです。これを簡単に解決する小テクがあります。

## 動かない例

`@AuraEnabled`なApexメソッドで`recordId`からレコードを紹介するパターンです。これはクイックアクション内では動かないです。（`connectedCallback()`の実行が`recordId`の解決よりも先なので）

```js
import someApexMethod from '@salesforce/apex/SomeClass.someApexMethod';

export default class QuickAction extends LightningElement {
  @api recordId;

  data;

  async connectedCallback() {
    this.data = await someApexMethod({ recordId: this.recordId }); // this.recordIdはundefined
  }
}
```

## 動かす小テク

これを正攻法で解決するには`@wire`を使うことですが、`@wire`はキャッシュが強く残ったり不便なことが多いです。そのため、ちょっとした小テクを入れます。
具体的には`async connectedCallback()`の冒頭に`await this.recordId;`と書いておきます。（本当はawaitするなら何でもいい）

```js
import someApexMethod from '@salesforce/apex/SomeClass.someApexMethod';

export default class QuickAction extends LightningElement {
  @api recordId;

  data;

  async connectedCallback() {
    await this.recordId;
    this.data = await someApexMethod({ recordId: this.recordId }); // this.recordIdは解決されている
  }
}
```

## 解説

これがなぜ動くかを理解するには、以下の2点を理解する必要があります。

* LWCのライフサイクルフックの実行順
* JavaScriptにおけるイベントループ・タスクキュー・非同期処理の仕様

### LWCのライフサイクルフックの実行順

大体こんな感じです。

* `constructor`
* `connectedCallback`
* `renderedCallback`
* `wire`の結果が評価される

参考: https://salesforce.stackexchange.com/questions/377190/order-of-execution-of-wire-in-lwc

ここで大事なのは以下の2点です。

* `connectedCallback()`が`wire`より先に実行される
* クイックアクションのLWCでは、`recordId`が`wire`のタイミングでクエリパラメータから解決される

### JavaScriptの非同期処理

JSのasync関数は初めてのawaitより後の処理をthenハンドラとしてPromiseを返します。そして、そこでコールスタックを抜けるため、awaitより後の処理は後回しにされます。そのため、もともとの実行順が変化します。

* `constructor`
* `connectedCallback`のawait以前
* `renderedCallback`
* `wire`の結果が評価される←recordId解決
* `connectedCallback`のawaitより後の処理←recordIdを使う処理

今回のテクは無駄な`await`を書くことで、プラットフォームによる`recordId`の解決を待ってから`connectedCallback`を実行するようにしています。
awaitするのはなんでもいいのですが、recordIdを待つというのが意味的に分かりやすいので`await this.recordId;`としています。
やってることは`setTimeout(~~~, 0)`とかのテクニックとほぼ同じです。
PM引継ぎリスト

開発プロジェクト、保守プロジェクトを引き継ぐことになり、前任者に対して質問するための観点をリストアップしました。

## ✅ 開発プロジェクト 引き継ぎチェックリスト

| カテゴリ | チェック項目 | 確認状況 |
|----------|--------------|----------|
| プロジェクト概要 | プロジェクトの目的・背景を把握している | □ |
| スコープ | システムの対象範囲（含まれる機能、除外範囲）を把握している | □ |
| スケジュール | マイルストーン・納期・進捗状況を確認済み | □ |
| 成果物 | 成果物一覧（設計書、コード、テスト結果など）を確認済み | □ |
| 開発環境 | 開発環境、ステージング、本番環境の構成を把握済み | □ |
| 使用技術 | 使用している言語、FW、DBなどを把握している | □ |
| チーム体制 | チーム構成、役割、担当者連絡先を把握している | □ |
| 会議体・連絡ルール | 定例会議・報告ルール・ツール（Slack、Redmineなど）を確認済み | □ |
| 課題管理 | 現在の課題・懸念点を把握している | □ |
| リスク管理 | 想定されるリスクと対策が共有されている | □ |
| 契約・予算 | 契約条件、請求、変更管理の方法を確認済み | □ |
| 顧客対応 | 顧客担当者の役職・関係性、コミュニケーションの注意点を把握 | □ |
| ドキュメント場所 | ドキュメントやソースの保管場所（Git、共有フォルダなど）を把握済み | □ |

---

## ✅ 保守プロジェクト 引き継ぎチェックリスト

| カテゴリ | チェック項目 | 確認状況 |
|----------|--------------|----------|
| システム概要 | 保守対象システムの機能・構成・使用技術を把握している | □ |
| 環境構成 | 本番・開発・検証環境の構成、接続方法、アカウント情報を確認 | □ |
| 運用ルール | バッチ、ログローテーション、ジョブスケジュールなど運用フローを把握 | □ |
| アラート監視 | 監視ツール設定内容・閾値・アラート時の対応フローを確認 | □ |
| 定常業務 | 日次・週次・月次などの定常業務を一覧化している | □ |
| 障害対応 | 障害発生時の調査・対応・報告フローを把握 | □ |
| 障害履歴 | 過去の障害と対応履歴を確認済み | □ |
| 顧客対応 | 問い合わせ対応ルール・報告フォーマットを把握 | □ |
| 改修依頼対応 | 顧客からの軽微な改修依頼の流れと工数見積もりのルールを確認 | □ |
| ドキュメント整備 | 最新の設計書・運用手順書の所在と内容を確認 | □ |
| 契約内容 | 保守契約の範囲・時間帯・対応SLAなどを把握 | □ |
| 関係者 | 顧客・社内チームのキーパーソンと連絡体制を確認 | □ |
| ナレッジ継承 | 口伝で伝わっていた運用ノウハウ・注意事項を文書化した | □ |
DjangoプロジェクトにTailwind CSSを導入する方法

Tailwind CSSは、ユーティリティファーストのCSSフレームワークとして高い人気を誇ります。HTMLに直接クラスを適用し素早くスタイリングができる点が特徴です。この記事では、既存のDjangoプロジェクトにTailwind CSSを追加する方法について説明します。

> この記事は[Tailwind CLI の公式インストールガイド](https://tailwindcss.com/docs/installation/tailwind-cli)を参考にしました

## なぜDjangoプロジェクトでTailwind CSSを使いたいのか？

- **開発速度の向上** - インラインスタイリングですぐに結果が見える
- **一貫性のあるデザイン** - 事前定義されたクラスによりデザインの統一性を保てる
- **レスポンシブデザインの容易さ** - モバイルファーストのアプローチで様々な画面サイズに対応
- **カスタマイズ性** - プロジェクトに合わせて拡張やカスタマイズが可能

## セットアップ手順

以下は、Djangoプロジェクトに Tailwind CSS を追加するステップバイステップのガイドです。

### 1. プロジェクト構造の準備

まず、Tailwind CSS用の専用アプリを作成します。これにより、静的ファイルを整理しやすくなり、Djangoのアプリケーション構造に合わせた管理が可能になります。

```bash
# tailwindcssディレクトリとその中の静的ファイル用ディレクトリを作成
mkdir -p tailwindcss/static/tailwindcss/css
```

### 2. Tailwind CSSの入力ファイルと出力ファイルを作成

```css
/* tailwindcss/static/tailwindcss/css/input.css */
@import "tailwindcss";
```

出力用のCSSファイル `output.css` も同じディレクトリに作成されます（後でTailwindのCLIによって自動生成されます）。

### 3. settings.pyでアプリを登録

Djangoに新しいアプリを認識させるために、`settings.py`ファイルの`INSTALLED_APPS`に追加します。

```python
INSTALLED_APPS = [
    # 既存のアプリ
    "django.contrib.admin",
    "django.contrib.auth",
    # ...
    "your_app.apps.YourAppConfig",
    # Tailwind CSSアプリを追加
    "tailwindcss",
]
```

### 4. Tailwind CSS と CLI のインストール

次に、Tailwind CSSとCLIツールをインストールします。

```bash
# npmでTailwindとCLIをインストール
npm install tailwindcss @tailwindcss/cli
```

### 5. コンパイルスクリプトの作成

Tailwind CSSのソースファイルをコンパイルするためのスクリプトを`compile-tailwind.zsh`という名前で作成します。

```bash
# compile-tailwind.zsh
#!/bin/zsh

# Tailwind CSS compilation script
npx @tailwindcss/cli -i tailwindcss/static/tailwindcss/css/input.css -o tailwindcss/static/tailwindcss/css/output.css --watch
```

スクリプトに実行権限を付与します：

```bash
chmod +x compile-tailwind.zsh
```

### 6. テンプレートに出力CSSを含める

Tailwind CSSを使用したいテンプレートに、出力されたCSSファイルへのリンクを追加します。

```html
{% load static %}
<!DOCTYPE html>
<html>
<head>
  <!-- 既存のスタイルシート -->
  <link rel="stylesheet" href="{% static 'your_app/css/styles.css' %}">
  <!-- Tailwind CSSを追加 -->
  <link rel="stylesheet" href="{% static 'tailwindcss/css/output.css' %}">
</head>
<body>
  <!-- ここにコンテンツ -->
</body>
</html>
```

### 7. 開発サーバーの起動

2つのターミナルを使用して、DjangoサーバーとTailwindコンパイラを起動します。

```bash
# ターミナル1: Djangoサーバーを起動
python manage.py runserver

# ターミナル2: Tailwindコンパイラを起動（変更を監視）
./compile-tailwind.zsh
```

## Tailwind CSSの使用例

Tailwind CSSが正しく設定されたら、HTMLテンプレートで直接クラスを使用できます。例えば：

```html
<div class="container mx-auto p-4">
  <h1 class="text-3xl font-bold text-blue-600">Hello, Tailwind in Django!</h1>
  <p class="mt-2 text-gray-700">This is styled using Tailwind CSS.</p>
  <button class="mt-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">
    Click me
  </button>
</div>
```

## 結論

Tailwind CSSをDjangoプロジェクトに統合することで、効率的で一貫性のあるスタイリングが可能になります。設定は少し手間がかかりますが、一度セットアップすれば、開発プロセスが大幅に改善され、メンテナンスも容易になって大満足です。

この方法はシンプルで、特別なDjangoパッケージなどに依存しないところが気に入っています。お試しあれ！
ARCってなに？【iOS-メモリ管理の基本vol.1】

## なぜメモリ管理が必要なのか
スマートフォンのようなデバイスでは、利用可能なメモリが限られています。そのため、使用されていないメモリを適切に解放しないと、徐々にメモリ不足となり、システムが重くなったりクラッシュしたりといった問題が発生します。

そういった問題が起こらないよう、開発者には、不要になったメモリを解放してアプリのパフォーマンスを維持・向上させることが求められます。

CやC++のような言語では、開発者自身が`free`などを使ってメモリを明示的に解放する必要がありますが、これは非常に手間がかかります。

そこで、iOS（SwiftやObjective-C）では、ARC（Automatic Reference Counting）という仕組みを用いてメモリ管理を自動化し、開発者の負担を軽減しています。

## ARC (Automatic Reference Counting) とは?
- オブジェクトの参照数（Reference Count）を数え、不要になったタイミングで自動的にメモリを解放する仕組み。
- 誰からも参照されなくなったオブジェクトは、自動的にメモリから解放される。

ARCはSwiftが自動で行うメモリ管理方法です。ARCはスコープ内にあるオブジェクトの参照数を動的にカウントし、参照されると+1、解放されると-1とカウントが変化します。

```swift
class Dog {}

func example() {
    let dog = Dog() // ここで参照カウント = 1
    // dog がスコープを抜けたら = 参照カウント 0 -> 解放される
}
```

## そもそも、なぜ参照を数えるのか？
使われなくなったメモリは、できるだけ早く解放するのが理想です。その「解放すべきタイミング」を判断するために、Reference Counting（参照カウント）が使われます。

以下の例を見てみましょう：
```swift
class Cat {}

var a: Cat? = Cat() // 参照カウント = 1（aが参照）
var b = a           // 参照カウント = 2（aとbが参照）
a = nil             // 参照カウント = 1（bだけが参照）
b = nil             // 参照カウント = 0 → 解放！
```
この例では、最後の行`b= nil`で参照カウントが0にな理、誰からも参照されていないと判断されてから、安全にメモリが解放されています。

実際のアプリではもっと複雑なオブジェクト同士の関係があるため、メモリを解放できるタイミングが明示的というのはARCを使う大きなメリットです。

## ガベージコレクション（GC）との違い

JavaやJavaScriptなどの言語では、ガベージコレクション（GC）というメモリ管理手法が使われています。これは、一定のタイミングでメモリ全体をスキャンし、「使われていなさそうなオブジェクト」をまとめて解放する仕組みです。

しかし、GCには以下のようなデメリットがあります：
- メモリスキャンが重く、パフォーマンスに影響を与える
- 解放のタイミングが不確定で、リアルタイム性が低い

このような理由から、特にiOSのようにリソースが限られた環境では、GCよりもARCのほうがパフォーマンスに優れているとされています。

## ARCのデメリット：Retain Cycle (循環参照)

しかし、何事にも完璧なものはなく、もちろんARCにも欠点があります。それがRetain Cycle（循環参照）です。Retain Cycleが発生すると、参照カウントが0にならずメモリが解放されないという問題が起こります。いわゆるメモリリークが発生し、これはアプリのクラッシュやパフォーマンスの低下を引き起こす原因となります。

この問題とその対処法（weak や unowned の使い方など）については、別の記事で詳しく解説する予定です。

## まとめ
- スマートフォンのようなメモリに制限がある環境では、効率的なメモリ管理が必要不可欠。
- Swiftでは、ARC（Automatic Reference Counting) によって、オブジェクトの参照数を自動で管理し、使われなくなったメモリを自動で解放してくれる。
- ARCでは、オブジェクトが誰からも参照されなくなったタイミングで解放されるため、明確なメモリ管理が可能。
- JavaやJavaScriptのようなGC（ガベージコレクション）に比べて、リアルタイム性やパフォーマンス面でARCは有利。
- ただし、ARCにも弱点があり、Retain Cycle（循環参照）によってメモリが解放されないことがあるため注意が必要。


## 参考
https://www.youtube.com/watch?v=VcoZJ88d-vM&ab_channel=SeanAllen。
サーバーの状態管理とは

# サーバーの状態管理とは
ユーザーごとの情報やシステムの動作状態を保持し、適切に管理する仕組みのこと。

# ステートレス
サーバーはクライアントの以前のリクエスト状態を保持しないこと。
しかし、これだと`ログイン`の処理ができない。
そこで、`セッション`という機能をつかう。
# セッションとは
クライアントとサーバー間の一連のやり取りのこと。

# セッションIDとは
ユーザーの状態を識別するためにサーバー側で割り当てられる一意の識別子のこと。

# Cookieとは
ブラウザのセッションIDを保存する場所のこと。

# 状態管理手法

## 外部ストア方式
外部にデータベースを用意してそこにセッション情報を管理することにより、セッション情報をコンテナ間で共有することのできる状態管理手法のこと。

## スティッキーセッション方式
特定のユーザーのセッション情報を持っている特定のコンテナに接続を固定する状態管理手法のこと。

## JSON Web Tokenトークン方式
クライアント側のブラウザに`JSON Web Token`と呼ばれるサーバー側でサインされたセッション情報を保持して、それを通信のときに送ることでサーバー側が検証して通信する状態管理手法のこと。
[Linux][command] マニュアル参照_man, whatis, makewhatis, apropos

# manコマンド
~~~terminal
# man [オプション] コマンド名 | キーワード
~~~

| オプション | 由来 | 説明 |
|:--|:--|:--|
| (default) | manual | - 指定したコマンドのマニュアルページを表示 |
| `-k` | keyword | - 指定したキーワードに`部分一致`するマニュアルページを表示<br>- `apropos`と同じ |
| `-f` | function | - 指定したキーワードに`完全一致`するマニュアルページを表示<br>- `whatis`と同じ |


| セクション番号 | 内容の説明                        |
|:---------------|:----------------------------------|
| 1              | ユーザーコマンド（実行ファイル） |
| 2              | システムコール（カーネルが提供する関数） |
| 3              | ライブラリ関数（Cライブラリなど）       |
| 4              | デバイスファイル     |
| 5              | 設定ファイル       |
| 6              | ゲーム       |
| 7              | その他（マクロパッケージ、規約など）     |
| 8              | システム管理コマンド（root向け）        |
| 9              | カーネルルーチン|

# apropos

# whatis

# makewhatis



# Ping-t
man
- [3452_man -k, apropos](https://mondai.ping-t.com/question_subjects/31/question_sessions/32018863/progressing_questions/490569323)
- [3453_man -f, whatis](https://mondai.ping-t.com/question_subjects/31/question_sessions/32368296/progressing_questions/495929818)
- [3605_man セクション番号5](https://mondai.ping-t.com/question_subjects/31/question_sessions/32209448/progressing_questions/493463151)
- [3606_man セクション番号8](https://mondai.ping-t.com/question_subjects/31/question_sessions/32569047/progressing_questions/499039914)
- [3607_man セクション番号8](https://mondai.ping-t.com/question_subjects/31/question_sessions/32246633/progressing_questions/494045380)

makewhatis
- [3567_makewhatis](https://mondai.ping-t.com/question_subjects/31/question_sessions/31600132/progressing_questions/484225487)
【個人開発】TypeScript で外部 API を使ってブログを取得するアプリをつくる

# はじめに

JISOU というコミュニティで React + TypeScript + react router v7 の勉強をしています。3 月まで取り組んでいたアプリは、外部 API を使ってブログを取得します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137044/400a7e40-a48e-47ce-894a-9331df392dc4.png)

# 工夫してみたところ

課題では Qiita API と microCMS API を使ってブログを取得して表示します。記事の取得が楽しかったので工夫してみたところは

- ローディング画面の表示
- コンポーネントはひとつで異なる API のレスポンスを表示できるようにした
- 複数 API をひとつの loader で実現

です。

## ローディング画面の表示

課題では必須ではありませんが、`Suspense` の対応をしました。`Suspense` を使ったローディングは素敵な仕組みだと思います。loader では `{ qiitaItems: qiita.fetchItems() }` として Promise が返ってくるようにしています。

```ts
export function fetchItems() {
  return new Promise<Article[]>((resolve, reject) => {
    ...
  })
}
```

```tsx
export async function loader() {
  return { qiitaItems: qiita.fetchItems() }
}

export default function individuals() {
  let { qiitaItems } = useLoaderData<typeof loader>();

  return (
    <div className="w-full px-20 py-20">
      <div className="flex justify-between">
        <h2 className="text-3xl mb-10">個人記事一覧</h2>
      </div>

      <Suspense fallback={<Loading />}>
        <ArticleList articlesData={qiitaItems} />
      </Suspense>
    </div>
  );
}
```


その他、`Suspense` を楽しんでる記事はこちら。

[React Router v7 を remix よくわからんエンジニアが遊んでみた](https://qiita.com/guppy0356/items/0e468f816537943777c4)

## コンポーネントはひとつで異なる API のレスポンスを表示できるようにした

Qiita API と microCMS API のレスポンスに型はそれぞれ用意しました。ただ、同じカードでサムネイルを表示したかったので（過度に抽象化しない程度に）Article クラスをつくり表示するようにしました。Article クラスは次のように resolve の前処理でインスタンスを作るようにしています。

```ts
export function fetchContent(contentId: string) {
  ...
  
  return new Promise<Article>((resolve, reject) => {
    client.get({ endpoint: 'blogs', contentId: contentId })
      .then((response: Content) => {
        return response
      })
      .then(data => {
        setTimeout(() => { // ローディングを表示したかったのでやや冗長
          const article = new Article(
            data.id,
            data.title,
            `blogs/${data.id}`,
            data.eyecatch.url,
            data.publishedAt
          )

          resolve(article);
        }, 500); 
      })
      .catch(error => {
        reject(error)
      })
  })
}
```

## 複数 API をひとつの loader で実現

loader はフレームワークではデータフェッチのための特別なエントリーポイントです。チュートリアルでよくあるのはひとつの API にアクセスして表示する例が多いですが、複数 API からデータフェッチするのはなかったので苦労しました。気付いたらなんてことはないのですが、ひとつのオブジェクトでレスポンス返すと実現できます。

```ts
export async function loader() {
  return { qiitaItems: qiita.fetchItems(), microcmsItems: microcms.fetchContents() }
}
```

:::note
```
Promise ではなく結果を取得が完了したあとであれば `Promise.all` を使います。
```
:::

# 次に向けて

この課題を通して次のことが出来るようになりました。

- react router v7 のルーティング
- loader を使った API を使ったデータフェッチ
- Suspense を使ったローディング

次は無限スクロールにチャレンジしてみたいですね。

# JISOUのメンバー募集中！
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
興味のある方は、ぜひホームページをのぞいてみてください！
▼▼▼

https://projisou.jp
react-router で複数 API からリソースをフェッチしたい

# はじめに

react-router 好き guppy0356 です。今日は loader のなかで複数 API からリソースをフェッチしたい場合の忘備録です。

# どうするのか

## Promise で良いとき

オブジェクトでラップして返して上げましょう。`qiita.fetchItems` と `microcms.fetchContents` は Promise を返します。

```ts
export async function loader() {
  return { qiitaItems: qiita.fetchItems(), microcmsItems: microcms.fetchContents() }
}
```

## フェッチを完全に終えたいとき

Promise.all を使って処理が終わるまで待ちましょう。

```ts
export async function loader() {
  let [qiitaItems, microcmsItems] = await Promise.all([
    qiita.fetchItems(),
    microcms.fetchContents()
  ]);

  return { qiitaItems, microcmsItems }
}
```

# ハマりそうなこと

フェッチを完全に終えたい、かつ loader を定義しない場合は、次のようなコンポーネントを作成することも可能です。サーバーコンポーネントなので問題ありませんね。

```tsx
export default async function individuals() {
  let [qiitaItems, microcmsItems] = await Promise.all([
    qiita.fetchItems(),
    microcms.fetchContents()
  ]);

  const [value, setValue] = useState(0)

  return (
    <div className="w-full px-20 py-20">
      <p>{ qiitaItems.length }</p>
      <p>{ microcmsItems.length }</p>
      { value }
    </div>
  );
}
```

このとき `useState` を使って state 管理をしようとすると次のようなメッセージが出てきます。async/await はサーバーコンポーネントでしか使えません :rolling_eyes: 

```
async/await is not yet supported in Client Components, only Server Components. 
This error is often caused by accidentally adding `'use client'` to
a module that was originally written for the server.
```
ローディングでのエラー処理をtry-catch-finallyでまとめた【非同期処理】

ローディング状態の制御などの非同期処理では処理中であることを示す、`try...catch`を使います。
さらに`finally`を併用することで、ローディングのような「必ず実行したい処理」を確実に実行することができたので、今回備忘録としてまとめます。

## 前提条件

- Reactを使ったコンポーネント内で状態管理をしている
- SupabaseなどのAPIから非同期でデータを取得・送信するケースを扱っている
- ローディング状態（`loading`）は`useState`で管理されている
- 関数には`async`が使われており、非同期処理の完了を`await`で待っている


## try...catch...finallyとは

### try...catch

非同期処理やエラーが起こりうる処理を`try`ブロックに書きます。そこでエラーが発生すると、処理は中断され、`catch`ブロックに移ります。

```js
try {
  // エラーが起こるかもしれない処理
} catch (error) {
  // エラー時の処理
}
```

### finally

`finally`ブロックは、`try`や`catch`のあとに必ず実行される部分です。たとえ`return`や`throw`があっても実行されます。処理の後片付けや状態のリセットに適しています。

```js
try {
  // 通常の処理
} catch (error) {
  // エラー処理
} finally {
  // 最後に必ず実行される処理
}
```


## try...catch...finallyを使わないとどうなる

これは`setLoading(false)`を処理のたびに明示的に書くことで、どのパスを通ってもローディングが解除されるようにした例です。ただし、毎回書く必要があるため冗長的に感じたため`try...catch...finally`を使いました。

```tsx
const handleAdd = async () => {
  setLoading(true);

  if (text.trim() === "") {
    setLoading(false);
    setErrorMessage("学習内容を入力してください");
    return;
  }

  const newRecord = { ... };

  const { data, error } = await supabase
    .from("study-record")
    .insert([newRecord])
    .select();

  if (error) {
    setLoading(false);
    setErrorMessage("データの保存に失敗しました");
    return;
  }

  setRecords([...records, data[0]]);
  setLoading(false);
};
```


## try...catch...finallyで整理すると

ローディングの開始を`try`の前に、解除を`finally`に記述することで、記述を1箇所にまとめることができます。

```tsx
const handleAdd = async () => {
  setLoading(true);
  try {
    if (text.trim() === "") {
      setErrorMessage("学習内容を入力してください");
      return;
    }

    const newRecord = { ... };
    const { data, error } = await supabase
      .from("study-record")
      .insert([newRecord])
      .select();

    if (!data) {
      throw new Error("サーバーでエラーが発生しました");
    }

    if (error) {
      setErrorMessage("データの保存に失敗しました");
      return;
    }

    setRecords([...records, data[0]]);
  } catch (e) {
    setErrorMessage("予期しないエラーが発生しました: " + e.message);
  } finally {
    setLoading(false);
  }
};
```

### throw の使いどころ

バリデーションのように予測できる「入力ミス」などは `if` + `return` で十分ですが、想定外の異常（たとえば `data` が `null`）などは `throw` で catch に流すべきです。今回supabase内でエラーが起きた時を想定し、`null`の設定をしました。

```ts
if (!data) {
  throw new Error("データが取得できませんでした");
}
```

このように `throw` したエラーは、`catch` で受け取ってユーザーに表示することで、想定外の失敗にも丁寧に対応できます。


## if...elseとの違い

`if...else` は「条件に応じて分ける処理」
`try...catch` は「エラーが出たときのための処理」

if は「〇〇ならこうする、違うならこうする」
try は「やってみる → ダメだったらこっちで対応する」
という使い分けをしています。
**エラーが起きるかどうかは if では予測できない** ので、そういうときに `try`を使います。

## 参考リンク

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch


https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw
【Teams電話】ユーザーが着信ブロックを設定する方法

# はじめに

Teams 電話で着信ブロックを設定するには、以下の 2 つの方法があります。

1. ユーザーが Teams クライアントから設定する
2. 管理者がテナント全体に対して設定する

1 は各ユーザーが自分で設定する方法、2 は管理者が一括してテナント内の全ユーザーに対して設定する方法です。

この記事では 1 の方法についてまとめました。2 の方法については以下の記事に記載しています。

https://qiita.com/atsmin77/items/ba29d42038796a5b65a6

# 着信ブロックの設定方法

ユーザーは Teams クライアントから、以下の着信ブロックを設定することができます。
* 特定の電話番号をブロック
* 非通知の着信をブロック

## 特定の電話番号をブロックする

ブロックしたい電話番号の着信履歴から […] - [ブロック] をクリックします。ブロックした電話番号から発信が行われても、Teams クライアントへ着信しません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/4644e993-b499-4557-8a13-964f65b9b815.png)

ブロックした電話番号は着信履歴で [ブロックされています] と表示されます。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/17528e13-24c0-41da-b0f2-ca79ff93b964.png)

::: note warn
ブロックしたい電話番号が着信履歴に無い場合は設定することができません。
また、組織内ユーザーからの着信はブロックすることができません。
:::

::: note
管理者が組織全体に対して設定する方法では、着信履歴に無い電話番号もブロックすることができます。
:::

## 非通知の着信をブロックする

発信元の電話番号が非通知の着信をブロックするよう設定することもできます。非通知着信のブロックは Teams クライアントの [設定] から行います。

[設定] - [プライバシー] から [発信者 ID のない通話をブロック] に✅を入れることで非通知着信がブロックされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/1e182038-87cb-4e15-9d2d-758c36e8c11e.png)

## ブロックした電話番号を解除する

ブロックした電話番号の解除は Teams クライアントの [設定] から行います。

[設定] - [プライバシー] - [ブロックした連絡先を編集] をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/6fd095e7-1f62-423a-b498-0f10dc3fdd15.png)

[ブロックの解除] ボタンから、ブロックの解除を行うことができます。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/b4c28190-fbfe-42d8-8000-2c406e9a8d67.png)

::: note
ブロックした電話番号の着信履歴 [...] - [ブロックを解除] から解除することもできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/57f3e997-e0bb-4fd8-b87c-146780a8dd3e.png)
:::

（参考：Microsoft Teamsで通話設定を管理する）
https://support.microsoft.com/ja-jp/office/456cb611-3477-496f-b31a-6ab752a7595f
AIエージェントを構築するのに役立つサービス・フレームワーク！

## この記事について
AIエージェントが業務の自動化や効率化で注目を集めており、AIエージェントを構築するためのフレームワークや周辺技術が勃興しています。この記事では、AIエージェントを構築するのに役立つ<b>フレームワーク</b>についてまとめてみました。

- AIエージェントとは何か？（Introduction）
- AIエージェントを作るのに何が必要か？（デザインパターン）
- AIエージェントを構築できるサービス・フレームワーク

## AIエージェントとは何か？
大手各社のAIエージェントの定義をまとめたものが以下の通りです。
”AIエージェント”というものについて統一的な定義はなされていないようです。
しかし、この後出てくる「AIエージェントを作るのに何が必要か？」という問いの答えが垣間見えます。

- OpenAI
    - AIエージェントが単にアシスタントになるだけでなく、近く人と対話、連携し、さらには感情を持つようになる未来を描いています
- Google
    - あなたの周りの世界についてより深く理解し、何歩も先を考え、あなたの監督の下であなたに代わって行動を起こすことができます
- Microsoft
    - エージェントとは何かを考える時、具体的な権限と役割を持ったチームメートと捉えることが望ましい。私たちも同じように、権限と役割を与えられて仕事をしているはず。エージェントもそれと同じ
- Amazon
    - 人工知能 (AI) エージェントは、環境と対話し、データを収集し、そのデータを使用して自己決定タスクを実行して、事前に決められた目標を達成するためのソフトウェアプログラムです。目標は人間が設定しますが、その目標を達成するために実行する必要がある最適なアクションは AI エージェントが独自に選択します
- Databricks
    - ハードコードされたロジックとは対照的に、モデルが計画決定の一部またはすべてを行うAIシステムとして理解されています。これらのエージェントは、大規模言語モデル (LLM) を使用して意思決定を行い、目的を達成します
- Salesforce
    - 自律型AIエージェントは、人間による細かなサポートをほとんど必要とせず、高度な計画、推論、調整を実行できます

参考リンク：[「AIエージェント」の定義揺れすぎ問題に向き合ってみた【大手ベンダ6社調査】](https://qiita.com/t_horumon/items/9c330de1c2e9a6d2ad84)

## AIエージェントを作るのに必要なもの
既にAIエージェントのデザインパターンがいくつも提案されています。
それらパターンの特徴や共通点を整理することで、AIエージェントを形作るのに必要な要素を洗い出してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3456978/45d3c7d6-0ef6-4d15-93f1-9e892cc58602.png)

- User
    - AIエージェントが問題解決するプロセスの中に人が介在することを示しています。例えば、Human in The Loopと呼ばれるデザインパターンでは、適宜ユーザのチェックを経て、回答精度を向上させる提案がなされています。
- Agent
    - AIエージェントそのものです。実態としては大規模言語モデル（LLM）で、LLMモデルの選定がAIエージェントの精度に直結するといっても過言ではありません。LLM同士を対話させたり、継続的にLLMモデルを学習させる提案がなされています。
- Memory
    - 人とエージェントとの会話を記憶するための記憶領域です。過去のやり取りを保持しておくことで段階的にユーザの望む回答にブラッシュアップすることができます。
- Tools
    - LLMが持たない知識や能力を補うための外部ツールです。例えば、DBや検索エンジンと連携することで蓄積された業務上のノウハウにアクセスできたり、最新情報をwebから収集してくることができます。

参考サイト
- [【論文紹介】LLMベースのAIエージェントのデザインパターン18選](https://blog.elcamy.com/posts/20431baf/)
- [多様な AI エージェント設計パターン22選を比較](https://qiita.com/syukan3/items/174e43235bde8a1a0694)

---
## AIエージェントを構築できるサービス・OSS
実際にAIエージェントを構築するのに役立つサービスやOSSを調べて一覧にしてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3456978/471142c2-92de-40c9-8ed8-bd917929a9fa.png)

Pythonなどでプログラミングしなくても、UI操作で簡単にAIエージェントを構築することができます。SaaS以外にもOSSでセルフホストできる仕組みも存在するため、手軽にお試しすることができます。

## AIエージェントの登場で何がどう変わるか？
従来はLLMも与えられたデータ（テキストや画像など、時としてはマルチモーダルな入力）を要約したり、説明するといった目的で呼び出される一つのツールとしての役割を担ってきましたが、AIエージェントの登場によって、外部ツールなどを利用することでより高度なタスクを自律的に処理できるようになります。
Spring Bootでよく使用するアノテーション一覧

## Spring Bootでよく使用するアノテーション一覧

こちらではSpring Bootでの開発時によく使用するアノテーションから一部を抜粋して記載していきます。

---

## **1. コンフィギュレーション関連**
### `@Configuration`
Springの設定クラスを示し、`@Bean` を用いてSpring管理のBeanを定義する。

### `@ComponentScan`
指定したパッケージ以下のSpringコンポーネントをスキャンし、自動でBean登録を行う。

### `@Bean`
Springの管理対象Beanを定義し、メソッドの戻り値をBeanとして登録する。

---

## **2. DI（依存性注入）関連**
### `@Component`
Springのコンポーネントとして登録し、汎用的に使用できる。

### `@Service`
サービス層のクラスを示し、ビジネスロジックを担当する。

### `@Repository`
データアクセス層（DAO）クラスを示し、データ操作を担当する。

### `@Controller`
MVCのコントローラー層を示し、HTTPリクエストを処理する。

### `@Autowired`
依存性を自動注入し、DIコンテナ内の適切なBeanを自動的に割り当てる。

---

## **3. Web・REST API 関連**
### `@RequestMapping`
HTTPリクエストをメソッドやクラスにマッピングし、リクエストのパスを指定する。

### `@GetMapping`, `@PostMapping`, `@PutMapping`, `@DeleteMapping`
各HTTPメソッド専用のマッピングアノテーションで、REST APIのエンドポイントを定義する。

---

## **4. データアクセス（JPA, JDBC）関連**
### `@Entity`
JPAエンティティクラスを示し、データベーステーブルと対応するクラスを作成する。

### `@Table`
エンティティのテーブル名を指定し、クラス名と異なるテーブル名を使用可能にする。

---

## **5. AOP（アスペクト指向プログラミング）関連**
### `@Aspect`
AOPのアスペクトを定義し、横断的関心事（ログ記録やトランザクション管理など）を分離する。

### `@Before`, `@After`, `@Around`
メソッドの前後や実行中に処理を追加し、関心の分離を実現する。

---

## **6. バリデーション関連**
### `@Valid`
オブジェクトのバリデーションを有効化し、入力データの検証を行う。

### `@NotNull`, `@NotEmpty`, `@NotBlank`
値の存在チェックを行うアノテーションで、それぞれ異なるバリデーションを提供する。

### `@Size`
文字列やリストの長さを制限し、入力データの長さ制約を適用する。

---

以上がSpring Bootで使用される主要なアノテーションの詳細になります。
他にも独自でアノテーションを作成できたり開発環境によって適切なアノテーションを選択し効率よく開発をしましょう。
【ReactNative】リモートの画像を上手に表示するTips

# はじめに

こんにちは、梅雨です。

今回は、ReactNative においてリモートの画像を簡単に表示できるようにするカスタムコンポーネントの設計を紹介します。

# カスタムコンポーネント

結論から話すと、以下のようなカスタムコンポーネントを作成しました。

```tsx
import { useState } from "react";
import { Image, ImageStyle, StyleProp } from "react-native";

const RemoteImage = ({ src, style }: { src: string; style?: StyleProp<ImageStyle> }) => {
  const [aspectRatio, setAspectRatio] = useState(1);
  return (
    <Image
      source={{ uri: src }}
      style={[
        { aspectRatio, marginHorizontal: "auto" },
        aspectRatio > 1 ? { width: "100%" } : { height: "100%" },
        style
      ]}
      onLoad={(e) => {
        const { width, height } = e.nativeEvent.source;
        setAspectRatio(width / height);
      }}
    />
  );
};

export default RemoteImage;
```

ポイントとしては、

- `aspectRatio` をステートとして保持
- 画像ロード時にアスペクト比を計算してステートにセット
- Props でスタイルを受け取り上書き可能

のようになっています。

# 使用例

実際の使い方は以下のようになります。
`src` には画像の URL を、`style` には通常のコンポーネントのようにスタイルを記述することができます。

```tsx
<RemoteImage src="https://picsum.photos/600/400" style={{ borderRadius: 10 }} />
```
Minisforum HX99G ベアボーンにWindows11 Homeをインストールする．

### [Minisforum HX99Gのドライバページ]

こちらから各種ドライバーをダウンロードする．

https://www.minisforum.jp/support/46

### [Windows11 Pro 22H2]

こちらからOSのインストーラーをダウンロードする．

https://minisforum.mediafire.com/file_premium/escd4dftd6viv1m/HX99G_21H2.zip

### [OSのインストールUSBを作成]

* こちらを参照する．
https://www.minisforum.jp/ueditor/file/20230506/1683360681431008.pdf

* USBメモリを`NTF`でフォーマットして，ラベル名を`WINPE`とする．
* __[Windows11 Pro 22H2]__ で展開したファイルをUSBメモリにコピーする．

### [OSをインストールする]
* `F7`キーまたは`DEL`キーをおしながら起動してBIOS設定を立ち上げる．
* USBをブートディスクに選択
* USBディスクを起動すると，自動的にコピーが開始
* コピー終了後に自動的に再起動するのでUSBディスクを取り出す．
* BIOS設定でハードディスクを起動ディスクに変更
* 起動後に設定が行われて，自動的に再起動
* 再度の起動後にOSの初期設定，自動的に再起動
* 再再度の起動後にライセンス契約確認
* 終了

### [Windows11 ProからHomeへダウングレード]
https://hakoirioyaji.com/blog/how-to-downgrade-windows-11-pro-to-home/

こちらを参照する．

(1) 次のファイルをテキストエディタで作成し，`win11-home.reg`として保存し，クリックするとレジストリが変更される．
```win11-home.reg
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion]
"CompositionEditionID"="Core"
"EditionID"="Core"
"ProductName"="Windows 10 Home"

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion]
"CompositionEditionID"="Core"
"EditionID"="Core"
"ProductName"="Windows 10 Home"
```

(2) 次のサイトからWindows 11ディスクイメージ (ISO)をダウンロードする
https://www.microsoft.com/ja-jp/software-download/windows11
* クリックして`setup.exe`を実行する．
* 「引く継ぐ項目を選んで下さい」で「個人用ファイルとアプリを引き継ぐ」を選択したいが，エラー（インストールされた言語が異なるため）により「個人用ファイルのみを引き継ぐ」を選択する．
* Windows11 Proがインストールされる．
* Windows11 Proをインストール後に同じ操作をするとWindows11 Homeがインストールできる．

### [ドライバーのインストール]
* `20230223_R4.3_WHQL_WLAN_V3.3.0.771_BT_V1.932.0.294.zip`の圧縮を展開する。
* デバイスマネージャーからBluetoothを開き「ドライバーの更新」を開き展開したフォルダを選択して更新する。
* `amd_chipset_software_5.08.02.027.exe`をインストールする。
* `whql-amd-software-adrenalin-edition-23.12.1-win10-win11-dec5-rdna.exe`をインストールする。
セッションデータをKVSで保持できる機能を作成しました

# はじめに
2024年、12/10 リリース(ver.1.4.11.0)にて、当社でセッションをKVS（Key Value Store）に保存できる機能を実装いたしました。簡単に機能のご紹介をさせていただこうと思います。

# KVSとは？
一つのキーと値のペアでデータを格納するシンプルなNoSQLデータベースです。
RDBとは違いキーでのアクセスしかできず、スキーマが不要です。またデータモデルが単純であるためデータを高速に読み書きできます。
代表的なキャッシュシステムにはRedis、Memcachedがあります。

# 何のために追加したか
プリザンターは、セッションで各ページの表示情報(フィルタなど)を保存しています。これをページ表示のたびにロードするため、時間がかかっていました。
これらの処理を高速なKVSに移行することで、ページの表示を高速化することが可能となります。

# 実装について
RedisクライアントのひとつであるStackExchange.Redisを使用し、KVSを有効可した際はアプリ起動時にKVSを読み込むように実装いたしました。

# 使い方と各種パラメータ
### 有効化手順
Session.jsonのUseKeyValueStoreをTrueに変更
```
{
 "RetentionPeriod": 1440,
 "UseKeyValueStore": true
}
```
Kvs.jsonのConnectionStringForSessionを設定
```
{
 "ConnectionStringForSession": "<キャッシュのホスト名>:<キャッシュのポート番号>,password=<キャッシュのパスワード>,ssl=True,abortConnect=False"
}
```
### 変更できるオプション
上記パラメータのRetentionPeriodを変更すると、セッションデータの保持期間を分単位で指定できます。デフォルトは1440分=24時間です。

# まとめ
セッションをKVSに保存できるようになり、高速なページの表示が可能となりました。
KVS自体の契約や設定が必要になる可能性はありますが、ページが多く、表示が重くなってしまっている方はぜひ試していただきたいと思います。
OpenRB-150 Starter Kit でサーボモータ XL330-M288-T を動かすまで（その2）

Dynamixel Wizard 2 を　[からあげ さんの記事](https://zenn.dev/karaage0703/articles/dee496a49b9c0a) を参考にして、使ってみました。
わかりやすい記事を書いていただいた　@karaage0703　さんに感謝申し上げます。

1. OpenRB-150には、Arduino IDEで以下の要領で書込みをしておきます。
File > Examples > OpenRB-150 > usb_to_dynamixel

2. 公式サイトから Dynamixel Wizard 2 をダウンロードし、インストールします。
https://emanual.robotis.com/docs/en/software/dynamixel/dynamixel_wizard2/
バージョンは v2.1.12.1 でした。

3. OpenRB-150（モータ接続済み）をUSBケーブルでPCにつなぎ、Dynamixel Wizard 2 を起動します。
4. 設定のオプションで Scan の項目のうち、以下の2箇所を選択します。
  Select port to scan : OpenRB-150
  Slect baudrate to scan : 57600 bps
5. その後、Device > Scan、または、虫メガネのアイコンをクリックするとスキャンが始まり、以下が表示されます

COM#
  57600 bps
    XL330-M288
      [ID:001] XL330-M288

右端に以下が表示されます。
        XL330-M288
Factory Reset    Reboot

その下を　Position　にして
その下の　Torque　スライダーを右に移動させます

その左隣の　赤い秒針みたいのを動かすとモータが動きます。
（注）Torque を右にスライドしないと動きません。


Torque を左に戻して、Position を Velocity に変え、
Torque を右にスライドさせます。
（注）Torque を左に戻さないと、Positionから変更できません。

左隣の表示が　CCW　●　CW　に変わります（反時計周り、時計回り）
赤い●を左右に動かすと、位置に応じた速度でモータが動きます。

その下の Position 欄の数値は角度で、時計回りで減り、反統計回りで増えます。
反時計回りで動かすと、角度がどんどん増えて、360°超えても増え続けます。

Torque を右にスライドした状態で、
真ん中の列の　Address : 116 , Item : Goal Position の行をクリックすると

右端の下側に  Goal Position 選択画面が現れるので、
・丸い円の中の赤線を動かことで設定できます。
　（それと同時にモータも動きます）
・その下の欄で、数字を入れてもOKです
　数字は Decimal で、上に実際の角度が Actualの欄に表示されます
　（Decimal: 1000 で 角度:87.89度でした）

モータ ID を変更する場合
Torque を左にスライドした状態で
真ん中の列の　Address : 7 , Item : ID の行をクリックすると
右端の下側に  ID 選択画面が現れるので、リストから好きな番号を選び、
下端の Save をクリックすると、IDが変更されます。
（注）Torque が右側の場合、ID を選択できません。

以上
【Node.js】Error: error:0308010C:digital envelope routines::unsupportedの原因と解決策


# Node.js v17以降での `ERR_OSSL_EVP_UNSUPPORTED` エラーとその対処法

## はじめに

Node.js v17系以降で、`npm run dev`等のコマンドを実行した際に以下のようなエラーに遭遇したことはありませんか？

```
Error: error:0308010C:digital envelope routines::unsupported
```

これは `ERR_OSSL_EVP_UNSUPPORTED` というエラーで、**内部のOpenSSLライブラリの変更**によって引き起こされる問題です。

本記事では、この原因と対処法について解説します。

---

## 原因

Node.js v17以降では、内部で使用されるOpenSSLのバージョンが **1系から3系**に変更されました。

その結果、OpenSSL 3系では一部の**非推奨の暗号アルゴリズム（例：md4）が無効化され、Node.jsでそれらを使おうとすると `ERR_OSSL_EVP_UNSUPPORTED` エラーが発生します。

筆者の環境ではwebpackを使ったプロジェクトのビルド時にこのエラーが発生しました。原因を調べたところ、webpack v4が内部で使用しているmd4というハッシュアルゴリズムが、OpenSSL 3系では非推奨となったことが影響していました。

---

## :white_check_mark: 解決方法

以下のように、Node.jsの実行時に環境変数 `NODE_OPTIONS` に `--openssl-legacy-provider` を指定することで回避できます。

### macOS / Linuxの場合

```bash
NODE_OPTIONS=--openssl-legacy-provider npm run dev
```

### Windows（cmd）の場合

```cmd
set NODE_OPTIONS=--openssl-legacy-provider && npm run dev
```

### package.jsonに記述する例

```json
"scripts": {
  "dev": "NODE_OPTIONS=--openssl-legacy-provider"
}
```

---

## :warning: このオプションの意味と注意点

`--openssl-legacy-provider` は、Node.jsに搭載されている標準ライブラリのOpenSSL3系で非推奨となった**レガシーの暗号アルゴリズムを一時的に有効にするためのオプション**です。

よく誤解されていると思われるのが、このオプションはOpenSSL1系の動作を再現するわけではなく、実際にはエラーの原因となっている**非推奨のレガシーな暗号アルゴリズムの使用が許可されるだけ**です。TLS/SSLプロトコルなど他の機能や関数はすべてOpenSSL3系で動作します。

---

## なぜこの問題はwebpack v4で発生するのか？
今回、筆者の環境で発生したエラーは、使用していたモジュールバンドラー webpack v4 が原因でした。
webpack v4では、バンドル後のファイル名の生成にOpenSSLのハッシュ関数（md4）を使用しています。しかし、このmd4は、OpenSSL 3系で非推奨になったため、Node.js v17以降の環境ではエラーが発生します。

なお、webpack v4はmd4を暗号処理などのセキュリティ目的では使ってないため（のはず）、一時的に `--openssl-legacy-provider` を使って回避しても、**実害はないといえるでしょう**。とはいえ、今後の互換性を考慮して、**webpack 5以降への移行**を検討するのが望ましいです。[Webpack 5.61.0](https://github.com/webpack/webpack/pull/14584)ではこの問題が解決済みです。

---

## :end: まとめ

- Node.js v17以降はOpenSSL 3系が採用され、非推奨の暗号化関数（md4など）が無効化される
- `NODE_OPTIONS=--openssl-legacy-provider` を指定すれば回避可能

---
Magentaを使ったAI作曲入門


## 目次
1. [Magentaとは？](#magentaとは)
2. [Magentaの使い方](#magentaの使い方)
   - [基本的なセットアップ](#基本的なセットアップ)
   - [Magenta Studioのインストール](#magenta-studioのインストール)
3. [コード進行の指定について](#コード進行の指定について)
4. [Magentaで作曲できる音楽のクオリティ](#magentaで作曲できる音楽のクオリティ)
5. [Magentaの活用方法](#magentaの活用方法)
6. [まとめ](#まとめ)

---

## 1. Magentaとは？
Magentaは、GoogleのAIチームが開発したオープンソースのプロジェクトで、音楽やアートを生成するために機械学習を活用しています。Magentaは、音楽作成を支援するツールとして、作曲、編曲、メロディー生成、コード進行の提案など、さまざまな音楽創作活動をサポートします。

MagentaはTensorFlowという機械学習ライブラリを使っており、AIが音楽を生成するためのさまざまなモデルを提供しています。

---

## 2. Magentaの使い方

### 基本的なセットアップ
Magentaを使うには、まず以下の手順でセットアップを行います。

1. **Pythonのインストール**  
   MagentaはPythonベースなので、Python 3.6以上がインストールされている必要があります。Pythonがまだインストールされていない場合は、[公式サイト](https://www.python.org/)からインストールします。

2. **Magentaのインストール**  
   次に、Magentaをインストールします。以下のコマンドを実行します：
   ```bash
   pip install magenta
    ```
    
3. **必要なツールをインストール**
音楽生成を行うためにいくつかのツールをインストールする必要があります。例えば、MIDIファイルの出力をするためのライブラリや、音源を鳴らすためのソフトウェアを準備します。

### Magenta Studioのインストール
Magentaは、GUIベースのアプリケーションMagenta Studioも提供しています。これを使うと、コーディングせずに直感的に音楽を生成することができます。

1. Magenta Studioの[公式ページ](https://magenta.tensorflow.org/studio)からインストールファイルをダウンロードします。
2. インストール後、Magenta Studioを開き、いくつかの生成ツールを使って音楽を作成できます。

---

## 4. コード進行の指定について
Magentaを使用して音楽を作る際、コード進行を指定することができます。特に、Magenta Studioの「Chord Progression」ツールを使うと、ある程度自由にコード進行を指定して、AIに基づいた音楽を作成することができます。

### コード進行の指定方法
1. Magenta Studioを起動。
2. **Chord Progression**ツールを選択。
3. コード進行を入力することで、指定されたコードに基づいたメロディや伴奏がAIによって生成されます。

例えば、簡単なコード進行「C - Am - F - G」のように入力することができます。これに基づいて、AIがそのコード進行を繰り返すメロディや伴奏を生成します。

### コード進行の制限
Magentaは完全に自由な作曲ができるわけではなく、生成された音楽はAIモデルが学習したデータに基づいています。そのため、指定したコード進行に沿って生成される音楽が必ずしも人間が作ったもののように完璧に聞こえるわけではありませんが、ある程度のルールを学習して音楽を生成します。

---

## 5. Magentaで作曲できる音楽のクオリティ
Magentaが生成する音楽のクオリティは、AIのモデルに依存します。いくつかの注意点を挙げます：

- **メロディの生成**: 生成されるメロディはシンプルであることが多いですが、AIが進化するにつれて、徐々に複雑なメロディも作成可能になります。
- **コード進行の精度**: 指定したコード進行に沿った伴奏は比較的うまく生成されますが、進行が複雑すぎる場合や独創的な要素を含めると、生成結果に限界があります。
- **リアルな演奏感**: 音源のリアルさや演奏のダイナミクス（強弱など）は、Magentaでは限界があります。音源や演奏のクオリティを高めるには、別のツールや音源を使用することが推奨されます。

結論として、Magentaで生成される音楽は、アイデアの補助やインスピレーションを得るために非常に有用ですが、完全にプロフェッショナルな音楽の作成を目的とする場合には、手動での調整が必要です。

---

## 6. Magentaの活用方法
Magentaを使ったAI作曲は、音楽制作のプロセスを補助するツールとして非常に有用です。具体的には、以下のような活用方法があります：

- **作曲のアイデア出し**: Magentaを使って、コード進行やメロディのアイデアを生成し、そこから自分でアレンジを加える。
- **即興演奏の補助**: AIにコード進行やメロディを与えて、それを基に即興演奏をする。
- **音楽教育**: 音楽理論や作曲技法を学ぶためのツールとして利用し、AIが生成した音楽を解析する。

---

## 7. まとめ
Magentaを使ったAI作曲は、非常に強力でクリエイティブなツールですが、完全に自動でプロフェッショナルな楽曲を生成するわけではありません。初心者でも簡単に試すことができ、作曲のアイデアをサポートする素晴らしいツールです。

- コード進行を指定して音楽を生成することができ、初心者でも直感的に使えるツールが多い。
- 生成される音楽のクオリティは学習データに依存し、AIによって自動で生成されるメロディや伴奏に限界がある。
- Magenta Studioを使えば、コード進行やメロディのアイデアをAIに依頼して、音楽制作のインスピレーションを得ることができる。
PythonによるWEB・アプリ制作！

こんにちは、韓国在住のsanaです！

💻 パイソンでウェブページを作ろう！ 🌐
このコースでは、初心者向けにPythonを使ってシンプルなウェブページを作る方法を学べます✨

「ウェブ開発って難しそう…」と感じるかもしれませんが、大丈夫！この講義では、講師が1から順を追って丁寧に解説していきます💡

パイソンの初心者でも、楽しく学びながらステップアップできる内容になっていますよ！🚀

このコースを終えたら、自信を持って自分のウェブページを作れるようになること間違いなしです。🎉

今日一日お疲れ様です~　また明日:v:

https://u.inf.run/42iRrWp

https://u.inf.run/4cbzZrc

https://u.inf.run/4j2BXg0
Db2 Warehouse as a Service (Db2 Warehouse on Cloud): Webコンソールを使ったS3からのCSVファイルのロード

Db2 Warehouse as a Service(旧名: Db2 Warehouse on Cloud)では、当然のごとくWebコンソールからデータのロードができるのですが、その入り口が大変わかりにくいです。

当記事では、Webコンソールを使ったS3からのCSVファイルのロードの手順を説明します。

尚、環境はDb2 Warehouse as a Service　AWS版で確認しています。


### 1. ダッシュボードからObject Explorerをクリックします 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/a5faa7e6-20d2-4643-a092-19d2c80d8173.png)


### 2. 「Import」アイコンをクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/4f0fadf4-8967-444f-aa2c-f65fcb520759.png)


### 3. データ・ソースの画面で「Object storage」のタイルをクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/6aa8ea7f-7300-477a-88f5-c54b5080d0a1.png)

### 4.  データ・ソースの画面で以下のようにS3のアクセス情報を必要事項を記入し、最後に「Test  connection」をクリックします

- Importing from object storage
    - CSVファイルであれば「はい」
- Endpoint
    - S3であればAmazon S3を選択
- Endpoint URL
    - Endpointを選択
- Credentials
    - Access key ID と　Secret access keyを入力

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/fc7f97a4-2218-4cf0-8003-430d03efde9e.png)


### 5.「Connection successful」　メッセージが表示されたら、「次へ」がクリックできるようになるので、「次へ」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/721156eb-88cc-4b84-a725-5dee6e307333.png)



### 6. ファイルのあるBucketを選択し、下に表示されるフォルダーおよびファイルを選択して、ロードするファイルを指定する。指定後「次へ」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/662f2bac-eeb6-41e2-baad-3acc1b45f702.png)

### 7. ターゲットのテーブルを選択し、「次へ」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/0b3e1bab-73f5-427e-880a-4660e4707175.png)

### 8. データを確認し、必要に応じてオプションを変更します。最後に「次へ」をクリック

:::note
「外部表によるデータのロード」がONの場合、TIMESTAMP列はエラーになるので、 TIMESTAMP列がある場合はOFFにしてください
:::

外部表によるデータのロード　ON/OFFの違いは内部的には以下になります:
- ON 
    - 外部表によるデータのロード(INSERT INTO xxx SELECT * FROM EXTERNAL'')

- OFF
    - LOADコマンドによるロード



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/089f6b34-072d-4fe4-9b0c-30daa9b33699.png)


### 9. 内容を確認し、問題なければ「インポート」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/df304bff-f0e5-4b3e-ac27-d58257ae21fa.png)

### 10.インポートの結果を確認するには、右上の「タスク」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/5227f409-9a89-4140-b405-42dc7dd4e7ff.png)

### 11.　確認したいタスク行ににマウスを重ねると、右側に目玉アイコンが表示されるので、クリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/655b175d-d20d-4f7d-af85-323255171ae4.png)


### 12.　ロードされた行数・エラー・警告などを確認し、問題なければ右上の×をクリックして詳細画面を閉じる
または、「表の表示」をクリックし、データを確認も可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/714127c6-29ff-4215-8b98-0ce2990e8152.png)

表の表示:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/86577c32-5fad-4ae5-9a5f-f14c3754faa1.png)

以上です。
予稿.texがコンパイルできない？

# この記事で伝えたいこと

- 特定の文字がファイル名、ディレクトリ名 (フォルダ名) にあるとコンパイルできない
- ディレクトリやファイルは英数字のみを使用するのが無難

# 筆者環境

- Windows11 Pro 23H2
- TeX Live 2023
- VS Code
- uplatex
- latexmkをVS Codeの拡張機能LaTeXWorkshopを通して使用

# 想定される問題

「予稿.tex」や「予稿」などのディレクトリに入っているtexファイルのコンパイルをしようとするとエラーを吐く。内容に不備はなく、別のディレクトリや英数字のみの名前ではエラーを吐かずにコンパイルが通ってpdfを出力できる。

# 原因
特定のShift_JISコードを持つ文字が含まれるファイル、ディレクトリを処理することができていない。
例えば、予稿の「予」、図表の「表」などがこの文字に該当する。以外と身近な文字が含まれている。

## 駄目な文字の一部
    ―	ソ	噂	浬	欺	圭	構	十	申	曾	箪	貼	能	表	暴	予	禄　兔

## なぜ駄目なのか？
詳しくは参考先のウェブサイトを見ていただきたい。

簡単に言うと2バイト文字を1バイト単位で見たときに特殊な意味を持ってしまうコードを持ってしまっているということ。

https://www.shtml.jp/mojibake/sjis_cgi.html


# 結論
日本語をファイル名やディレクトリ名に使用すると意図しないトラブルの原因になる。
不具合が生じたら英数字のみを使用するようにしてみて確認する。
MCPでMySQLに接続しAI Agentを作ってみる

## 実現したいこと
- ローカルのMySQL DBにAI Client (Claude Desktop)を接続したい
- 接続の方法はMCP（Model Context Protocol）を利用したい


## 実現方法
- MCPサーバーは[mysql_mcp_server](https://github.com/designcomputer/mysql_mcp_server#)を利用
- [uv](https://docs.astral.sh/uv/)を利用してローカルに仮想Python実行環境を構築
- `python v3.13.2`を利用


## 成果物
- Claudeとの会話キャプチャ: DBの内容を踏まえて回答してくれる
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/cdc5b773-2f2b-438c-b03c-f49d10098d7d.png)
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/37325e25-e277-4bbe-b09a-9314279da985.png)


## 実現方法
1. [mysql_mcp_server](https://github.com/designcomputer/mysql_mcp_server#)をローカルにクローン
    ```:powershell
    git clone https://github.com/designcomputer/mysql_mcp_server.git
    ```
    
1. python仮想環境を構築
    ```:powershell
    python -m venv venv
    ```

1. 仮想環境をアクティベート
    ```:powershell
    venv\Scripts\activate
    ```
    
1. MCP接続に必要なライブラリを仮想環境にインストール
    ```:powershell
    pip install -r requirements.txt
    ```
    requrement.txtの中身：
    ```
    mcp>=1.0.0
    mysql-connector-python>=9.1.0
    ```

1. 環境変数としてMySQLへの接続情報を設定（以下はWindows例）
    ```:powershell
    (venv) PS mysql_mcp_server> $env:MYSQL_USER="<DB user name>"   
    (venv) PS mysql_mcp_server> $env:MYSQL_PASSWORD="<user passsword>" 
    (venv) PS mysql_mcp_server> $env:MYSQL_DATABASE="<database name>"  
    ```

1. MCPサーバの起動
    ```:powershell
    uv --directory <Path to mysql_mcp_server folder> run server.py
    ```

1. Claude DesktopのConfigファイルにMySQLへの接続情報を追加
    ```:claude_desktop_config.json
    {
        "mcpServers": {
            "mysql": {
                "command": "uv",
                "args": [
                    "--directory", 
                    "Path to /mysql_mcp_server/ folder",
                    "run",
                    "server.py"
                ],
                "env": {
                    "MYSQL_HOST": "<MySQL hostname>",
                    "MYSQL_PORT": "3306",
                    "MYSQL_USER": "<DB user name>",
                    "MYSQL_PASSWORD": "<user passsword>",
                    "MYSQL_DATABASE": "<database name>"
                }
            }
        }
    }
    ```

1. Claude Desktop Appを起動する。トンカチのマークを選択し、今回追加した`execute_sql`が表示されていればOK。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/5b399533-c94b-43dc-baed-7b42dbed06a9.png)

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484097/8e428dc1-52cb-4b4c-b96c-7c6348f4f037.png)



## ハマりポイント
- 仮想Python環境にも環境変数としてDBへの接続情報を入力することを忘れていた。
- Claude Desktop App側のConfigファイルを修正したら一度アプリを終了して再度立ち上げる必要があった。
Coral Cloudの設定続き(権限セット、サンプルデータ、Coral Cloudサイトのインストール)

前回は、Coral Cloud Resortsデモ環境をインポートしました。

https://qiita.com/Mijinko-kun/items/fc8cc2bc1817f8e09f93


今回は、インポート後の設定を行っていきます。

## 権限セットで、自分に割り当て

設定から、[Coral Cloud]という権限セットを開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2716146/5ee3f3fa-28f1-4938-9779-6380da060599.png)

[割り当ての管理]から自分自身のAdminユーザーを設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2716146/f3a824ff-2439-4e94-ad2b-79bd87ad7b83.png)


## サンプルデータのインポート

[Sample Data Import]アプリケーションを開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2716146/7a3bb84c-3bee-4a50-9000-872b9ac5d935.png)

[Import Sample data]ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2716146/2a11a429-555b-4524-bed3-2c01bbe9c904.png)

Coral Cloud Resortsアプリを開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2716146/78e8b1a6-1e11-4dbd-a9f5-684c000141b8.png)

どのデータがインポートされたのか、定かではありませんが、問題なさそうです。


## Expericence Cloudサイトのインストール

設定の[デジタルエクスペリエンス]の設定を開き、エクスペリエンスクラウド(Webサイト)を有効化します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2716146/d70c407c-884b-4818-8f1d-48515ebf00b2.png)

同じページでリロードすると、設定が増えているので、[Enable ExperienceBundle Metadata API]をONにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2716146/5e2bb8b6-1537-44f8-9499-2795073ab3be.png)


### Coral Cloud Experience Cloud サイトのインストール
次に次のURLから、パッケージで、サイトをインストールします。


```
https://xxx.develop.lightning.force.com/packaging/installPackage.apexp?p0=04tWx0000001fqjIAA
```


管理者でインストールします。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2716146/0ecc9418-6c7a-4fe8-a99c-c62437d2ab6e.png)

今回はすぐにインストールが完了します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2716146/ca9267c6-8725-4746-b0fc-7453a6ae7508.png)


Auraサイトが作られています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2716146/a40a0fc9-7bf5-4929-9af7-ff5137a2b9a4.png)

ビルダーで開くことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2716146/8462c85e-229d-47f1-8747-358fd3d1654f.png)


以上です。

次回は、Coral Cloud リゾートがどういうものなのか、対象とする領域をみていきます。

https://qiita.com/Mijinko-kun/items/ba6679abc3249d110b74
Qwenをローカルで使ってみた。

### Qwenとは
Qwenとは、Alibaba（アリババ）が開発したLLMシリーズの一つで、優秀と評判のモデルです。

### llama.cpp
llama.cppとは、LLMを、CPUだけで軽量かつ高速に動かせるようにするC++ライブラリです。


## 概要
以上の2つを利用してローカルにAIエージェントを作成し、日本語の文章作成をさせました。


## 結果

**良い点**
・出力が安定している。
・トークンを増やしても、認識してくれる。
**悪い点**
・めっちゃ文字化けする
・中国語をよく出力する
・出力結果や入力文を繰り返す

## 具体的な症状
#### 中国で作成されたモデルのためか、中国語出力へ偏りが見られる
・日本語で聞いても中国語で出力される
・漢字が多いと、中国語と勘違いする
・単語を中国語で出力しようとする→文字化けする
→[対策] 同じ内容を再度出力してもらう（内部で日本語解釈をしてくれて修正される）

#### ひたすら繰り返す
・出力上限のトークン数に至るまで、出力を繰り返すことがわかった
→[対策] 出力を終了したら「。終了」と入力してもらい、後処理で消す

## まとめ
- 現時点のQwenは正確な日本語出力には向いていない
- 精度や文脈を読み取ることはできるため、個人でのローカル利用はアリかも