OmniAICreator/Qiita-1.07M huggingface dataset:
.NET9のWPFアプリを爆速で作る　アップデート編

## 概要
Windowsアプリを作成するにあたり、アップデート機能は煩わしいポイントの1つです。
そんなアップデート機能を、手間なく実装する方法を紹介します。

## サンプルコード
https://github.com/umbreon-nu/fluent-app-win

## 方法
### アプリ側
AutoUpdater.NETを使用します。

https://github.com/ravibpatel/AutoUpdater.NET

AutoUpdater.NETは、NuGetパッケージから追加できます。

![スクリーンショット 2025-02-27 102946.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3722996/80df2e44-56ad-4763-88b2-7e1c86172d31.png)

パッケージ追加後、UIスレッドから`AutoUpdater.Start()`を呼び出します。  
以下のように記述すると、メインウィンドウがロードされた後に、バージョンアップがあればバージョンアップの通知ダイアログが表示されるようになります。

```MainWindow.xaml.cs
using System.Windows;
using AutoUpdaterDotNET;

namespace WpfApp1.Views
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            Loaded += MainWindow_Loaded;
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            // FIXME: AutoUpdater.NETのサンプルなので、アップデートサーバーに配置したXMLを指定してください
            AutoUpdater.Start("https://rbsoft.org/updates/AutoUpdaterTest.xml");
        }
    }
}

```

基本的なアプリ側の設定としては、これだけです。

:::note
スキップボタンを非表示にしたり、後でボタンを非表示にしたり、強制的にアップデートさせる設定があります。
各種設定については、AutoUpdater.NETのREADMEに詳しく記載されています。
:::

あとは、アップデートサーバーにXMLファイル、リリースノート、インストーラーを配置するだけで完了します。

### アップデートサーバー側
#### XMLファイル
アップデートの情報が記述されたファイルです。
このファイルをアプリが読みに行きます。
最低限必要な情報は、バージョンと、インストーラーのURLです。

```UpdateInfo.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- AutoUpdater.NETのREADMEから抜粋 -->
<item>
  <version>2.0.0.0</version>
  <url>https://rbsoft.org/downloads/AutoUpdaterTest.zip</url>
  <!-- リリースノートの場所を指定するchangelogは任意らしい -->
  <changelog>https://github.com/ravibpatel/AutoUpdater.NET/releases</changelog>
</item>
```

#### インストーラー
XMLファイルの`url`要素で指定したURLに、インストーラーを配置します。

#### リリースノート
XMLファイルの`changelog`要素で指定したURLにリリースノートを配置します。

## AutoUpdaterの挙動

![スクリーンショット 2025-02-27 104225.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3722996/0e0ff292-4440-49f6-80ea-16badf411640.png)

#### 「アップデート」ボタンを押した場合
インストーラーがダウンロードされ、実行されます。

#### 「スキップ」ボタンを押した場合
アップデート可能なバージョンがレジストリ
`\HKEY_CURRENT_USER\Software\<CompanyName>\<AssemblyName>\AutoUpdater\SkippedVersion`
に書き込まれます。

:::note
AutoUpdaterの設定で、特定のJSONファイルに書き込むよう変更できます。
:::

このバージョンでは、自動アップデートのダイアログが表示されなくなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3722996/2a46b93a-f856-4a47-8dc4-ec1d96cdfa57.png)

#### 「後で」ボタンを押した場合
以下のダイアログが表示され、「OK」を押すとレジストリ
`\HKEY_CURRENT_USER\Software\<CompanyName>\<AssemblyName>\AutoUpdater\RemindLaterAt`
に書き込まれます。

:::note
AutoUpdaterの設定で、特定のJSONファイルに書き込むよう変更できます。
:::

書き込まれた時刻までは、自動アップデートのダイアログが表示されなくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3722996/9f5f2891-4c8a-4a54-ab9c-7fd75d398bad.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3722996/b70cb10c-2d3f-4d7a-965e-28921827f9c3.png)

## つづく
https://qiita.com/umbreon-nu/private/7386cd9012a90d7e2b7d
文書埋め込みモデル（SBERT など）とは？

## はじめに
近年、自然言語処理（NLP）の分野では、文書埋め込み（Document Embedding）が注目されています。特に、**Sentence-BERT（SBERT）** の登場により、文レベルの意味理解が大きく向上しました。本記事では、**Sentence-Transformers** ライブラリを中心に、文書埋め込みの基本概念、モデルの仕組み、応用例、実装方法について詳しく解説します。

---

## 文書埋め込みとは？
文書埋め込みとは、テキストを**数値ベクトル**に変換する手法です。これにより、機械が文書の意味を理解しやすくなり、検索・分類・クラスタリングなどの様々なタスクに活用できます。

従来の手法としては、以下のようなものがあります。
- **Bag-of-Words（BoW）**：単語の出現回数をベクトル化
- **TF-IDF**：単語の重要度を考慮したベクトル化
- **Word2Vec, GloVe, FastText**：単語レベルの埋め込み
- **Universal Sentence Encoder（USE）**：文レベルの埋め込み

しかし、これらの手法では**文脈の違いや語順の重要性が考慮されにくい**という問題がありました。

---

## SBERT（Sentence-BERT）とは？
SBERT（Sentence-BERT）は、BERT（Bidirectional Encoder Representations from Transformers）を基盤とした文書埋め込みモデルであり、文レベルの意味理解を強化するために設計されました。

### 特徴
- **BERTを基にした文ベクトル生成**：通常のBERTでは、単語単位の埋め込みしか取得できませんが、SBERTでは**文全体を表す固定長のベクトル**を取得できます。
- **Siamese Network構造**：ペアになった文を入力し、類似度を計算することで学習を行う。
- **効率的な類似度計算**：SBERTで埋め込んだベクトルは、コサイン類似度を使って簡単に比較可能。

### 仕組み
1. **入力文のトークナイズ**：SentencePieceやWordPieceを用いてトークナイズ。
2. **Transformerエンコーダを通過**：BERTのようなモデルを通じてコンテキストを考慮した特徴量を取得。
3. **Pooling処理（[CLS]トークンや平均プーリング）**：固定長の文ベクトルを生成。
4. **類似度計算や分類タスクに利用**。

---

## Sentence-Transformers ライブラリ
SBERTを簡単に利用できるライブラリが **Sentence-Transformers** です。

### インストール
```bash
pip install sentence-transformers
```

### 使い方
以下のコードで簡単に文書埋め込みを取得できます。
```python
from sentence_transformers import SentenceTransformer

# モデルのロード
model = SentenceTransformer('all-MiniLM-L6-v2')

# 文章のリスト
sentences = [
    "私は自然言語処理が好きです。",
    "機械学習の応用範囲は広がっている。"
]

# 埋め込み取得
embeddings = model.encode(sentences)

# 結果表示
print(embeddings.shape)  # (2, 384) -> 2つの文、それぞれ384次元のベクトル
```

### よく使われる事前学習モデル
- `all-MiniLM-L6-v2`（軽量かつ高性能）
- `paraphrase-MiniLM-L12-v2`（パラフレーズ対応）
- `multi-qa-MiniLM-L6-dot-v1`（質問応答向け）

---

## SBERTのファインチューニング
### 必要なライブラリのインストール
```bash
pip install torch transformers datasets sentence-transformers
```

### データの準備
ファインチューニングには、ペアになった文とその類似度スコア（0〜1の範囲）が必要です。
```python
from sentence_transformers import InputExample, losses
from torch.utils.data import DataLoader

train_samples = [
    InputExample(texts=["この映画は最高です。", "この映画はとても良い。"], label=0.9),
    InputExample(texts=["この映画は退屈だった。", "この映画は面白くなかった。"], label=0.8),
    InputExample(texts=["この映画は面白い。", "今日はいい天気です。"], label=0.1)
]

train_dataloader = DataLoader(train_samples, shuffle=True, batch_size=8)
```

### モデルの設定と学習
```python
from sentence_transformers import SentenceTransformer, losses

model = SentenceTransformer('all-MiniLM-L6-v2')
train_loss = losses.CosineSimilarityLoss(model)

# モデルのトレーニング
model.fit(train_objectives=[(train_dataloader, train_loss)], epochs=1, warmup_steps=100)
```

### ファインチューニング済みモデルの保存と読み込み
```python
model.save("fine_tuned_sbert")
model = SentenceTransformer("fine_tuned_sbert")
```

---

## まとめ
Sentence-Transformers（SBERT）は、文書埋め込みを高精度かつ効率的に行える強力なツールです。特に、意味的類似度の計算や自然言語処理タスクへの応用において、大きな利点を持っています。

### 本記事のポイント
✅ 文書埋め込みとは？
✅ SBERTの特徴と仕組み
✅ Sentence-Transformersライブラリの使用方法
✅ SBERTのファインチューニング方法
✅ 代表的な応用例（検索・クラスタリング・分類）

実際のプロジェクトに応用し、より高精度な自然言語処理を実現してみてください！
AWSレイヤのコスト削減ばかりに目が行きがち

# 前置き
AWSを運用する上で、AWSは従量課金なので、無駄を省くコスト削減は大切かと思います。
Trusted Advisorやコスト最適化ハブなどでコストを最適化することばかりに目が行きがちでした。

# 本題
契約しているAWSサポートのプランは適切ですか？
AWSサポートは４つのプランがあります。
https://aws.amazon.com/jp/premiumsupport/pricing/
個人的な感覚では、商用利用している場合でもだいたい「ビジネス」プランで十分だと思っています。

とある企業様では、小規模システムなのに「エンタープライズ」プランのサポートプランを契約しており、このプランはげつがく最低15,000USDもします。（高すぎだろ）

生成AIに「ビジネス」と「エンタープライズ」プランの違いについて聞いたところ、以下でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4021557/a2c33247-7f21-48c6-8e83-12c3019d2542.png)

# まとめ
ミッションクリティカルなシステムや大規模システムなら「エンタープライズ」プランの契約はわかるが、Trusted Advisorの機能もすべて使えるし、「ビジネス」プランがコスパ良いので、AWSレイヤのコスト最適化ももちろん大切なんだけど、それ以外に無駄なコストが発生していないかを見直すのも大事だよね。と思いました。
PCで正体不明の何かが悪さをしていると感じた時の対処方法

# PCが重い


ある日、急にPCが重くなりました。
ファイルを開くのに数分かかり、電話会議などできたものではありません。
長時間かけてWindows Updateをしてみたけど改善せず。
パフォーマンスモニターを見ても負荷が高いということしかわからず。
きっと裏で何がなんかやってるんだろうな、とは思うものの、有効な対処方法がわかりませんでした。

そんなときに有効な対処となり得るのが、クリーンブートになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818349/c96fcd5f-f1ae-458e-9164-230ea7873d72.png)

# クリーンブートとは
クリーンブートはドライバーやスタートアッププログラムを必要最低限にして Windows を起動させるものになります。
PCが重くなっている原因となるものが動かない状態で Windows を起動できる可能性があるため、切り分けの1つとして有効です。

セーフモードは Windows の基本的なファイルとドライバーのみが読み込まれた状態で起動するため、機能がかなり限定的な状態で起動してきますが、クリーンブートは通常の Windows 起動で余計なものを起動させないだけなので、Windows としての機能の制限が少なくてすみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818349/fffaffc6-5262-4c78-84f2-454fde13840c.png)

# クリーンブートのやり方
1．クリーンブートの実行のためにはスタートメニューから[システム構成]を選択します。

(※今年サポート終了ですが、会社のPCが Windows 10 のため、Windows 10 での説明となっています。Windows 11 でも大まかな手順は一緒です)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818349/52de4bff-3d05-41fb-953b-0582fa08dcc6.png)


2．システム構成の画面の[サービス]タブで[Microsoft のサービスをすべて隠す]にチェックを入れます。これにより、一覧から Microsoft のサービスが非表示になります。

3．[すべて無効]をクリックして、一覧のすべてのチェックボックスにチェックを入れます。

4．[適用]をクリックして設定を適用させます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818349/8ad141a1-5f94-4791-ab1d-80008ea289c7.png)

5．システム構成の画面の[スタートアップ]タブで[タスクマネージャーを開く]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818349/1db8f1c3-f0b8-4e9b-b4fd-4c03a911c337.png)

6．タスクマネージャーの画面が開きますので、ここで状態が有効となっているものをすべて無効にします。

7．すべて無効にしたらタスクマネージャーを閉じます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818349/2e97d158-0cc8-4623-a4f3-56a9484cb93e.png)

8．システム構成の画面で[OK]をクリックします。

9．Windows を再起動するとクリーンブート環境で起動します。

10．これで問題が解消した場合は手順2～7で無効にしたものを有効にしていき、事象の再現有無で原因を特定できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818349/76dc0276-85ce-4fbf-b3f7-e371d84421c1.png)

クリーンブートはPCが重い事象以外でも問題の切り分けに役立ちます。
例えば Windows Update が更新に必要なファイルを何らかのアプリケーションが掴んでいて失敗する事象に遭遇した場合、クリーンブートで起動した状態で Windows Update を実行することで、問題を回避できることがあります。

# クリーンブートのその他の使い方
クリーンブートはPCが重い事象以外でも問題の切り分けに役立ちます。
例えば Windows Update が更新に必要なファイルを何らかのアプリケーションが掴んでいて失敗する事象に遭遇した場合、クリーンブートで起動した状態で Windows Update を実行することで、問題を回避できることがあります。
ワンランク上の市民開発者になろう ~ 環境周り編 ~

Power Platform をご利用いただく中で、最初は見よう見まねでキャンバスアプリや自動化フローを作っていたところから、スキルが上がってきてより複雑なものや最新機能を取り入れたものを作る人も多いのではないでしょうか。

その際に、最低限環境周り設定しておきたいことを列挙してみたいと思います。
（主に開発者目線です）

# 開発環境を利用する
開発環境は「個人」向けの環境で、他の人に共有はできないのですが、Dataverse テーブルや Power Apps アプリを作って自分で検証することができます。会社でご利用される場合は、[DLP ポリシー](https://learn.microsoft.com/ja-jp/power-platform/admin/wp-data-loss-prevention)や[環境ルーティング](https://learn.microsoft.com/ja-jp/power-platform/admin/default-environment-routing?tabs=new)を整備した上で利用者に開放となるケースが多いかと思いますが、利用者は環境設定や Dataverse 容量の制約のないこの環境を使い倒しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/79e1a12e-9719-4c16-a262-d26a86c11514.png)

# 開発環境の各種設定をとりあえずオンにしてみる
開発環境のシステム管理者はご利用者になります。
そこで Power Platform の最新の機能（Wave）を有効化したり、細かい設定を有効化して、どんどん最新の機能を使い倒しましょう。

[設定場所] Power Platform 管理センター > 管理 > 環境 > みなさま個人の開発環境
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/0cbc96cb-dae2-450c-9374-02a19d9b1f32.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/36f02057-6f8a-4293-9f2d-fd0c0c4c6023.png)

# ソリューションを利用して開発する
ソリューションは Power Platform で作成した資材を格納する箱のようなものです。例えば複雑な Power Apps アプリを作ろうとすると Power Automate フローや Dataverse テーブルなど別の製品に跨ってくるケースが多いので、ソリューションとして一つにまとめることで、アプリ（システム）全体として管理することが可能になります。
（既定の環境でやろうとすると、色んな人が似たようなアプリやテーブルを作っていたり、識別に時間がかかったりして煩わしいですよね...）

さらにソリューションにしておくと別環境に移送することが容易になるので、開発環境で作成したアプリを、多くの人に使ってもらうために別環境に移送するといった作業が、安定的かつ効率的に実施いただけます（いわゆる ALM というやつです）。

※一つのアプリを開発してから運用するまでをきちんとやろうとすると以下のようなタスクが発生するかと思いますが、利用者が多い・組織として重要なアプリを開発するときには意識されたほうが良いかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375815/5b48b3f2-9609-4f99-a167-0529a6438c4c.png)

以上ご参考になれば幸いです。
Web APIシリーズその3(全5回)：Swaggerで型安全なAPI呼び出しを！

## REST APIの利点と不足
- REST APIはシンプル！アクセスしやすさが大きな魅力
- 一方で具体的なデータ型などを示す仕様には欠ける

----
## そこでSwagger
- SwaggerはREST APIの仕様を記述するもの、及び周辺ツール

----
## Swaggerの運用
- APIサーバから仕様をSwaggerファイルとして提供する
   - どのようなAPIがあるのか、そのURLは何か
   - どのような操作が可能か
   - **入力や出力のデータ型はどんなか**
- クライアントはSwaggerを見ながらAPIにアクセスする
- **クライアントのコード生成が有用**

----
## 補足・SwaggerとOpenAPI
- Swaggerは、現在ではOpenAPIと呼ぶのが正しいようです
- OpenAPI Initiativeという団体にSwaggerの成果が寄贈されたようです

----
## Swaggerを試す
- [Swagger Editor](https://editor.swagger.io/)
- swagger-typescript-api
  TypeScriptクライアントはこのツールで生成したものが使いやすい感じ

----
## Swaggerをどうやって提供するか：C#の場合
- Debugモードで起動したときにSwaggerが見られるように構成できる

----
## Swaggerの注意点
- 場合によってはAPI仕様を晒さない方がよい
  企業向けのシステムなど

----
## 最後に
- Swaggerを利用するとAPI呼び出しが非常に簡単になる
- クライアントが利用しやすいSwaggerとなるよう、API実装を工夫することには価値がありそう
【Python】毎週勉強するシリーズ ～タプル～

# 概要
AI が流行ってる昨今 Python は必須級のスキルになってきてます。
時代に取り残されないようにコツコツと Python を勉強しようと思います！
三日坊主にならないように Qita でアウトプットしながら進めます💪

# 今日やること
[とほほのPython入門 - リスト・タプル・辞書](https://www.tohoho-web.com/python/list.html) のタプルを理解する。

# タプル(tuple)

### 1. 基本的な書き方
`(...)` でタプルを表します。
タプルはリストとほぼ同じように使用できますが、要素を変更できない点が異なります。

```py
a = (10, 20, 30, 40)
```

### 2. 要素がひとつだけな場合の書き方
要素がひとつだけの時は、最後にカンマ(,)を記述する必要があります。

```py
a = (10)                # タプルではなく数値の10となる
a = (10,)               # タプルの(10,)となる
```

これはちょっと混乱しますね…
個人的な解釈としては、「`()` で囲まれたものがタプル」というより「カンマで区切られたもの」と捉える方が腑に落ちます。

気になって調べたら、`()` は省略できるらしく解釈は合っているみたいです。
```py
a = 10, 20, 30, 40
```

### 3. タプル要素を変更する
リスト要素と違って、タプル要素を変更することはできません。

```py
a1 = [10, 20, 30, 40]
a2 = (10, 20, 30, 40)

a1[2] = 60              # 代入できる
a2[2] = 60              # エラーとなり、TypeError例外が発生する
```

### 4. タプルをリストに変換する
タプルからリストに変換するには `list()` を使います。

```py
print(list((1, 2, 3)))    #=> [1, 2, 3]
```

### 5. リストをタプルに変換する
リストからタプルに変換するには `tuple()` を使います。

```py
print(tuple([1, 2, 3]))   #=> (1, 2, 3)
```

### 関数の戻り値としてタプルを返却する
関数の戻り値としてタプルを返却することもできます。
```py
def get_date():
    return 2022, 10, 9

year, month, day = get_date()
print("%04d/%02d/%02d" % (year, month, day))   # 2022/10/09
```

ふむふむ。JavaScript で言う分割代入ですね。
これは慣れているのでイメージつきやすいです。
```js
const [year, month, day] = [2022, 10, 9]
console.log(`${year}/${month}/${day}`)   // 2022/10/09
```

# 感想
今日はタプルをやってみました！

リストとタプルの違いは以下であると分かりました。
- リスト：動的な配列。値や要素数の変更が可能。
- タプル：静的な配列。値や要素数は固定で変更不可。

使い分けは「変更する必要があるか」を基準に考えれば特に問題なさそうですね👀

今回も見ていただきありがとうございました。
また次回お会いしましょう！！

# 次回やること
[とほほのPython入門 - リスト・タプル・辞書](https://www.tohoho-web.com/python/list.html) の辞書を理解する。
pnpmで管理しているプロジェクトをfirebase hostingにデプロイする時のgithub Workflow file

Github workflowの環境にはデフォルトで`pnpm`が入っていないため、firebase hostingの設定中に、CLIに聞かれるままbuildスクリプトで`pnpm build`を指定するとコケるので、workflow fileを書き換えてやる必要がある。

### 参考↓

https://pnpm.io/continuous-integration#github-actions

上記を参考にautogeneratedのworkflowファイルと組み合わせたものが以下

```yaml

name: Deploy to Firebase Hosting on merge
on:
  push:
    branches:
      - main
jobs:
  build_and_deploy:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [20]
    steps:
      - uses: actions/checkout@v4
      - name: Install pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 10
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: "pnpm"
      - name: Install dependencies
        run: pnpm install
      - name: Build
        run: pnpm build
      - uses: FirebaseExtended/action-hosting-deploy@v0
        with:
          repoToken: ${{ secrets.GITHUB_TOKEN }}
          firebaseServiceAccount: ${{ secrets.xxxxxxxxxxxx }}
          channelId: live
          projectId: some-project-id
```

今んとこはこれでうまく行ってます。
AWS DMS タスクの新規作成

AWS DMS (Database Migration Service) で移行タスクを使い回せず、新規でタスクを作成する必要があるケースは以下の通りです。
	•	異なるエンドポイントを使用する場合
	•	ソースまたはターゲットのデータベースが変更される
	•	エンドポイントの認証情報や接続設定を変更する必要がある
	•	移行タイプが異なる場合
	•	全量移行（full load）から継続的レプリケーション（CDC）への変更
	•	増分レプリケーションのみ（CDC）のタスクを新たに作成する場合
	•	テーブルマッピングやフィルタリング条件を変更する場合
	•	特定のテーブルやカラムのみ移行する設定を変更する場合
	•	データのフィルタリング条件を変更する場合
	•	変換ルール（データ変換や列マッピング）を変更する場合
	•	特定のデータ型を変換するルールを新たに追加・変更する場合
	•	カラムのマッピング設定を変更する場合
	•	DMSタスクの設定（バッチサイズ、スロット数、並列処理など）を変更する場合
	•	パフォーマンスチューニングのために設定を変更する場合
	•	タスクのリカバリ動作やエラーハンドリング設定を変更する場合
	•	DMSのバージョンやエンジン設定が変更された場合
	•	DMSのエンジンがアップグレードされ、既存タスクでは互換性の問題が発生する場合
	•	ソースまたはターゲットのデータベースバージョンが変わり、互換性が影響する場合
	•	既存のタスクが失敗し、修正が困難な場合
	•	タスクの内部エラーや一部データの不整合により、再実行しても問題が解決しない場合
	•	ログを確認しても明確な原因が特定できず、クリーンな状態で再実行したい場合

このような場合、新規のDMS移行タスクを作成するのが推奨されます。
cursorが起動しなくなった時の対処法を画像一枚で

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3527006/05045230-ee11-4ed1-9f38-42ec8371e1df.png)

これ起動したら１分で直った。

1. `C:\Users\（ユーザー名）\AppData\Local\cursor-updater` に移動
2. `cursor-updater.exe` を実行
   ```
   C:\Users\（ユーザー名）\AppData\Local\cursor-updater
   ```
Nuxt.js v3 .nu​​xtignore で generate 時に生成させないファイルを指定する

## 目的
デバッグ用のページを削除せずに、本番用のビルド時にhtmlを生成させない

## 使用ファイル

[.nu​​xtignore](https://nuxt.com/docs/guide/directory-structure/nuxtignore) を開発用(ファイルは未指定)とジェネレート用(除外したいファイルを指定)を用意する

```.nu​​xtignore.local
```


```.nu​​xtignore.prod
pages/debug/index.vue
```


```package.json
{
  "scripts": {
    "dev": "cp .nuxtignore.local .nuxtignore && nuxt dev",
    "generate": "cp .nuxtignore.prod .nuxtignore && nuxt generate"
  },
```


```.gitignore
.nu​​xtignore
```
Laravel忘備録-重複を削除し最新のレコードを取得-

重複を削除し、最新のレコードを取得する機会があったため忘備録として記録に残そうと思います。

# 想定するデータ

purchase_historiesテーブル
購入履歴のようなテーブルを想定しています。

```sql:purchase_histories
+---------------+---------------------+------+-----+---------+----------------+
| Field         | Type                | Null | Key | Default | Extra          |
+---------------+---------------------+------+-----+---------+----------------+
| id            | bigint(20) unsigned | NO   | PK  | NULL    | auto_increment |
| user_id       | bigint(20) unsigned | NO   | FK  | NULL    |                |
| product_id    | bigint(20) unsigned | NO   | FK  | NULL    |                |
| created_at    | timestamp           | YES  |     | NULL    |                |
| updated_at    | timestamp           | YES  |     | NULL    |                |
+---------------+---------------------+------+-----+---------+----------------+
```

# ユーザーが最も最近購入した商品を取得したい

手順
1. `purchase_histories`テーブルから`user_id`の重複を削除し、で`created_at`が最も新しいレコードを取得する
2. 1.で取得した`user_id`、`created_at`と等しいレコードを同じく`purchase_histories`テーブルを使い`JOIN`する
3. 2.で`JOIN`した結果を受け取る

上記の手順でユーザー(`user_id`)の重複を削除し、直近購入した商品(`product_id`)を取得することができます。

```php:code
// user_idの重複を削除し、created_atが新しいレコードを取得
$users = DB::table('purchase_histories')
            ->select('user_id', DB::raw('MAX(created_at) as last_created_at'))
            ->groupBy('user_id');

// 上記で取得したuser_idとcreated_atが一致するレコードを同じテーブルにJOINする
$latestPurchases = DB::table('purchase_histories')
            ->joinSub($users, 'users', function ($join) {
                $join
                    ->on('purchase_histories.user_id', '=', 'users.user_id')
                    ->on('purchase_histories.created_at', '=', 'users.last_created_at');
            })->get();
```

# Where句でレコードを絞りたい
where句に`user_id`を指定した場合に以下のエラーが返ってきました。
where句が曖昧です。と怒られます。

`SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'user_id' in where clause is ambiguous`

テーブル名を指定しないとどっちの`user_id`を使えば良いかわからない。
と怒られるようです。

```php:修正前
$latestPurchases = DB::table('purchase_histories')
            ->joinSub($users, 'users', function ($join) {
                $join
                    ->on('purchase_histories.user_id', '=', 'users.user_id')
                    ->on('purchase_histories.created_at', '=', 'users.last_created_at');
            })
            ->where('user_id', '=', '1234') // <-ここで怒られます
            ->get();
```

```php:修正後
$latestPurchases = DB::table('purchase_histories')
            ->joinSub($users, 'users', function ($join) {
                $join
                    ->on('purchase_histories.user_id', '=', 'users.user_id')
                    ->on('purchase_histories.created_at', '=', 'users.last_created_at');
            })
            ->where('purchase_histories.user_id', '=', '1234') // <-テーブル名を明示します
            ->get();
```

# 参考資料

https://qiita.com/harluz06/items/6f35cb61e5af368ce724

https://readouble.com/laravel/9.x/ja/queries.html

→ サブクエリのJOINを参照

# 告知

最後にお知らせとなりますが、イーディーエーでは一緒に働くエンジニアを
募集しております。詳しくは採用情報ページをご確認ください。

https://eda-inc.jp/recruit/

みなさまからのご応募をお待ちしております。
個人的備忘録：「504 Gateway Time-out」エラーの一般的な原因と対策を体系的にまとめてみた

## はじめに
Web サイトやアプリケーションを運用していると、エラーに遭遇することは避けられません。

:::note note
**その中でも「504 Gateway Time-out」というエラーは、サーバーの応答遅延が原因で発生することが多く、特にリバースプロキシやロードバランサーを利用している環境では頻発することがあります。**
:::

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

## 記事を書こうと思ったきっかけ
受講しているハッカソンの活動中に、他の受講生が 504 Gateway Time-out エラーに直面していました。

:::note warn
***原因の特定や解決に苦労している様子を見て、一緒に調査を進める中で多くの知見を得ることができました。***
:::

同じ問題に悩む方の助けになればと思い、この記事を書くことにしました。

## 504 Gateway Time-out エラーの原因と対処法

Web サイトやアプリケーションを運用していると、「504 Gateway Time-out」というエラーに遭遇することがあります。

このエラーは、ゲートウェイ（リバースプロキシやロードバランサー）が、バックエンドサーバーからの応答を受け取れず、一定時間が経過したために発生します。

本記事では、504 Gateway Time-out エラーの主な原因と具体的な対策について解説します。

### **1. サーバーの処理遅延**
#### **原因**
- サーバーの負荷が高すぎる
- 実行時間の長いスクリプトやクエリがある

#### **対策**
- サーバーのリソース使用状況を確認（`top` や `htop` コマンドを使用）
- 負荷が高い場合はリソースを増強（CPU/RAM のスケールアップ）
- 実行時間の長いスクリプトやクエリを最適化

### **2. サーバー設定（NGINX/Apache）の問題**
#### **原因**
- タイムアウト時間の設定が短すぎる

#### **対策**
- 設定ファイルでタイムアウト時間を延長し、サーバーを再起動

**NGINX の場合 (`/etc/nginx/nginx.conf`)**
```nginx
http {
    proxy_connect_timeout 600;
    proxy_send_timeout 600;
    proxy_read_timeout 600;
    send_timeout 600;
}
```

**Apache の場合 (`/etc/httpd/conf/httpd.conf` または `/etc/apache2/apache2.conf`)**
```apache
Timeout 600
```

### **3. バックエンド（アプリケーション）の問題**
#### **原因**
- アプリケーションの処理が遅い

#### **対策**
- アプリケーションのログを確認（`/var/log/app.log` など）
- 遅い処理の最適化（キャッシュの活用、並列処理の導入）
- データベースクエリのチューニング

### **4. データベースの応答遅延**
#### **原因**
- クエリの実行時間が長い

#### **対策**
- `EXPLAIN` を使ってクエリを分析し、適切なインデックスを追加
- クエリキャッシュを利用
- 非同期処理やバッチ処理を検討

### **5. クラウド環境での問題**
#### **原因**
- AWS, GCP などのロードバランサーのタイムアウト設定が短い

#### **対策**
- AWS ALB の `Idle Timeout` を延長（デフォルト60秒 → 300秒など）
- AWS Lambda を利用する場合、タイムアウト設定を適切に調整

### **6. ネットワーク接続の問題**
#### **原因**
- ネットワーク遅延や接続障害

#### **対策**
- `ping` や `traceroute` を使ってネットワークの遅延をチェック
- Firewall の設定を確認
- サーバー間通信の経路を見直し

## **まとめ**
「504 Gateway Time-out」エラーは、サーバーの負荷、設定ミス、アプリケーションの処理速度、データベースの遅延、クラウド環境の設定、ネットワークの問題など、さまざまな要因で発生します。

:::note alert
まずは **サーバーの負荷を確認し、設定の見直しや処理の最適化を進める** ことが重要です。
:::

特に **NGINX/Apache のタイムアウト設定やデータベースのチューニング** など、適切な対策を施すことで、このエラーを回避できます。
25年2月に発表されたプロンプト最適化手法「Intent-based Prompt Calibration」


# 2025年2月に発表されたプロンプト最適化の研究


最近仕事で扱った参考文献が面白かったので、メモにしておきます。
タイトル「Intent-based Prompt Calibration: Enhancing prompt optimization with synthetic boundary cases」という論文の内容です。

和訳すると、
**「意図に基づくプロンプト調整: 合成された境界事例を用いたプロンプト最適化の強化」** 

https://arxiv.org/abs/2402.03099


**「Intent-based Prompt Calibration（IPC）」** という​新しい手法、
大規模言語モデルの性能を最大限に引き出し、ユーザーの意図に沿ったプロンプトを自動的に最適化する手法を提案しています。


IPCを日本語で言うと「意図ベースのプロンプト最適化」、
特にAIが誤解しやすいケース（境界事例）を作成し、それを学習させることで、より正確で意図に沿った回答を引き出せるようにします。この辺りがIPCの大きな特徴かもしれません。
めっちゃ簡単に言うと、「AIへの指示を賢く調整して、もっと的確な答えを得られるようにする仕組み」ということっぽいですね。




# IPCの概要

IPCは、ユーザーが"初期プロンプト"を提供し、その初期プロンプトに対して"合成データ"を生成しプロンプトの性能を評価します。
LLMがその性能評価に基づいて、"新たなプロンプト"を提案するというプロセスを繰り返します。
 
 ​このプロセスの繰り返しにより、よりユーザーの意図に適したプロンプトが生成されるというわけです。​特に、「境界事例・モデルが誤りやすいケースを"合成データ"として生成し、それに基づいてプロンプトを最適化する点」が特徴的です。

>  上記論文本文より。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780099/1122a8b7-0a7f-48b2-8abc-380c1586c6e4.png)

論文内の実験では、従来の最先端手法を上回る性能を示したそうで、またシステムの各主要コンポーネントの有効性も検証されています。​他タスクへの適応も簡単になっているようです。


# 詳細は以下Github
 
IPCを使用するための詳細な情報やコードは、以下のGitHubリポジトリ「AutoPrompt」にて公開されています。

https://github.com/Eladlev/AutoPrompt

​詳細な使用手順や依存関係については、リポジトリ内のREADME.mdやドキュメントをご参照ください。​
AutoPromptを活用することで、手動でのプロンプトエンジニアリングの手間を大幅に削減し、モデルの性能を効果的に向上させることが期待できます。

# プロンプトエンジニアリングとの違い

最初にこれを見た時にプロンプトエンジニアリングの進化系っぽいイメージがありました。
正確に言うと、part-ofの関係になります。

プロンプトエンジニアリング は、大規模言語モデルから適切な出力を得るために、プロンプトを設計・最適化する技術全般を指します。これは人間が手動で試行錯誤しながらプロンプトを調整することが一般的です。

一方、IPCは、プロンプトエンジニアリングの中でも「自動化」に焦点を当てたアプローチです。特に、境界事例を合成し、それを利用してプロンプトを最適化することで、ユーザーの意図に沿ったより良い出力を得ることを目的としています。

広義的にIPCはプロンプトエンジニアリングの一部でありますが、特に「最適化手法の自動化」に分類されます。つまり、プロンプトエンジニアリングが広い概念であり、IPCはその中の高度な自動化技術の一つという位置づけになります。


| 項目 | プロンプトエンジニアリング | IPC |
|------|------------------|------------------|
| **定義** | AIの出力を最適化するためにプロンプトを設計・調整する技術全般 | プロンプトを合成データと自動最適化アルゴリズムを用いて調整する手法 |
| **アプローチ** | 手動 or 半自動（人が試行錯誤） | 自動（合成データを活用しAIが調整） |
| **目的** | 適切なAIの応答を引き出す | 境界事例を考慮しつつプロンプトを最適化 |
| **特徴** | 試行錯誤しながら調整 | AIが最適化プロセスを主導 |


# Pythonで使用する手順

AutoPromptのIPC（Intent-based Prompt Calibration）機能をPythonで使用するには、以下の手順を参考にしてください。

## 1. リポジトリのクローンと依存関係のインストール

まず、AutoPromptのリポジトリをローカル環境にクローンし、必要な依存関係をインストールします。

```py
git clone https://github.com/Eladlev/AutoPrompt.git
cd AutoPrompt
```
Pythonのバージョンは3.10以下が推奨されています。

## 2. LLM（大規模言語モデル）の設定

`config/llm_env.yml`ファイル内の`openai_api_key`に、OpenAIのAPIキーを設定します。APIキーの取得方法については、OpenAIの公式サイトを参照してください。
推奨モデルはGPT-4ですが、他のモデルやプロバイダーもサポートされています。​


## 3. アノテーション手法の選択
プロジェクトに適したアノテーション手法を選択します。​人間が介入する方法（Argillaの使用）や、LLMをアノテーターとして設定する方法があります。​

https://githubissues.com/Eladlev/AutoPrompt/readme


## 4. パイプラインの実行
設定が完了したら、以下のコマンドでパイプラインを実行し、プロンプトの最適化を開始します。​

```py
python run_pipeline.py
```
このコマンドは、デフォルトの設定に基づいてプロンプトの最適化を行います。​詳細な使用例や追加のオプションについては、README.md内の「Prompt optimization examples」セクションを参照してください。

# 引用

以下関連文書も置いておきます。

https://arxiv.org/abs/2402.03099

https://arxiv.org/pdf/2402.03099

https://arxiv.org/abs/2402.03099
Kubernetes の CoreDNS 名前解決 と  デバッグ方法について

## 導入

Kubernetes 環境下でシステム連携（Pod 間通信）を行った際に、名前解決で苦労したため、知識の整理をする目的で本記事を執筆します。

## Kubernetes 環境下での名前解決

### Namespace が異なる場合

Kubernetes では、異なる Namespace 間で通信を行う場合、FQDN を使用する必要があります。
`例: service-name.namespace.svc.cluster.local`

異なる Namespace の Service にアクセスする場合、以下のように指定することで名前解決が可能です。
`curl http://my-service.my-namespace.svc.cluster.local:8080`

### 同じ Namespace に属する場合

同じ Namespace 内であれば、Service 名のみで名前解決が可能です。
`例:curl http://my-service:8080`

Kubernetes の DNS は、まず同じ Namespace 内の Service を探索するため、短縮形でも解決されます。


## Kubernetes の Service Discovery の仕組み

### ClusterIP, NodePort, LoadBalancer, Ingress での名前解決の違い

#### ClusterIP（デフォルト）

クラスタ内でのみアクセス可能。
`my-service.default.svc.cluster.local` で名前解決。

#### NodePort

各ノードの固定ポートで外部からアクセス可能。
`http://<NodeIP>:<NodePort>` でアクセス。

#### LoadBalancer

クラウドプロバイダーのロードバランサを使用し、外部アクセスを提供。
パブリック IP を持ち、直接名前解決が可能。

#### Ingress

ドメインベースのルーティングを提供。
`example.com` などのドメイン名でアクセス可能。

#### CoreDNS の仕組み

- Kubernetes では、CoreDNS が DNS 解決を担当しています
  - Service や Pod に対して svc.cluster.local 形式の DNS レコードを提供
  - kube-dns や coredns の Pod がクラスタ内で稼働し、DNS クエリを処理

- 動いているか確認する
  - `kubectl get pods -n kube-system | grep coredns` で CoreDNS の稼働確認が可能

### nslookup, dig, kubectl exec でのデバッグ方法

名前解決の問題をデバッグする際は、以下の方法を試します。

- nslookup コマンドで名前解決を確認
`kubectl exec -it my-pod -- nslookup my-service.default.svc.cluster.local`

- dig コマンドで詳細な DNS 情報を取得
`kubectl exec -it my-pod -- dig my-service.default.svc.cluster.local`

- kubectl exec を使用して Pod 内部から通信テスト
  `kubectl exec -it my-pod -- bash`
  `curl http://my-service:8080`
個人的備忘録：AWS RDS の MySQL に接続する方法と、その際に発生する可能性のあるトラブルシューティングについてまとめてみた

## はじめに

AWS の RDS (Relational Database Service) にホストされた MySQL に接続する際には、適切な設定とトラブルシューティングが必要です。

この記事では、接続コマンドの説明と、接続エラーが発生した場合の確認ポイントを紹介します。

## MySQL 接続コマンド
AWS RDS の MySQL に接続するには、以下のコマンドを実行します。

```sh
mysql -h RDS のエンドポイント -u root -p
```

このコマンドは以下のオプションを指定しています。
- `-h`：RDS のエンドポイント (ホスト名)
- `-u`：ユーザー名 (例: `root`)
- `-p`：パスワードの入力を求めるオプション

パスワード入力を求められるので、適切なパスワードを入力してください。

## 接続できない場合の確認ポイント

### 1. ホスト名 (エンドポイント) の確認
RDS のエンドポイントが正しいか確認します。以下のコマンドで DNS 解決できるかチェックできます。

```sh
nslookup RDS のエンドポイント
```

または、サーバーに接続できるか `ping` コマンドを使用して確認します。

```sh
ping RDS のエンドポイント
```

### 2. セキュリティグループ (SG) の設定確認
AWS RDS は **セキュリティグループ (SG)** の設定によりアクセスが制限されている可能性があります。

- **ポート 3306 が開放されているか確認**
- **アクセス許可された IP に自分の端末の IP が含まれているか確認**

AWS コンソールから **RDS > セキュリティグループの設定** を確認し、アクセス可能な IP を追加します。

### 3. 認証情報の確認
- `-u root` のユーザー名が正しいか
- `-p` で入力するパスワードが間違っていないか
- 必要に応じて `mysqladmin` でユーザー情報を確認

### 4. ファイアウォールや VPN の影響
- **VPN 接続中だとアクセスできない可能性** があります。
- `telnet` コマンドで RDS の MySQL ポート 3306 に接続できるかチェックできます。

```sh
telnet RDS のエンドポイント 3306
```

もし `telnet: Unable to connect to remote host` のようなエラーが出た場合、ネットワークの制限が原因の可能性があります。

### 5. MySQL クライアントのバージョン
RDS の MySQL バージョンとローカルの MySQL クライアントのバージョンが適切であることを確認します。バージョンの違いによる互換性の問題が発生することがあります。

```sh
mysql --version
```

## まとめ
AWS RDS の MySQL に接続する際に問題が発生した場合、以下の点を確認しましょう。

1. **ホスト名 (エンドポイント) が正しいか**
2. **セキュリティグループの設定が適切か (ポート 3306 開放、アクセス許可 IP の確認)**
3. **認証情報 (ユーザー名、パスワード) が正しいか**
4. **ネットワーク制限 (VPN、ファイアウォール、telnet での接続確認)**
5. **MySQL クライアントのバージョンが適切か**

このように、順番に確認することで接続問題の原因を特定し、適切に対処できます。
[Flutter] You have popped the last page off of the stack, there are no pages left to show

# 前提

go_routerを使用しています

# エラー

```zsh
You have popped the last page off of the stack, there are no pages left to show
```

# エラー発生箇所

以下のようなダイアログで `Navigator.pop(context)` を実行したところ上記エラーが発生島下

```dart
await showDialog(
  context: context,
  builder: (context) {
    return CupertinoAlertDialog(
      title: const Text('これはダイアログです'),
      actions: [
        TextButton(
          onPressed: () async {
            Navigator.pop(context);
          },
          child: const Text('戻る'),
        ),
      ],
    );
  },
);
```

# 解決方法

`GoRouter.of(context).pop()` を使う

```dart
await showDialog(
  context: context,
  builder: (context) {
    return CupertinoAlertDialog(
      title: const Text('これはダイアログです'),
      actions: [
        TextButton(
          onPressed: () async {
            GoRouter.of(context).pop(); // これ
          },
          child: const Text('戻る'),
        ),
      ],
    );
  },
);
```
```
New Relic アップデート(2025年1月)

2025年1月のNew Relic のアップデートをまとめて紹介です！他アカウントのテレメトリデータを参照してアラート条件を作成できるようになりました！

## [Alerts] 他アカウントのデータを利用してアラート条件を作成
他アカウントのテレメトリデータを参照してアラート条件を作成できるようになりました。例えば、インフラ部門と開発部門でアカウントが別れているときにAPMなどの違反をインフラ部門のアラート条件で検知できるようになります。
![update202501-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3485441/b453b4ce-222f-465f-af9e-eb0c6221db79.png)

## [Logs] ログ解析ルールで Key-Value型データのパースが可能に
ログ解析ルールでKey-Value型のログメッセージを解析できるようになり、ルールで抽出したKey-Valueをログデータの属性として追加できるようになりました。これにより、多様なログデータから必要な常用をより簡単に抽出して分析可能になります。
![update202501-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3485441/b7f3b594-9141-4b0e-9d8e-898ad98b488f.png)

## [Dashboard] Mermaid記法で視覚的な表現が可能に
ダッシュボードのMarkdownエディタでMermaid記法で、様々な図をテキストで記述できるようになりました。簡単なテキスト入力で図を作成でき、ダッシュボードにアーキテクチャやワークフローの視覚的な表現を加えることで、データの理解が容易になり、情報を迅速に把握可能になります。
![update202501-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3485441/421d653a-5f34-4093-89a5-1e2d791699e0.png)

## [Browser] カスタムイベントAPIでユーザー行動の詳細を分析可能に
Browser エージェントで、ユーザーのブラウザ操作をカスタムイベントして記録できるようになり、パフォーマンスデータ、エラー情報などのユーザー体験の指標とあわせて、ブラウザ上でのユーザ行動の追跡と分析が可能になりました。
![update202501-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3485441/bd718524-0823-4f88-8e48-4d1c7d4826ba.png)

## [Query Builder] Data ExplorerでLookupテーブルを使ったNRQLを作成可能に
アップロードしたLookupテーブルをData explorerからデータを確認したり、分析のベースとなるNRQLの作成ができるようになりました。また、アカウント毎に登録できるLookupテーブルが20個から250個に拡大しました。
![update202501-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3485441/e49b9f2d-7c5e-4343-9d82-983657748f4f.png)

## [Synthetics] プライベートネットワーク内で外形監視
Synthetics Job Managerを使うことでプライベートネットワーク内のアプリケーション等に対して外形監視を実施できますが、今回のアップデートでPodmanの環境でもSynthetics Job Managerを動作できるようになりました。
![update202501-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3485441/c83e4fbd-0fab-46ff-942e-6ec2ebff78ba.png)

アップデートの詳細はこちらのブログでご確認ください。
↓↓↓↓↓↓
https://newrelic.com/jp/blog/nerdlog/new-relic-update-202501

- **2025年1月アップデート**
  - Alerts: 他アカウントのデータを利用してアラート条件を作成
  - Logs: ログ解析ルールで Key-Value型データのパースが可能に
  - Dashboard: Mermaid記法で視覚的な表現が可能に
  - Browser: カスタムイベントAPIでユーザー行動の詳細を分析可能に
  - Query Builder: Data ExplorerでLookupテーブルを使ったNRQLを作成可能に
  - Synthetics: プライベートネットワーク内で外形監視
プロダクトマネージャーとエンジニア・デザイナーの関係性

# プロダクトマネージャーとエンジニア・デザイナーの関係性

プロダクトマネージャー（PM）とエンジニア、デザイナーの関係性は、プロダクト開発の成功を左右する重要な要素である。特に、各職種の役割を深く理解し、相互に尊重し合う関係を築くことが求められる。

## PMの役割とエンジニア・デザイナーとの関係

PMは、プロジェクトのビジョンを明確にし、チーム全体をリードする役割を担う。しかし、その過程でエンジニアやデザイナーとの間に摩擦が生じることも少なくない。例えば、PMがビジネス視点から要件を詰めすぎると、エンジニアは実装の負担を感じ、デザイナーはユーザー体験の最適化が困難になる。このような状況を避けるためには、各職種の視点を理解し、適切なコミュニケーションを行うことが不可欠である。

## エンジニアとの関係

エンジニアとの関係においては、技術的な制約を理解しながら仕様を決定することが重要である。エンジニアはシステムの実装において現実的なアプローチを取るため、PMは理想論だけでなく、技術的な実現可能性についても考慮する必要がある。例えば、短期間で開発する場合、スコープの調整や技術的負債の管理が求められる。このような課題を解決するために、PMはエンジニアと積極的に議論し、技術的なトレードオフを理解する姿勢を持つことが望ましい。

また、エンジニアの視点を考慮した要件定義を行うことが不可欠である。例えば、以下のような点に注意するとよい。

- **技術的な実現可能性を考慮する**: 無理な仕様を押し付けるのではなく、エンジニアの意見を尊重する。
- **開発の優先度を整理する**: 必要な機能と将来的に拡張可能な要素を明確にする。
- **スプリント計画に余裕を持たせる**: 不測の事態に備えてバッファを設ける。

このように、エンジニアの立場を理解しながら、実装しやすい環境を提供することが求められる。

## デザイナーとの関係

一方で、デザイナーとの関係では、ユーザー体験（UX）の重要性を十分に認識することが不可欠である。PMが機能の優先度を決定する際に、デザイナーの視点を軽視すると、使い勝手の悪いプロダクトが生まれる可能性がある。例えば、ビジネス要件を優先するあまり、デザインの一貫性や直感的な操作性が損なわれるケースがある。

このような問題を防ぐために、PMはデザイナーと協力し、ユーザーの視点からプロダクトの品質を維持する努力をする必要がある。そのためには、以下のようなアプローチが有効である。

- **ユーザーリサーチを共有する**: デザイナーと協力し、ユーザーのニーズを理解する。
- **ワイヤーフレームやプロトタイプのレビューを積極的に行う**: 開発前にデザインの方向性を確認する。
- **デザインシステムを活用する**: 一貫性のあるUI/UXを実現する。

これにより、デザインの品質を向上させながら、ビジネス目標と調和したプロダクト開発が可能となる。

## PMが橋渡し役となる重要性

PMがエンジニアとデザイナーの橋渡し役を果たすことも重要なポイントである。例えば、エンジニアは機能の実装に集中しがちであり、デザイナーは視覚的な一貫性を重視する傾向がある。そのため、PMが両者の間に立ち、共通の目標を設定しながら調整を行うことで、円滑な開発プロセスが実現できる。

これを実現するために、定期的なミーティングを開催し、各職種の意見を統合する場を設けるとよい。具体的には、以下のような取り組みが効果的である。

- **スクラムミーティングの実施**: 進捗状況を共有し、課題を早期に発見する。
- **デザインレビューと技術レビューの合同開催**: 両者の視点を反映した最適なソリューションを模索する。
- **フィードバックループを設計する**: ユーザーのフィードバックを基に、プロダクトの改善を行う。

## PMの信頼構築とリーダーシップ

最後に、PM自身が信頼される存在であることが、チームの関係性を良好に保つための前提となる。エンジニアやデザイナーに対して、一方的に指示を出すのではなく、互いに意見を尊重し合う姿勢を示すことが不可欠である。

そのためには、プロダクトの方向性を明確に伝えるだけでなく、課題が生じた際に迅速に対応する能力も求められる。こうした姿勢を持つことで、PM、エンジニア、デザイナーの関係性は強化され、プロダクト開発の成功につながるのである。

## 関係性を構築する上で考慮するべき点
### そのデザインはマーケティングには影響ないか

特にデザイナーとプロダクトに対するUIUX改善を行う際に、意外と落とし穴となってしまうところが、「マーケティングの観点が抜けてしまう」ということである。
例えば、toCプロダクトのProject Managerだった場合、当然SEO対策も必要になってくるが、しばしば意見が対立することがある。
まだ手探りで解決策を見出そうとはしているが、必ずしもUIUX改善がマーケティングに影響を与えてくるわけではないので、注意が必要だ。
この点に関しては、別途記事を作成して取り組みたい。
個人的備忘録: Django + Nginx - "No such file or directory" エラーの原因を自分なりに調査してみた

## はじめに
Django アプリケーションを Nginx 経由で提供している際に、静的ファイルが見つからないエラーに関する情報を調べました。

本記事では、その原因と解決策についてまとめます。

## エラーに困っていた
以下のエラーメッセージが発生し、静的ファイルが正常に読み込めない状況について調べました。

### 発生したエラー
```
nginx-dev   | 2025/02/25 16:32:43 [error] 30#30: *23 open() "/app/staticfiles/static/img/logo_transparent.png" failed (2: No such file or directory), client: xxx, server: localhost, request: "GET /static/img/logo_transparent.png HTTP/1.1", host: "xxx:8080", referrer: "http://xxx:8080/xxx/"
```

このエラーメッセージから、`/static/img/logo_transparent.png` が見つからず、Nginx がリクエストに適切に応答できない状況であることがわかります。

## 原因と対応策

### 1. `collectstatic` を実行する
Django の静的ファイルが適切に収集されているかを確認するために、以下の情報を調べました。

```sh
python manage.py collectstatic --noinput
```

このコマンドを実行すると、`STATIC_ROOT` に設定されたディレクトリへすべての静的ファイルがコピーされます。

### 2. `STATIC_ROOT` の設定を確認
`settings.py` において `STATIC_ROOT` が正しく設定されているか確認する必要があります。

```python
STATIC_URL = '/static/'
STATIC_ROOT = '/app/staticfiles'
```

また、静的ファイルが `STATIC_ROOT` に適切に配置されているかを確認する方法もあります。

```sh
ls -l /app/staticfiles/static/img/logo_transparent.png
```

もしファイルがない場合、Django の `static/` ディレクトリ (`/app/static/` や `/app/techhub/static/` など) に `img/logo_transparent.png` が存在するか確認するのが有効です。

### 3. Nginx の設定を確認
Nginx が正しいパスを参照しているかを調べました。

`nginx.conf` に次のような設定があることを確認する必要があります。

```nginx
location /static/ {
    alias /app/staticfiles/;
}
```

もし `/static/` の `alias` が `/app/staticfiles/` になっていなければ、修正が必要になります。

### 4. Docker コンテナを再起動
設定を適用するためには、Docker コンテナを再起動する方法も考えられます。

```sh
docker-compose down
docker-compose up -d --build
```

### 5. 追加のデバッグ
上記の手順を試しても解決しない場合、以下の点を調査するとよいでしょう。

- `nginx.conf` の構文エラーをチェック
  ```sh
  nginx -t
  ```
- Nginx のエラーログを確認
  ```sh
  docker logs <nginx-container-name>
  ```
- `STATICFILES_DIRS` の設定（開発環境の場合）
  ```python
  STATICFILES_DIRS = [
      os.path.join(BASE_DIR, "static"),
  ]
  ```

## まとめ
1. `python manage.py collectstatic --noinput` の実行について調査
2. `STATIC_ROOT` の設定とファイルの存在確認が重要
3. `nginx.conf` で `/static/` の `alias` 設定を確認
4. Docker コンテナの再起動が有効な場合がある
5. 追加のエラーログや設定を調査し、デバッグの参考にする

これらの情報を基に、Nginx 経由で Django の静的ファイルを正しく提供するための対策を検討できると思います！
Knowleadge BaseのAuroraはPrivate Subnetでも大丈夫

# 前置き

下記記事で勉強会の資料を共有するWEBサイトを作成しました。

https://qiita.com/infra365/items/c5671e988402d87945f4

WEBサイトの一つの機能として、過去の勉強会資料を検索できるような仕組みを追加しました。仕組みとしてはAmazon BedrockのKnowleage Baseを使用しています。S3上の勉強会資料をRAG用のベクトルDBにエンベディングして保存。クライアントはチャット欄からキーワードを検索するとKnowleage Baseにアクセスして回答を返却する仕組みです。

![kb02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/1efaae1a-e408-4353-9dff-081a767e2c22.png)

アーキテクチャは下記の様な形です。

* フロントエンドをStreamlitで作成
* ALB経由でCongito認証後Streamlitに接続
* 事前にAurora ServelessをPrivate Subnetに作成
* Knowleadge Baseで事前に作成したAurora ServerlessをベクトルDBに指定
* Knowleadge BaseでデータソースとしてS3を指定
* S3に勉強会資料を保存しベクトルDBに保存

![kb03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/ef4960ac-aded-4dab-bf71-deef927da120.png)

# Knowledge Baseの内部通信
Aurora ServerlessをPrivate Subnetに作成していますが下記の処理が可能です。

* S3に保存したデータをベクトルDBに保存（図の赤線）
* StreamlitからBedrock問合せの際にベクトルDBを参照（図の青線）

EC2サーバからStartIngestionJobでS3のデータをベクトルDBに同期する処理とRetreiveでベクトルDBを参照する処理を考えてみます。これらの通信はBedrock AgentとBedrock Agent runtime用のVPCエンドポイントを作成すれば内部通信になります。VPCエンドポイントを作成しない場合、上記のアーキテクチャではNATゲートウェイを経由したインターネット経由の通信となります。Knowledge BaseからS3へのアクセス、ベクトルDBへのアクセスも（多分サービスVPCの様なものがあって）Knowledge Baseの内部通信によって行われます。Knowleage BaseからPrivate SubnetのAuroraへのアクセスはRDS Data APIという仕組みでアクセスを行っています。VPC内のAuroraクラスターエンドポイントにアクセスしているわけではなくこちらも内部通信によって行われます。上記よりKnowleage BaseはVPCエンドポイント作成により、インターネットを経由しない内部通信が可能になります。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/data-api.html

![kb05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/f7226723-b9d7-4976-a236-175c1e9d7cf2.png)
ポインタについて初めて勉強してみた

生まれて初めてポインタというものに触れました。以前から「アドレスを指すものらしい」くらいの認識だけはありました。難しい…


1.変数に&演算子をつけると、その変数のアドレスが得られる。「ポインタを生成する」という言い方をする
```C:ポインタ
#include <stdio.h>

int main()
{
  int n = 999;
  printf("int型nの値は%dで、アドレスは%p", n, &n);
  return 0;
}
```
```terminal:実行結果
int型nの値は999で、アドレスは00000055f05ffa7c
```
<br>

2.ポインタを格納する専用の変数型がある。その名もポインタ型で、以下のように宣言する
```C:ポインタ型変数の宣言
int a = 10;
int *ptr = &a;  //aのアドレスをptrに代入してる
```
ポインタを関数に渡してポインタの示す変数を操作することが可能。変数そのものを渡すわけではない。
つまり、変数がめちゃくちゃ大きいサイズだったときには、そのデータ自体の受け渡しがなくなるのでプログラム実行がスムーズになる?
これがメリットの1つっぽい
ポインタ型仮引数を使う関数にint型を渡してみたらエラーが起きた。実態はどちらも数値だし、int型とchar型のノリでいけるのでは?と思ったが動かなかった。どうやらコンパイラに安全装置（想定外のアドレスにアクセスすることを防ぐ）が備わっているらしい
<br>

3.ポインタの頭に*をつけると、ポインタが指し示す変数そのものを操作できる。ポインタを介して変数を操作することから、間接演算子と呼ばれているらしい

```C:間接演算子*
#include <stdio.h>

void updateValue(int *p) {
    *p = 20;
}

int main() {
    int a = 10;
    printf("updateValue関数を実行する前のaの値は%d\n", a);

    updateValue(&a);
    printf("updateValue関数を実行。aの値は%d\n", a);

    return 0;
}
```
```terminal:実行結果
updateValue関数を実行する前のaの値は10
updateValue関数を実行。aの値は20
```

とりあえず初日はこんな感じでした。難しい～
統計検定1級　2021　統計数理　問1　解説

![img20250226_09114016.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/203e4fbe-434d-45ae-ab61-661d77ba0ff0.jpeg)
![img20250226_09121113.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/0f0afb4a-bf69-4841-888e-70f23de10ad6.jpeg)
AIエージェントとAGIの違いを無人タクシーを例に考えてみた

# はじめに
こんにちは、インティメート・マージャーの直人です。
サム・アルトマン (OpenAI CEO) のブログ「[Three Observations](https://blog.samaltman.com/three-observations)」にてAGIについて語られていたのをきっかけに、自分なりにAGIについて考えてみました。

最近はテキストや画像を生成するだけでなく、以下のように実際の動作を行うAIエージェントが次々と登場しています。
- 情報収集や分析を行いレポートを作成する「[Deep Research](https://openai.com/index/introducing-deep-research/)」
- Webブラウザを操作してタスクを実行する「[Operator](https://openai.com/index/introducing-operator/)」
- コード作成からCLIでの実行まで行う「[Cline](https://github.com/cline/cline)」


しかし、これらは「ANI（特化型人工知能）」であり、「AGI（汎用人工知能）」とは言えません。
では、AIエージェント (ANI) とAGIでは何が異なるのか、無人タクシーを例に考えてみます。

:::note warn
本記事で述べる内容はあくまで個人の見解に基づくものです。
AGIは未知の技術であり、定義や実現時期については専門家の間でも意見が分かれています。
また、筆者自身もAIに関する知識が浅いため、内容に誤りが含まれている可能性があります。
そのため、本記事の内容は一つの考え方として捉えていただければ幸いです。
:::

# AIエージェントとAGIとは？
自分なりのAIエージェントとAGIの認識について述べておきます。

### AIエージェント
特定のタスクを「自律的に」こなすように設計されたAIシステムを指します。
こうした特定分野に特化したAIは、ANI（Artificial Narrow Intelligence / 特化型人工知能）とも呼ばれます。

<ins>特徴</ins>
1. **特定のタスクに特化**
自動運転であれば「安全に目的地に到着する」ことに専念するなど、あらかじめ定められた領域で機能する。
2. **自律的に判断や行動を実行**
人間が細かく指示を与えなくても、ルールや学習データに基づいて次のステップを決定する。
3. **専門分野以外には対応できない**
訓練された範囲外の問題を解決する能力は持っていない。
 
### AGI (Artificial General Intelligence / 汎用人工知能 )
特定の分野にとどまらず「人間のようにあらゆる課題に取り組むことができる」汎用的な知能を持つAIです。
まだ研究途上であり、いつ・どのように実現するかはわかりませんが、実現すればあらゆる分野に爆発的な影響を及ぼすとされています。

<ins>特徴</ins>
1. **幅広い分野に対応できる**
交通・医療・教育・製造業など、まったく異なる領域にも対応できる。
2. **自分で学んで成長できる**
既存の知識に依存するだけでなく、新しい情報や環境の変化にあわせて学習・成長を続ける。
3. **新しいアイデアを生み出せる**
蓄えた知識や経験にとらわれず、まったく新しいアイデアや解決策を導き出す。

# 現在の無人タクシー
アメリカではすでに[Waymo](https://waymo.com/)が完全無人のタクシーサービスを提供しており、2025年内には東京都心でもサービス開始が予定されています。
しかし、現状では以下の理由からAGIとは言えないと考えています。

1. **運転タスクに特化**
乗客とのコミュニケーションや特別な要望への柔軟な対応は難しい。
2. **走行できる地域が限定的**
サンフランシスコやロサンゼルスなど、道路環境や天候条件が比較的整った地域のみで運行している。
3. **想定外の出来事に対応しきれない**
実際、以下の動画のように道路の陥没を検知できず走り抜けてしまうケースも確認されている。

<iframe width="560" height="400" src="https://www.youtube.com/embed/-tJH8hED11I?si=syNYyakqxyySjSQ3" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

# AGIによって無人タクシーはどう変わるのか
では、もしAGIが実現すれば、無人タクシーはどのように進化するのでしょうか？
考えられる変化をいくつか挙げてみます。

1. **乗客との自然なコミュニケーション**
乗客の音声や視線、表情など多様な情報をもとに、乗客のニーズを把握し、柔軟に対応できる。
行き先の変更や寄り道などもスムーズに対応できる。

2. **幅広い地域・環境への対応**
自己学習によって未知の環境下でも適応し、激しい雨や雪、未整備の道路、複雑な交通ルールがある場所でも運転できる。

3. **車両自体のメンテナンスや管理の自動化**
燃料やタイヤの状態をモニタリングし、自ら整備を行ったり、他の車両と連携して利用者の待ち時間を最適化するなど、総合的な管理ができる。

4. **周辺サービスとの統合**
目的地の予約代行や施設との連携、さらには信号機や他の車と連携して交通渋滞の分散を図るなど、周辺サービスと連携することで利便性が大幅に向上する。

5. **予期せぬトラブルへの柔軟な対応**
大規模な道路工事や交通事故、自然災害などが起きても、自治体との連絡を取りながら最適なルートを再設計するなど、より臨機応変な対応が可能となる。

# おわりに
AIエージェントとAGIの違いを無人タクシーを例に考えてみましたが、AGIが実際どのように実現し、社会にどんなインパクトを与えるのかは未知数です。
急速に発展するAIを見ていると将来への期待が膨らむ一方、AIだけで完結する社会になるのではないかという不安も感じます。
今後も進化するAIを学び続け、どんな変化にも柔軟に対応できるようになりたいですね

また、インティメート・マージャーでは新卒から中途まで幅広く採用募集中です！
少しでも弊社に興味を持っていただいた方は採用情報をご確認ください！

https://recruit.intimatemerger.com/
計算理論入門: Grzegorczyk階層

## 自己紹介
ごきげんよう、論計舎代表・講師の川井 新です。
本記事では、計算可能関数をご存知の向きにGrzegorczyk階層 (ぐじぇごるちくかいそう、英: Grzegorczyk hierarchy) というものを紹介します。
なお、論計舎は、数理「論」理学と理論「計」算機科学を伝えるオンライン私塾で、[三つの柱](https://ronkeisha.net/three/)を重んじて、[セッション・コース](https://ronkeisha.net/tutor/)と[クイックコンサル・コース](https://ronkeisha.net/mentor/)、および[よくよむ会](https://ronkeisha.net/reading_group/)を主に開講し、[様々なイベント](https://ronkeisha.net/events/)も行っています。


## イントロダクション

本記事では、計算可能関数をご存知の向きにGrzegorczyk階層 (ぐじぇごるちくかいそう、英: Grzegorczyk hierarchy) というものを紹介します。Grzegorczyk階層は、原始再帰的関数をその増加度によって階層分けするものです。

まず原始再帰的関数を復習がてら定義し、その後Grzegorczyk階層を定義します。その後、Grzegorczyk階層の性質を、最後に原始再帰的関数とGrzegorczyk階層の関係を紹介します。

## Grzegorczyk階層とは

「グジェゴルチク」と読みます (発音難しいですね) 。これは計算可能性理論に基づく関数の階層で、原始再帰的関数からなり、任意の原始再帰的関数はこの階層のあるレベルに属します。Grzegorczyk階層は、関数の増加度を扱い、階層が高くなればなるほど増加度も大きくなります。

YouTubeでも解説しています。よろしければご覧ください。

https://youtu.be/V4DE45fI4ps?si=wSKwFOUysC4nDKmP





## 原始再帰的関数

まず原始再帰的関数をおさらいしよう。

### 原始再帰的関数の定義

![1720919561414-4UJYGTarlh.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4022394/24659d15-0c2a-407e-9aa6-9e1323acb251.png)

原始再帰的関数は計算可能である。(cf. [1])

### 原始再帰的関数の例

* 定数
* 加法: ${x+0=x, x+(y+1) = S(x+y)}$
* 乗法: ${x0=0,   x(y+1)= xy+x}$
* 冪乗: ${x^0 = 1, x^{y+1} = {x^y}x}$

他にも基本的な数論的関数の大半が原始再帰的である。

## Grzegorczyk階層の気持ち

Grzegorczyk階層は、原始再帰的関数の増加の度合いを扱ったものである。原始再帰的関数の増加の度合いは、入れ子になった原始再帰の深さによって見積もることができる。
そこで原始再帰の深さによって、原始再帰的関数を分類したい。

## Grzegorczyk階層の定義

![1720920001887-vhZeuGRq0I.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4022394/2afc5e51-7ad7-43cd-8710-98e33c776ea0.png)


## Grzegorczyk階層の性質

* ${\mathcal{E}^0 \subset \mathcal{E}^1 \subset \mathcal{E}^2 \subset \dots}$
* 実際、${\mathcal{E}^I}$は${B_i}$の閉包であって${B_0 \subset B_1 \subset B_2 \subset \dots}$となるからである。
* しかも、この階層は厳密である: ${\mathcal{E}^0 \subsetneq \mathcal{E}^1 \subsetneq \mathcal{E}^2 \subsetneq \dots}$
* というのも、ハイパー演算子${H_n}$について${H_n \in \mathcal{E}^n}$かつ${H_n \not \in \mathcal{E}^{n-1}}$だからである。
* ${\mathcal{E}^0}$は次を含む: ${x+1, x+2, \dots}$
* ${\mathcal{E}^1}$はすべての加法関数を備える: ${x+y, 4x, \dots}$
* ${\mathcal{E}^2}$はすべての情報関数を備える: ${xy, x^4, \dots}$
* ${\mathcal{E}^3}$はすべての指数関数を備える: ${x^y, 2^{2^{2^x}},\dots}$
* ${\mathcal{E}^4}$はテトレーション関数を備える。


## 原始再帰的関数との関係

* ${\mathcal{E}^n}$の定義は、再帰が「限定」されていて${(E_k)_{k < n}}$が明示的に導入されていることを除けば、原始再帰的関数のクラスの定義に似ており、実際Grzegorczyk階層は原始再帰の強さを制限しているものと見ることができる。
* このことから${\mathcal{E}^n \subset PR}$であり、したがって${\bigcup_n \mathcal{E}^n \subset PR}$。
* さらにすべての原始再帰的関数がいずれかの階層に属することも示される: ${\bigcup_n \mathcal{E}^n = PR}$ (cf. [4])


## 余談

原始再帰の深さはloopプログラムにおけるloop深度と密接な関わりがある。

## Reference

Amn. **計算理論の魔導書**. 2021 [link](https://amntksr.booth.pm/items/1536898)

Andrzej Grzegorczyk. Some classes of recursive functions. 1953

グジェゴルチク階層 wikipedia. [link](https://w.wiki/Abr6)

H Schwichtenberg. He rose. subrecursion. functions and hierarchies. oxford logic guides, no. 9. clarendon press, oxford university press, oxford and new york1984, xiii+ 191 pp. The Journal of Symbolic Logic, Vol. 52, No. 2, pp. 563–565, 1987.
Emacs 30.1

## Emacs 30.1
初めて Emacs を触ったときのバージョンは 18 だったと思う。確か。もう 30 になるんかー。
新しい Emacs リリースされたし、暇なので早速インストールしてみる。
## ネイティブコンパイル
ネイティブコンパイル有りにすると、Cygwin 環境では以前のバージョンから動作がおかしい。試しにネイティブコンパイル有りでビルドしてみると、Emacs はエラーを表示して起動しなかった。
## なのでネイティブコンパイルは無し！
```
$ ./configure --without-xim --with-w32 --without-native-compilation
```
一番最後の引数が重要。
しかし、最新の Emacs 使う意味はたぶん無いｗ
## 起動時に警告
DDSKK の警告が出るけども使えるので気にしない。対応待ち。
## スクショ
![emacs-30.1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3430684/92ef74dc-c686-4382-9b6a-5cdab02195a8.png)
無事に起動。
今回のバージョンアップでは、init.el がらみのエラーは起きなかった。
elm327の研究 その20

# 概要
elm327の研究やってみた。
obdコマンド、01 01 をデコードしてみた。

# 成果物

<p class="codepen" data-height="700" data-default-tab="html,result" data-slug-hash="PwobYzO" data-pen-title="elm327 0101" data-user="ohisama" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/ohisama/pen/PwobYzO">
  elm327 0101</a> by ohisama (<a href="https://codepen.io/ohisama">@ohisama</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://public.codepenassets.com/embed/index.js"></script>

以上。
SAP HANA CloudのVECTOR_EMBEDDING Functionを使ってみる

## はじめに
SAP HANA CloudでEmbedding（テキストをベクトルに変換したもの）を生成できる機能が2024 Q4にリリースされました。

https://community.sap.com/t5/technology-blogs-by-sap/new-machine-learning-and-nlp-features-in-sap-hana-cloud-2024-q4/ba-p/13953934

従来はSAP AI Coreや外部のLLMを使ってEmbeddingを取得していましたが、HANA Cloudの中でできるようになったということです。PALを使う必要があると勘違いしていたのでトライアル環境では試せないと思っていたのですが、Natural Language Processingを有効化するだけでできました。

## 前提
HANA Cloudの設定でNatural Language Processing (NLP)を有効化します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/37aff8c6-71d5-4360-9dc5-e85809475e7d.png)

## VECTOR_EMBEDDINGを取得
以下のクエリを実行します。

```
SELECT VECTOR_EMBEDDING('Hello world!','DOCUMENT','SAP_NEB.20240715') FROM DUMMY;
```
Embeddingが返ってきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/76161809-8d75-4f1f-b601-4eb27e43cbc3.png)

### シンタックス
```
VECTOR_EMBEDDING(<text>, <text-type>, <model-and-version>)
```
`<text>` : Embeddingを生成する対象のテキスト
`<text-type>` : テキストの種類。 `DOCUMENT`または`QUERY`を指定
`<model-and-version>` : Embeddingを生成するためのモデルとバージョンを指定

サポートされるモデルおよびバージョンは以下のヘルプに記載があります。現時点では`SAP_NEB.20240715`のみで、このモデルではドイツ語、英語、スペイン語、スペイン語、ポルトガル語がサポートされています。
https://help.sap.com/docs/hana-cloud-database/sap-hana-cloud-sap-hana-database-vector-engine-guide/vector-embedding-function-vector

## 参考
- [Working with Vectors and Text Embeddings in SAP HANA Cloud | SAP Blog](https://community.sap.com/t5/technology-blogs-by-sap/working-with-vectors-and-text-embeddings-in-sap-hana-cloud/ba-p/13688534)
- [VECTOR_EMBEDDING Function (Vector) | SAP Help Portal](https://help.sap.com/docs/hana-cloud-database/sap-hana-cloud-sap-hana-database-vector-engine-guide/vector-embedding-function-vector)
コンストラクタについて

## コンストラクタの定義
 - インスタンス化した時に最初に(自動で)呼び出される
 - 名前がクラスと同じ
 - 戻り値をもたない(void も書かない)

## 構文
[修飾子]コンストラクタ名(引数) {}


## デフォルトコンストラクタ
クラスに1つもコンストラクタが明示的に定義されていない場合
引数なし、中身なしのコンストラクタ(デフォルトコンストラクタ)が自動的に追加される

``` java
class Test {
    int score;
    Test( ) { //引数なし
    
        //実装なし
        
    }
}
```

## 戻り値
ちょっと悩んだので記録しておく

```java
//コードA
class Exm {
  void Exm() { System.out.println("Say HELLO");}
}

---------------------------------------------

class Test {
  public static void main(String[] args) {
    Exm e = new Exm();
  }
}
```

```java
//コードB
class Exm {
  Exm() { System.out.println("Say HELLO");}
}

---------------------------------------------

class Test {
  public static void main(String[] args) {
    Exm e = new Exm();
  }
}
```


この場合の出力結果は以下の通り
```java
///コードA

```

```java
///コードB
Say HELLO

```



コードAは -void- がついており戻り値が指定されているため、
通常のメソッドとして扱われるため、インスタンス化すると
デフォルトコンストラクタが呼び出され、何も出力されない。

:::note
void ＝「戻り値なし」として認識していたため悩んだ。
テスト実行時にThe given element does not have a value setterというエラーが表示される

## The given element does not have a value setterの対処法

# 問題のファイルでエラーが発生する原因になっている箇所
```jsx
describe("フォームに入力ができること", () =>{
    test("学習内容が入力できる",
      async () => {
            const learnRecordForm = screen.findByLabelText("学習内容");
            fireEvent.change(learnRecordForm, {target: { value: "test" }});
      }
    )
  }

```
修正した箇所
```jsx
describe("フォームに入力ができること", () =>{
    test("学習内容が入力できる",
      async () => {
            const learnRecordForm = await screen.findByLabelText("学習内容");
            fireEvent.change(learnRecordForm, {target: { value: "test" }});
      }
    )
  }
```
# 問題の原因
要素が見つかる前にfireEventで入力しようとしていたため
# エラー解決策
要素が見つかるまで待機してからfireEventを実行する。

:::note warn
react-testing-libraryについて勉強しているところの為
間違っているところがありましたらご指摘・コメントをいただけると幸いです。
:::