OmniAICreator/Qiita-1.07M huggingface dataset:
Qwen2.5 テクニカルレポート

# はじめに
本記事はQwen2.5のテクニカルレポートの要約です。

タイトル:Qwen2.5 Technical Report

https://arxiv.org/abs/2412.15115

![Screenshot 2024-12-20 at 22.56.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1707407/68d42bbd-20e2-fb3b-0cbb-5cd23347fc9f.png)


# 概要
本報告では、多様なニーズに応えるために設計された包括的な大規模言語モデル（LLM）シリーズであるQwen2.5を紹介します。前バージョンと比較して、Qwen2.5は事前学習と事後学習の両段階で大幅な改善が行われました。事前学習では、高品質なデータセットの規模を従来の7兆トークンから18兆トークンに拡大し、常識、専門知識、推論能力の強化を図っています。事後学習では、100万件以上のサンプルを用いた精緻な教師あり微調整や、オフライン学習DPOやオンライン学習GRPOを含む多段階の強化学習を実施し、人間の嗜好への適合性を向上させました。これにより、長文生成、構造化データの分析、指示追従能力が著しく向上しています。
Qwen2.5 LLMシリーズは、0.5B、1.5B、3B、7B、14B、32B、72Bの各パラメータサイズで、ベースモデルと指示調整済みモデルを提供し、量子化バージョンも含め、Hugging Face HubやModelScope、Kaggleから100以上のモデルにアクセス可能です。さらに、Alibaba Cloud Model Studioでは、Mixture-of-Experts（MoE）バリアントであるQwen2.5-TurboとQwen2.5-Plusも提供されています。
Qwen2.5は、言語理解、推論、数学、コーディング、人間の嗜好適合性など、多岐にわたるベンチマークで最高水準の性能を示しています。特に、オープンウェイトのフラッグシップモデルであるQwen2.5-72B-Instructは、多くのオープンおよびプロプライエタリモデルを上回り、約5倍のサイズであるLlama-3-405B-Instructと競合する性能を発揮しています。また、Qwen2.5-TurboとQwen2.5-Plusは、GPT-4o-miniやGPT-4oと比較して、コスト効率と性能の両面で優れたバランスを提供しています。さらに、Qwen2.5は、Qwen2.5-Math、Qwen2.5-Coder、QwQ、マルチモーダルモデルなどの専門モデルの基盤としても活用されています。

# 用語の解説
1.	大規模言語モデル（LLM）: 人間の言語を理解し生成するために設計された人工知能モデルで、大量のテキストデータを学習して言語処理能力を獲得します。
2.	事前学習: モデルが大量の未ラベルデータから一般的なパターンや知識を学習するプロセスで、モデルの基礎的な能力を構築します。
3.	教師あり微調整: 事前学習済みモデルに対して、特定のタスクに関連するラベル付きデータを用いてさらに学習させ、特定のタスクでの性能を向上させるプロセスです。
4.	強化学習: モデルが試行錯誤を通じて最適な行動を学習する手法で、報酬を最大化するように行動を調整します。
5.	Mixture-of-Experts（MoE）: モデル内に複数の専門家（サブモデル）を持ち、入力に応じて最適な専門家を選択して処理を行うアーキテクチャで、効率的な計算と高性能を両立します。

# 図表の引用

![Screenshot 2024-12-20 at 22.56.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1707407/a8cf297c-f42a-5e24-4e0e-8a8913e7ce7e.png)

![Screenshot 2024-12-20 at 22.56.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1707407/69087720-71fb-694b-2477-de6b3a40c588.png)

![Screenshot 2024-12-20 at 22.57.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1707407/4cf646f9-4da9-35a5-24f2-2fba5f6f7d7f.png)

![Screenshot 2024-12-20 at 22.58.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1707407/0a42b0e6-ed15-8ae0-8692-826749eafca1.png)

---
友達とゲームをするためにサーバーを作った話

:::note warn
現在はサーバーの稼働形態を変えているためこの情報は古いです。
:::
# 自己紹介&サーバー作ったきっかけ
こんにちは。
N中等部 通学コースのりょーといいます。
友達とゲームをしたい！という話になり、私がマインクラフトのサーバーを作ることになりました。
マイクラサーバーは作ったこと何回もあるんですが、「新しいことをやってみたい！」と思いました。
当時の私は[某散財系鯖主さん](https://www.youtube.com/@unchama)(いつも楽しく動画とか配信見てます！！！！)の動画で **Proxmox**という仮想化プラットフォームに興味しかありませんでした。
そこで、「Proxmox使ってサーバー作ってみよう！」と思いサーバー作ってみました。今回はそのお話になります。

# ProxmoxのVMを構成する
Proxmoxは仮想化プラットフォームで、めっちゃ簡単にいうとパソコンの中にパソコンを作れるすごいやつです。
今回作ったサーバーでは、ubuntu serverを中にインストールして使用をしています。
「そのままUbuntu Server突っ込んでやったらいいじゃん！」と思う人が多いと思いますが、まあロマンですよね！！

# Minecraftサーバーのセットアップと工夫

今回はUbuntu Serverの中にdockerをインストールして、docker-composeでPaperMCを動かしています。PaperMCは軽量で高パフォーマンスなマインクラフトのサーバーソフトウェアで、プラグインを使った柔軟な拡張が可能なのが魅力です。

## PaperMCとDiscordSRVの導入
PaperMCの導入はスムーズでしたが、「せっかくなら便利にしたいよね〜」ということでさまざまなプラグインを導入しました。今回はその中でも特に便利だった、 **DiscordSRV**というプラグインを紹介します。
このプラグインは、Minecraftのゲーム内チャットとDiscordサーバーを連携させることができます。友達がゲーム内でメッセージを送ると、Discordに自動で反映されるようになり、逆にDiscordのチャットがゲーム内にも表示されます。
めちゃめちゃ便利です。

### 導入時のポイント
DiscordSRVを使うためには、DiscordのBotアカウントを作成し、それをサーバーに連携する必要があります。手順は少し複雑ですが、検索しながら普通にセットアップをすることができました。
自分は元からDiscordのBot開発などをしていたので、簡単にすることができました。

## 工夫したポイントと課題

### 1. バックアップの重要性
バックアップの仕組み、サーバー運営にはめっちゃ大事だと思います！
ワールドのデータに何かあっても大丈夫なように、プラグインを使ってバックアップを行っています。

### 2. 友達とテストプレイ
完成したサーバーに友達を招待し、実際にマインクラフトをプレイしました。めちゃめちゃ楽しい！そして、思っていたよりも軽く動きます。予期せぬトラブル(プラグインの影響と、プラグインテストで死んだのが重なってアイテム全ロス）を解決していく過程も楽しかったです。

## 終わりに
いかがでしたでしょうか。久しぶりにqiitaを書きましたが楽しいですね。
今後はProxmoxでできることを最大限活用してたくさん有効活用していきたいなと思いました。
最後まで読んでくださり、ありがとうございました！
Svelte Online Meetup #3 で登壇しました

:::note info
この記事は[Svelte Advent Calendar 2024](https://qiita.com/advent-calendar/2024/svelte)の20日目の記事です。

が…さすがに主催者である@ryoppippiさんの昨日の記事[Svelte Online Meetup #3 を開催しました](https://qiita.com/advent-calendar/2024/svelte)を差し置いて登壇レポを先に出すわけにもいかんだろう

ということで記事の内容はまだ書いておりません！(断じていい訳じゃないですよ！断じてね！)
:::

みなさんの登壇を見ての感想や、自分が登壇してみての感想、懇親会でのことなどをあれこれ書く予定です〜〜！
numpy.float32はisinstanceにおいてPythonのfloat型と認識されない

## 問題

タイトル通りだが、numpy.float32はisintanceにおいてpythonのfloat型として認識されないという問題を発見した

```python
>>> print(isinstance(numpy.float32(5.23), float))
False
```

ちなみに、numpy.float64はpythonのfloat型として認識される
```python
>>> print(isinstance(numpy.float64(5.23), float))
True
```

## ちなみに
同じ問題がnumpyのGitHubでも唱えられていたので共有しておく

https://github.com/numpy/numpy/issues/13133
【Git】削除されたファイルをコミット履歴から探して復元する方法

## ファイルを削除したコミットを探す

まず、削除されたファイルが含まれていたコミットを特定します。以下のコマンドを使用します:

```terminal
git log --diff-filter=D --summary
```

このコマンドは、削除（D）されたファイルのコミット履歴を表示します。

また、以下のコマンドでも検索できます。

```terminal
git log -- <ファイルパス>
```

例:

```terminal
git log -- src/main.py
```

詳細については [git-log](https://git-scm.com/docs/git-log) を参照してください。

## ファイルの復元

特定したコミットからファイルを復元します。以下のコマンドを使用します:

```terminal
git checkout <コミットハッシュ> -- <ファイルパス>
```

- `<コミットハッシュ>`: ファイルが削除されたコミットのハッシュ
- `<ファイルパス>`: 復元したいファイルのパス

例:

```terminal
git checkout a1b2c3d4 -- src/main.py
```

詳細は[git-checkout](https://git-scm.com/docs/git-checkout) を参照してください。

## 復元したファイルをコミットする

ファイルを復元したら、通常通りにステージングしてコミットします。

```terminal
git add <ファイルパス>
git commit -m "<コミットメッセージ>"
```

例:

```terminal
git add src/main.py
git commit -m "src/main.py を復元"
```
UbuntuOSで作った共有ファイルにアカウントを作る

1年くらい前に、自作NASを作り、最近では、PCやiphoneでVPNを使い自宅外からファイルサーバーにアクセスできるようになりました。しかし、個人的に不安な点が一つ。それは、**ゲストでファイルサーバーに入れてしまう**ことです。そもそも自宅のWifiに接続されなければ基本大丈夫だと思いますが、これから誰かとシェアすることもあるかもしれないので、ユーザーやグループを作成し、登録してみたいと思います。

まずはグループを作成します。
```
sudo groupadd ＜グループ名＞
```
グループが作成できたら、グループの中に所属するユーザーを登録します。
```
sudo gpasswd -a ＜ユーザー名＞ ＜グループ名＞
```
ユーザーが登録できたら、一度グループの確認をしましょう。
* 全グループを表示
```
cat /etc/group
```
* 特定のグループを表示
```
getent group ＜グループ名＞
```
sambaの設定ファイルに以下のように設定します。
```
[共有ファイル名]
   path = ＜共有ディレクトリ＞
   valid users = @グループ名
   read only = no
```
この設定により先ほど設定したグループのメンバーのみがアクセスできる状態になる。

ここまで設定が終わったら、実際にアクセスしてみよう、ゲストではアクセスができず、登録ユーザーでログインすることで、アクセスできるようになります

## 独り言
PCだとファイルアップロードができるのに、なぜかiPhoneやiPadだと読み取りしかできないんですよね〜...次は、それを設定できるようにしたいですね。ではまた！
GraphQLを1から勉強しなおしてみた ~ ミューテーション ~

# はじめに
先日に引き続きGraphQLを一から勉強し直していきます。

前回はこちら。

https://qiita.com/mattsu_mocha/items/5b7a666fdd0a34676798

# ミューテーション
GraphQLの書き方は変わらず、データのCreate（作成）・Update（更新）・Delete（削除）を行うことができる。

## Create

```graphql:create
enum Episode {
  NEWHOPE
  EMPIRE
  JEDI
}
 
input ReviewInput {
  stars: Int!
  commentary: String
}
 
type Mutation {
  createReview(episode: Episode, review: ReviewInput!): Review
}
```

## Update
idと更新したいフィールドを引数として指定する。

以下の理由から特定のフィールドを更新するように定義することが推奨されている。
1. **スキーマの表現力向上**
    - フィールド引数の入力タイプをNon-Nullにでき、クライアントが必要な値を確実に提供することを保証する
2. **ランタイムロジックの削減**
    - 更新したい値が送信されたかをチェックするロジックが不要になる

```graphql:update
type Mutation {
  updateHumanName(id: ID!, name: String!): Human
}
```

## Delete
削除対象のidを引数として指定する。

削除が成功したことを示すために、削除されたエンティティのidやpayloadを返すことが一般的。

```graphql:delete
type Mutation {
  deleteStarship(id: ID!): ID!
}
```

## 複数フィールド
ミューテーションではクエリ同様複数指定することが可能。

ただし、クエリは**並列**で実行されるのに対し、ミューテーションは**直列**で実行される。

例えばクエリは以下のように書いた場合、`user`と`posts`のクエリは同時に実行される。これは、パフォーマンスの向上や効率的なリソース利用・高速なレスポンスを担保するためである。
```graphql:クエリ
query {
  user(id: "1") {
    name
    email
  }
  posts(userId: "1") {
    title
    content
  }
}
```

一方、ミューテーションは以下のように書いた場合、`firstShip`が実行されてから`secondShip`が実行される。これは処理が競合しないようにするためである。

ただし、ロールバック機能はないため、`secondShip`が失敗しても`firstShip`の処理は戻せない。

```graphql:ミューテーション
mutation { 
  firstShip: deleteStarship(id: "3001")
  secondShip: deleteStarship(id: "3002")
}
```

# 参考

https://graphql.org/learn/mutations/
「差が無いこと」を確認するための検定方法

# はじめに
### 注意
※ この記事は私のメモであり、ほぼ解説はしない

### 本題
- 2つの実験条件を変えた実験データに対して、「これらには差がある」とか「これらには差がない」とか言いたい時がよくある
- 「差がある」ことを示すためには、例えばt検定を実施するが、このとき統計的に次の考え方を実施する：
  1. 帰無仮説が棄却された → **差があると言える**
  1. 帰無仮説が棄却できなかった → **なにもわからなかった**
  （この辺りが分からない方は、検定が背理法であることを学ぶ必要があります）
- ここで、<font color="#0072BC">**じゃあ、どうやって「差が無いこと」を示すんだ…？**</font> となるが、それがこの記事の話

# 結論：非劣性検定

「差が無いをことを確認したい」ときに、「劣っていないことを確認したい」と解釈することで、**非劣性検定**というものが使えるらしい

次の記事が私が初めて非劣等性検定を知った記事：https://tjo.hatenablog.com/entry/2021/06/14/180757

非劣等性検定は、上の記事でも解説されていますが、次の本の8.3章（付録的な部分）に登場します：

https://www.amazon.co.jp/exec/obidos/ASIN/4254128827/hatena-blog-22/

# おわりに
- 普通に勉強になった
【eBay】デコードを忘れるんじゃあないよ【OAuth】

人間、成長を実感し始めていろいろなことがわかるようになったころが一番危ないですよね。
そんな初心忘るるべからずの精神を胸に刻まんと、戒めとして記します。

# ことの始まり
ある日突然ebayのAPIで使用するアクセストークンを取得している部分で認証エラーが出始めた。
この辺のエラーは何度も経験してきているので、「あぁ、リフレッシュトークンの期限が切れたのか。。」とすぐさま察知。

通常のプロジェクトだとappID(Client ID)とru-name(リダイレクトuri)を含んだリンクを「ebay連携」のようなボタンで設置し、以下のフローでリフレッシュトークンを取得するケースが多い。

1. ボタン押下
2. ebayログイン画面に遷移&ログイン実行
3. アプリケーションを許可
4. アプリにリダイレクト
5. リダイレクトされてきたコントローラ内で、付与されたcodeパラメータを使用してAPIリクエストを行いリフレッシュトークンを取得

ただこのプロジェクトは上記フローのようにアプリにリダイレクトさせて自動でリフレッシュトークンを取得するのではなく、codeをURLから直接取得し、postmanを使用して手動でリフレッシュトークンを取得してDBに保存しているようだった。
※postmanについては[こちら](https://qiita.com/kazuhiro0418/items/c3243a5073178c366916)で簡単に紹介しています。

# 長い戦い
手順はわかったので1-3のフローを終えURLからcodeを取得し、postmanでリクエストしたところ、以下のエラーが返却される。

```
{
    "error": "invalid_grant",
    "error_description": "the provided authorization grant code is invalid or was issued to another client"
}
```

直訳すると
「提供された認可付与コードが無効であるか、別のクライアントに発行されたものです」
となるが、この辺のエラーメッセージは当てにならないケースが往々にしてあるので、検証を開始してみる。

## 検証したこと
※以下いずれの方法もpostmanでの手動リクエストで検証

① リクエスト内容に問題はないか
一番最初にすること。ebayのリフレッシュトークン取得のリクエストに必要なのはappID, CertID, redirect_uriとなるが、いずれも正しいものであった。

② 該当アプリに対して別のストアで連携してみる
同様のエラー("invalid_grant"以下同)が発生する

③ 別のアプリで連携してみる
自社の別のアプリで連携できるか検証。同様のエラーが発生する。

④ rails cでリフレッシュトークンを取得するサービスにcodeを渡して実行
同様のエラーが発生する。

⑤ 別アプリの自動連携(ボタン押したら連携してくれる)処理内でcodeを出力し、それをリクエスト
リフレッシュトークン取得成功

上記①-④いずれも解決には至らず、頭を悩ませていたところで「これpostmanのリクエスト方法がそもそも間違ってるんじゃないか...？」と疑い始めるが、⑤を実行したところ成功。
postmanのリクエストは合っていると認識。

成功したリクエストと失敗したリクエストと睨めっこしたところ「失敗してるやつのcode、%が多いな...((ﾟДﾟ)))ﾊｯ」

## デコードしてない
これデコードしてないやんけ！！
デコードしてリクエストしたら無事成功。

# 反省
エラーメッセージの通りcodeに問題があったので、やはりまずはそこをちゃんと検証すべきだった。
ちなみにAmazonAdsAPIのOAuth連携で付与されるcodeはエンコードされていないのでそのまま使える。
ebayの時はデコードを忘れずに。戒め。
Azure PsPing使ってみた



# はじめに

pingできないことが分かったのでPsPing使ってみました

https://qiita.com/yuyanz/items/c87cb403137922d3000c

# 準備

1. 下記よりPsToolsをダウンロード
1. 解凍（解凍した場所は覚えておいてください）

https://learn.microsoft.com/ja-jp/sysinternals/downloads/psping

# テストしてみる

あとは管理者権限のコマンドプロンプトで実行するだけです。

格納したところまで移動
~~~ windows
cd C:\PSTools
~~~

pspingを実行（IPとポートを指定）
~~~
psping 192.168.100.100:3389
~~~

無事使用できました。

オプションを使うと色々なテストができます。
> -n	送受信の数。 秒数を指定する場合は 's' を追加します (例: '10s')
> -l	要求のサイズ。 キロバイトの場合は 'k' を、メガバイトの場合は 'm' を追加します

詳細なコマンドは公式から確認してください

https://learn.microsoft.com/ja-jp/sysinternals/downloads/psping

# テスト環境

下記の通り、P2S接続をしました

https://qiita.com/yuyanz/items/ac88f795b29faf92753d

仮想ネットワーク上のVMにはプライベートIPのみ（パブリックIPを付与しない）状態にしています

この状態で手元のPCから仮想ネットワーク上のプライベートIPにpspingを打ってきちんと通信可能なことを確認できました。

普通のpingだと疎通できないケースが多いので便利！

# 最後に

pspingを使ってみた話でした。
若干公式ドキュメント見るのめんどくさかったんですが、思っていたより遥かに簡単でした。
よければ使ってみてください！
[Rust]マクロとコードの生成

## 宣言的マクロ

`println!`や`vec!`のように、`!`を末尾につけて呼び出す処理をマクロと呼びます。
マクロは標準で用意されているものもありますが、必要に応じて自作することが可能です。マクロを定義するには`macro_rules!`キーワードを使い、このように定義したマクロを宣言的マクロと呼びます。

宣言的マクロの構文は以下の通りです。

```rust
macro_rules! マクロ名 {
    (パターン1) => {
        // パターン1にマッチした場合のコード
    };
    (パターン2) => {
        // パターン2にマッチした場合のコード
    };
    // 必要に応じて他のパターンを追加
}
```

マクロはコンパイル時に、`パターンnにマッチした場合のコード`の部分がRustのソースコードに展開されます。Rustのソースコードを作るためのコードになるので、一般的なRustの文法とは異なります。

## パターン

同名のマクロに、異なる引数に応じた処理を定義できます（オーバーロード）。そのために、マクロを呼び出したときに与えられた引数がどのようなものなのかをパターンで区別します。

## 引数のアノテーション

引数が無いマクロは以下のように定義します。

```rust
macro_rules! say_hello {
    () => {
        println!("Hello, World!");
    };
}

fn main() {
    say_hello!(); // Hello, World!が出力される
}
```

一つの式を受け取るマクロは以下のようにします。引数の先頭には`$`を付ける必要があります。

```rust
macro_rules! double {
    ($x:expr) => {
        $x * 2
    };
}

fn main() {
    let result = double!(5);
    println!("5の2倍は{}", result); // 出力: 5の2倍は10
}

```

`double!`が受け取る引数は何かしらの式である必要があるため、マクロの引数には`:expr`というアノテーションを付けます。`expr`は式を表します。そのほかのアノテーションには以下のようなものがあります。
- `block`
- `ident` 関数、変数の名前に使用
- `pat` (パターン)

引用：https://doc.rust-jp.rs/rust-by-example-ja/macros/designators.html

## 可変長引数

可変長引数は`,*`で表現します。下記のコードでは、`1, 2, 3, 4, 5`が`($x:expr)`の繰り返しと判定され、順に`0`に加算されていきます。

```rust
macro_rules! sum {
    ($($x:expr),*) => {
        0 $(+ $x)*
    };
}

fn main() {
    let result = sum!(1, 2, 3, 4, 5);
    println!("合計は{}", result); // 出力: 合計は15
}
```

## 関数の作成

`ident`アノテーションを使うと、その引数の値を使って関数や変数を宣言することができます。下記の例では、与えた文字列と同名の関数を作成します。仕組みとしては、`fn $func_name()`以降の部分がRustのソースコードとして展開されるので、直に`fn foo()...`と書いているのと同じ挙動になります。

```rust
macro_rules! create_function {
    ($func_name:ident) => {
        fn $func_name() {
            println!("関数 {} が呼び出されました", stringify!($func_name));
        }
    };
}

// マクロを使用して関数を生成
create_function!(foo);
create_function!(bar);

fn main() {
    foo(); // 出力: 関数 foo が呼び出されました
    bar(); // 出力: 関数 bar が呼び出されました
}
```

:::note
マクロの定義はかなりローレイヤーな印象を受けます。DRYの法則を意識した機構ではありますが、使いこなすのにはそれなりの熟練度が必要そうです・・・
:::
Salesforce Bulk API 2.0 実践ガイド - 大規模データ処理の効率化

## はじめに
Salesforceで大量のデータを扱う場合、通常のSOAP/REST APIでは処理に時間がかかり、タイムアウトの可能性も高くなります。そこで効果的な解決策となるのがBulk API 2.0です。この記事では、Bulk API 2.0の特徴から実装方法まで、図解を交えながらまとめました。

## Bulk API 2.0の特徴

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/b68cc01e-2c8a-a857-d3d0-be032202f11d.png)

Bulk API 2.0には、以下のような特徴があります：

- REST規則に基づいた設計で、直感的に使いやすい
- 数千から数百万レコードの大規模データセット操作に最適化
- 非同期処理による効率的なデータ処理
- CSVフォーマットのサポート

### 従来のAPIとの比較

|特徴|Bulk API 2.0|SOAP/REST API|
|---|---|---|
|処理方式|非同期|同期|
|適用ケース|大量データ処理|少数レコードのリアルタイム処理|
|処理単位|数千〜数百万レコード|少数レコード|

## 実装手順

### 1. 初期設定

1. Trailhead Playgroundへのログイン
2. Postman Webアプリケーションの設定
3. 認証トークンの取得
4. 接続テスト

### 2. ジョブの作成と管理

```http
POST /services/data/v57.0/jobs/ingest
Content-Type: application/json

{
    "operation": "insert",
    "object": "Account",
    "contentType": "CSV",
    "lineEnding": "LF"
}
```

### 3. データの追加

```http
PUT /services/data/v57.0/jobs/ingest/{jobId}/batches
Content-Type: text/csv

Name,BillingCity,Phone
Acme Corp,東京,03-1234-5678
```

### 4. ジョブの完了処理

```http
PATCH /services/data/v57.0/jobs/ingest/{jobId}
Content-Type: application/json

{
    "state": "UploadComplete"
}
```

## ジョブ状態の管理

ジョブには以下の3つの主要な状態があります：

1. **Open**: 初期状態。データ受信待機中
2. **UploadComplete**: データアップロード完了、処理待機中
3. **JobComplete**: 全処理完了、結果確認可能

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/1d76aaff-c79c-0636-9430-a3afbe7fa663.png)

### モニタリング方法

モニタリングは以下の2つの方法で行えます：

1. Salesforce UI経由
   - 設定画面から確認
   - 一括データ読み込みジョブの確認

2. API経由
   - GETリクエストによる状態確認
   - 詳細情報の取得

## エラー処理とトラブルシューティング

### 一般的なエラーと対処方法

1. 必須項目の欠落
   - エラーログで該当フィールドを確認
   - データを修正して再実行

2. 重複レコード
   - 重複ルールの確認
   - 必要に応じてデータのクレンジング

3. データ形式の不一致
   - CSVフォーマットの確認
   - 文字コードやデリミタの調整

## まとめ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/b7f43943-b8ba-fd16-d473-daace0fa738d.png)

Bulk API 2.0は、Salesforceでの大規模データ処理を効率化する強力なツールです。非同期処理と最適化された設計により、大量のレコードを効率的に処理できます。実装時は、適切なジョブ管理とエラー処理を行うことで、より信頼性の高いデータ処理が実現できます。

## 参考資料

- Salesforce 開発者ドキュメント
- [Bulk API 2.0 開発者ガイド](https://developer.salesforce.com/docs/atlas.ja-jp.api_asynch.meta/api_asynch/asynch_api_intro.htm)
- [Trailhead: Bulk API モジュール](https://trailhead.salesforce.com/ja/content/learn/modules/api_basics/api_basics_bulk) : 詳細の説明・手順はTrailheadを参照

<iframe width="560" height="315" src="https://www.youtube.com/embed/Rln4M4Z5AMY?si=MK0zXAd_kFDNRtTA" 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>
NumLockを常に有効にしたいのにログインすると無効になってしまう時にチェックするポイント

# まえがき
業務に使っているPCはテンキーの付いたノートPCなのですが、基本的にNumLockを有効としてテンキーでも数字が入力できるようにしたいと思っています。
PCの調子が悪くなり、初期化を行ったのですが、NumLockを常に有効にしたいのにログインすると無効になってしまうという問題にしばらく悩まされたので、これをチェックしておけばよいというポイントをメモしておきたいと思います。
# BIOSの設定
まずはBIOSに設定項目があります。メーカーによって異なってくるかとは思いますが、多分基本的にはどこのPCでも設定できるんじゃないかと思います。今使っているのはHPのやつですが、ロゴが出ているときにF10を連打してセットアップメニューに入り、詳細設定のブートオプションの中に「ブート時のNum Lock」というのがあるので、これをONにして保存します。
# シャットダウン時の設定
そもそもNumLockが有効な状態でシャットダウンしておかないと、次回起動する際に、有効な状態になっていないという情報がありました。一応、これは意識しておきます。
# 高速スタートアップの無効化
これは実際影響があるのか不明なのですが、高速スタートアップが有効だと良くないという情報がありました。分からないけれどとりあえず無効化しておきます。
コントロールパネルの電源オプション、「電源ボタンの動作を選択する」の中にあります。無い場合はそもそも無効だということで関係ないのだと思いますが、もし項目を出したい場合は、PowerShellから`powercfg /hibernate on`とすると出てきます。
# レジストリの変更
ググるとよく出てくる情報ですが、レジストリをいじるとログイン後のNumLockの状態を制御できるとのことです。`[HKEY_USERS]-[.DEFAULT]-[Control Panel]-[Keyboard]`の "InitialKeyboardIndicators" の値のデータを"2"または"2147483650"にするとよいそうです。
しかし自分のケースではうまくいきませんでした。上記のレジストリ位置とは違うのですが、`[HKEY_CURRENT_USER]-[Control Panel]-[Keyboard]`の "InitialKeyboardIndicators" を確認してみると、これを"2"または"2147483650"に変えても、再起動すると"0"に戻ってしまうのです。これは、次の項の設定が原因のようでした。
# スクリーンキーボードの設定
これが検索してようやく見つけた情報で、自分のケースでの根本原因でした。シャットダウン時にキーボード上ではNumLockを有効にしていても、再起動後にWindowsのスクリーンキーボード機能を開いてみると、NumLockは無効状態になっていたのです。起動したことさえ無かった機能でしたが、これを有効にして、そのまま再起動してみたところ、NumLockが有効な状態でログインすることができました。前述の`[HKEY_CURRENT_USER]-[Control Panel]-[Keyboard]`を確認しても、"0"に戻っていることはありませんでした。
# おわりに
ネットでまとまっている情報がほとんど上記3番目までしか書いておらず、5番目の情報を残しておきたいと思い、記事にしました。もし困っている方の助けになれば幸いです。
# おまけ：NumLockキーを使わない…いや、使う
上記のようにNumLockは常に有効でありたいマンなので、NumLockキーのキーバインドを変えてそもそも使えなくしてやろうと思いました。[こちらの記事](https://qiita.com/MatsumotoDesuyo/items/9355e3f1f9383bcf7c86)で紹介されているサイトからレジストリ変更ファイルを取得してえいやっと対応しました。しかし、対応した段階ではまだ上記5番目の解決策にたどり着いておらず、すなわちログインしてNumLockが無効な状態になっていて、しかしキーバインドを変えてしまったためNumLockキーを押してNumLockを有効にすることができない！するとNumLockが有効な状態でシャットダウンすることもできない！という真理に気付いたりしていました。
そういうわけなので、NumLockキーよりも全く押されることのないキーにNumLockを割り当てて、いざという時に切り替えができるようにしておこう、ということで、2つあるAltキーの右側（たぶん一度も押したことがない）にNumLockを割り当てる形を取ることにしました。
みなさんも、使わないからと言って一つしかないものをゼロにすると、いざという時に困ってしまう可能性があるので、そういうケースは慎重に扱いましょう。
リスナー指定無しでイベントリスナーを無力化

# はじめに
先日とあるWebラジオを聞こうとした際、バックグラウンド再生ができないことに気づき、どうにか毎回それほどの作業を必要とせずに、スマホでバックグラウンド再生できるようにできないか考えた時の副産物。

### この方法の特徴
* リスナーを指定しなくていい（**無名関数,アロー関数**も**無効化**できる）
* 対象の要素を絞れる
* イベントの種類も絞れる

ここでは以下のような処理を無効化する場合を考えてみる。
```exsample.js
window.addEventListener("test",function(){
    //無効化したい処理
});
```

`removeEventListener()`が使えればよかったが、無名関数やアロー関数では使えないし、外部から使用できる変数に格納されているわけもないので、`removeEventListener()`では歯が立たない。

そこで思いついたが`stopImmediatePropagation()`を使う方法だ。

https://qiita.com/hikagami/items/0739b766871d770e847d

# 最初に実行&他のリスナーを阻止作戦
イベントリスナーは基本**登録された順**に実行されるが、それでは後から追加したイベントリスナーで他のリスナーが実行されるのを阻止できない。

そこで、`addEventListener()`三つ目の引数、`useCapture`を使う。

https://qiita.com/tkengo/items/39a9ecd426e53d6bd513#usecapture

細かいことはいろいろあるが、`useCapture`を`true`に指定すれば大抵の場合そのイベントリスナーを最初に実行させるようにできる、ということらしい。

https://developer.mozilla.org/ja/docs/Web/API/EventTarget/addEventListener#usecapture

というわけで最終的にこんな感じ。
```exsample.js
window.addEventListener("test",function(e){
    e.stopImmediatePropagation();
},true);
```
* `useCapture`を`true`に指定して追加したリスナーが一番最初に実行されるようにする
* `stopImmediatePropagation()`で他のリスナーの実行を阻止

# おわりに
おわり
Power Automate for desktop のエラーをよく見る方法

※ この記事は、[Microsoft Power Automate Advent Calendar 2024](https://qiita.com/advent-calendar/2024/powerautomate) 12月5日 担当分の記事です

## Power Automate for desktop のエラーの確認方法
デスクトップ フローを作成する際、デザイナー画面から実行すると、実行時エラーが発生した場合、画面の下部にエラーリストが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729371/8dddf45b-dc53-92b6-1982-10ee5515b198.png)


## エラーリスト
エラーリストではエラーの種類（エラー／警告）、どのサブフローで発生してるのか、何行目（何アクション目）で発生しているかをわかりやすく表示してくれます。

また、エラーの説明を表示してくれているため、どのようなエラーが発生しているかを簡単に把握することができます。

## エラーの詳細
エラーリストの説明部分をダブルクリックすることで発生したエラーの詳細を確認することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729371/c5f932f7-e059-9cdc-6cfa-494ccbad3262.png)

下記は「Excel の起動」アクションで存在しないファイルを開こうとした際に表示されるものです。
エラーの詳細ではどこでエラーが発生しただけではなく、対処方法も記載されています。
対処方法は考えられるものが記載されていますので、1つ1つ確認することでエラーを解消する手がかりとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729371/e56952be-5b03-4019-e281-3a15acd5f5cf.png)

別な例としてアプリケーションのテキストボックスに文字が入力できなかった場合は以下のエラー詳細が表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729371/257040aa-cdab-66bc-b961-99d287b37de1.png)

対処方法として考えられる解消方法が記載されています。原因はUI 要素関連かと思いますが丁寧に確認していく必要があります。

>• アクションを実行する際に、UI 要素が画面に表示されていることを確認します。
• アクションの UI 要素の入力パラメーターが、指定したリストから正しく入力されていることを確認します。
• UI 要素のセレクターが正しいことを確認します。失敗したアクションの UI 要素パラメーターの隣にある [セレクター ビルダーを開く] ボタンを押すか、指定された UI 要素のセレクター ビルダー ウィンドウに移動し、次を行ってください。
   ▫ セレクターをテストします。
   ▫ [新規] ボタンを使用して、指定された UI 要素に追加するセレクターを取得します。
   ▫ [修復] オプションを選択して UI 要素のセレクターを修復し、表示される手順に従います。
   ▫ UI 要素のセレクターで使用される属性、属性値、オペランドを変更しながらセレクターを手動で編集し、より堅牢なセレクターを作成します。
• 実行中、UI 要素がすぐに表示されない場合は、「ウィンドウ コンテンツを待機する」アクションを追加してください。
• アプリケーションでバージョン アップグレードなどの変更が生じた場合、UI 要素に異なるセレクターが作成される可能性があります。その場合は、UI 要素を再度取得する必要があります。
>• UI 要素を含むアプリケーションと、デスクトップ用 Power Automate を含むアプリケーションが、どちらも同じ特権で実行されることを確認します。

## まとめ
開発中にエラーが発生するケースはいくつか考えられますが、エラーが出たからといってあきらめずにまずはエラーをダブルクリックしてみる。とヒントが隠させていますので参考にしてみるが良いのかなと思います。
Next.js Custom Server を Docker コンテナとして本番環境デプロイする

## 書くこと

セキュリティ要件のため通信を HTTPS で受ける Custom Server を開発する、ネットワーク要件のため Next.js を Docker コンテナで動かすことがあり、本番環境デプロイするにあたり調べて動かしたことを書きます。

Next.js バージョン 14 を前提とします。

## 結論：Dockerfile

```dockerfile
FROM node:20 AS builder

WORKDIR /app

COPY ./frontend /app

RUN npm ci

RUN npm run build
RUN npm run build:https-server

FROM node:20 AS runner

WORKDIR /app

COPY --from=builder /app/package*.json /app
COPY --from=builder /app/node_modules /app/node_modules
COPY --from=builder /app/.next /app/.next
COPY --from=builder /app/https-server/dist /app/https-server/dist

ENV NODE_ENV=production

EXPOSE 443

CMD ["node", "/app/https-server/dist/server.js"]
```

NPM Scripts は次を前提とします。

- "build": "next build"
- "build:https-server": "tsc --project tsconfig-for-https-server.json"

ディレクトリは次を前提とします。

- frontend
    - package.json
    - tsconfig.json
    - tsconfig-for-https-server.json
    - src
    - https-server
        - src
            - server.ts（Custom Server 実装）
        - dest
            - server.js（Custom Server ビルド成果物）


## 解説

Next.js ではビルド成果物を最小限にするため、ビルドの選択肢として standalone output mode がありますが、Custom Server では使えません。

> When using standalone output mode, it does not trace custom server files. This mode outputs a separate minimal server.js file, instead. These cannot be used together.

[Configuring: Custom Server | Next.js](https://nextjs.org/docs/pages/building-your-application/configuring/custom-server)

[next.config.js Options: output | Next.js](https://nextjs.org/docs/pages/api-reference/next-config-js/output) を参考に、次を COPY して動かすことができました。

- package*.json
- node_modules
- .next

静的コンテンツは次のように Docker コンテナ、または CDN などにデプロイできます。

```dockerfile
COPY --from=builder /app/.next/static /app/.next/static
COPY --from=builder /app/public /app/public
```

余地として依存関係のトレースなどでより最小限のビルド成果物にすることもできそうです。
公式に対応する動きもあるようなので、そのうちより簡単により最小限のビルド成果物で動かせるようになるかもしれない。
[Support custom servers with minimal node modules by MJez29 · Pull Request #72966 · vercel/next.js](https://github.com/vercel/next.js/pull/72966)
Cloudflare Pagesで原因不明の500エラーになった件

こんにちは、minabeと申します。

Cloudflareでデプロイしてるブログサイトが、2週間ほど前から落ちていました...。
ようやく解決できたので、備忘録として残しておきます。

## 使用技術
- Next.js v15
- Mantine v7
- NotionAPI

## 原因はcloudflare！
どうやら、Vercelのリリースバージョンが上がってしまったことで起きたっぽい。

症状としては、デプロイ後にURLを叩くと
> Internal server error

となってしまうというもの。
ローカルでは全く問題なかったので苦戦しました。

問題のなかったコミットに戻しても、環境変数を見直しても全く解決せず。
本当に原因がわからず大苦戦しました。

詳細 > Functionsのリアルタイムログで見られることに気づき、以下のエラーが見つかってからは早かったです。
> "Error: No such module \"__next-on-pages-dist__/functions/async_hooks\".\n  imported from \"__next-on-pages-dist__/functions/blog.func.js\""

全てはこのissueのおかげです。

https://github.com/cloudflare/next-on-pages/issues/908

## 解決方法
Vercelのバージョンを固定することで、一時的に解決する。
どうやらまだ根本的な解決はされてなさそう。

自分はpnpmを使用していたので、上記のissueに書いてるpackage.jsonの変更だけじゃダメだったのでこちらに記します。(一応issueコメントをしっかり読めば書いてますが。)

1. `package.json`を変更する
1. 設定を変える

### 1. `package.json`に以下を追記

```
"dependencies": {
  "@cloudflare/next-on-pages": "^1.13.6",
  "vercel": "39.1.1"
},
"overrides": {
  "vercel": "$vercel"
}
```
以下のコマンドで依存関係を解決する。

```
pnpm i
```

### 2. 設定を変更する
1. ランタイム > 互換性の日付を`"2024-09-23"`または`"2024-11-11"`にする
1. ビルドコマンド`pnpm exec next-on-pages`に変更する

## 最後に
何か問題があれば、コメントください。
お読みいただきありがとうございました！
インターネットが脳と認知に与える影響：論文要約

# はじめに
本記事はインターネットが脳と認知に与える影響を論じた論文の要約記事です。

```
The “online brain”: how the Internet may be changing our cognition

Joseph Firth, John Torous, Brendon Stubbs, Josh A Firth, Genevieve Z Steiner, Lee Smith, 
Mario Alvarez‐Jimenez, John Gleeson, Davy Vancampfort, Christopher J Armitage, Jerome Sarris

Article notes:Issue date 2019 Jun.
Copyright and License information:© 2019 World Psychiatric Association
PMCID: PMC6502424  
PMID: 31059635
```

https://pmc.ncbi.nlm.nih.gov/articles/PMC6502424/


## 論文の要約
本論文は、インターネットが現代社会の様々な側面に与える影響は明らかである一方、脳の構造と機能に与える影響は依然として重要な研究課題であるとし、心理学、精神医学、神経イメージングの最新の知見に基づいて、インターネットが認知に与える変化に関する主要な仮説を検証しています。具体的には、オンライン世界の独自の特徴が、以下の3つの側面にどのように影響を与えているのかを探求しています。

注意能力: 絶えず進化するオンライン情報の流れが、持続的な集中力を犠牲にして、複数のメディアソースへの分割された注意を助長している可能性。

記憶プロセス: 膨大で遍在するオンライン情報源が、知識の検索、保存、さらには価値観までも変化させ始めている可能性。

社会認知: オンラインの社会環境が現実世界の社会プロセスに類似し、それを想起させる能力が、自己概念や自尊心を含む、インターネットと社会生活の間の新たな相互作用を生み出している可能性。

利用可能な証拠は、インターネットがこれらの認知の各領域において、急性的および持続的な変化を引き起こす可能性を示しており、それは脳の変化に反映されている可能性があります。しかし、今後の研究の優先事項は、広範囲なオンラインメディアの使用が若者の認知発達に与える影響を特定し、高齢者のインターネット利用の認知への影響や脳への影響とどのように異なるかを検証することです。

インターネットは人類史上最も普及し、急速に普及している技術です。わずか数十年で、インターネットの利用は、情報の検索、メディアやエンターテイメントの消費、ソーシャルネットワークや人間関係の管理方法を完全に刷新しました。スマートフォンの登場により、インターネットへのアクセスは携帯可能でユビキタスになり、先進国の人口は「オンライン」と見なせるようになりました。

しかし、この新しい接続、情報、コミュニケーション、および画面時間のチャネルが、私たちの脳と認知機能に与えている影響は不明です。インターネット以前の研究で、脳は特に新しいプロセスを学習する際に、神経可塑性によって環境の要求や刺激に対してある程度可塑的であることが示されていました。第二言語の習得、ジャグリングなどの新しい運動技能の学習、さらには正式な教育や試験準備など、さまざまな状況が人間の脳の神経構造に長期的な変化をもたらすことが観察されています。世界中でインターネットが広く使用されるようになったことで、多くの人々にとって、社会と相互作用するための無数の新しいスキルと方法を学習する必要性と機会が生まれ、それが神経の変化をもたらす可能性があります。例えば、スマートフォンのタッチスクリーンインターフェースを介したインターネットとの単純な相互作用でさえ、手と親指の感覚および運動処理に関連する皮質領域の神経変化により、持続的な神経認知の変化をもたらすことが示されています。さらに、インターネットは、オンラインとオフラインの両方の世界に関連する、新しい情報と複雑なプロセスのほぼ無限の学習のための新しいプラットフォームも提供します。

神経可塑性のメカニズムに加えて、他の環境要因や生物学的要因も脳の構造と機能に変化を引き起こし、認知機能の低下につながる可能性があります。例えば、高齢者のサンプルでは、加齢に伴う認知機能の低下は、部分的に萎縮のプロセスによって引き起こされる可能性があることを示す証拠があります。いくつかの研究では、生涯を通じて関与の少ないライフスタイルを採用すると、低い「認知予備能」（加齢や病状による損傷に脳が耐える能力）のために、認知機能の低下が加速する可能性があることが示されています。新たな証拠は、仮想環境を支持して「現実世界」から離れることが、同様に有害な神経認知の変化を引き起こす可能性があることを示しています。例えば、最近の無作為化比較試験では、6週間のオンラインロールプレイングゲームへの参加が、衝動制御と意思決定に関与する脳領域である眼窩前頭皮質の灰白質の有意な減少を引き起こすことがわかりました。

インターネットが私たちの脳の構造、機能、および認知発達に影響を与える可能性のある複数の経路を経験的に調査する実質的な研究が生まれています。具体的には、既存の研究の大部分は、インターネットがどのように影響を与えているかを調査する3つの特定の領域に分けられます。

a）注意（つまり、絶え間ないオンライン情報、プロンプト、および通知が私たちの注意を奪い合い、複数の受信メディアストリームに集中力を分散させるように人々を促す可能性とその結果）。

b）記憶と知識（つまり、インターネットを主要な情報源としてどの程度依存しているか、オンライン情報アクセスの独自性が新しい記憶の処理方法と内部知識の評価にどのように影響するか）。

c）社会認知（オンライン世界に社会ネットワーク、相互作用、およびステータスをますます組み込むことの個人的および社会的な結果）。


本論文では、インターネットがこれらの認知プロセスをどのように変化させるかについての現在の主要な仮説を提示し、その後、これらの仮説が心理学、精神医学、および神経イメージング研究からの最近の発見によってどの程度裏付けられているかを検証しています。このようにして、複数の研究分野から生じる現代の証拠を集約し、インターネットが私たちの脳と認知にどのように影響を与えているかについての改訂されたモデルを作成します。さらに、これまでの研究は特定の年齢層にのみ焦点を当ててきましたが、生涯にわたる人間の脳に対するインターネットの影響を検証します。特に、認知プロセスと広範囲なインターネット統合の潜在的な利点/欠点が、子供と高齢者でどのように異なるかを探ります。最後に、既存の文献の重要なギャップを特定し、インターネットの有害な影響を最小限に抑えながら、社会のこの新しい特徴を利用して神経認知プロセスに有益な影響を与えるための新しい洞察を得るために、将来の研究のための重要な優先事項を提示します。
Kong API Gatewayと過ごした四年間

![いつも心の片隅にkongを宿して日々生きるプログラマー.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18012/309d29c4-8804-b1ee-bbad-08ef65348611.jpeg)

本記事は「[Kong Advent Calendar 2024](https://qiita.com/advent-calendar/2024/kong)」の20日目のエントリとして、Kong Gatewayを実際にプロダクト環境で4年間運用して得た経験を皆様に還元いたします。

## はじめに
皆さんはKong API Gatewayを運用していますでしょうか？マイクロサービスアーキテクチャにおいて、APIゲートウェイは不可欠な存在です。本記事では、私たちのチームがKongを4年間運用してきた経験を基に、Kongのメリットとデメリット、そして意外な活用事例についてご紹介します。

4年前、私たちがKong Gatewayを本番環境で運用始めた際には情報が少なく、不安もありました。
2020年の初夢にはゴリラが出てくる程度には寝ても覚めてもKongのことを考えていた4年間の一つの区切りとしてアウトプットを以下に記載いたします。

## 私たちの環境
* 利用している Kong製品： Kong Gateway, Kong Ingress Controller, Kong Helm Chart, 自作したGo製のKong Plugin
* 利用期間：約4年
* 利用規模：Kubernetes上の150くらいのマイクロサービス
* 利用目的：独自の認証認可をkong pluginに集約した集中管理

## Kongを使っていてよかったところ
### 高い拡張性と柔軟性
Kongは、プラグインによって機能を拡張できることが大きな特徴です。認証、レート制限、キャッシュなど、様々な機能をプラグインで実現できます。また、Kongはオープンソースであるため、コミュニティが開発したプラグインも豊富に存在します。
そして、まさに、Kong Pluginを自作することで独自の認証認可機構を構築できる目処が立った点こそがKong Gatewayを利用するに至った点でもあります。
### 高いパフォーマンス
Kongは、Luaで実装されており、高いパフォーマンスを実現しています。大規模なトラフィックにも耐えうるスケーラビリティも魅力です。
Kong Gatewayを配置したKuberntes上のpodがスケールアウトする速度も申し分なく、スパイクアクセスがあっても、大きな問題は起きていません。
### Kubernetesとの高い親和性
Kong Ingress Controllerを利用することで、Kubernetes環境にKongを簡単に導入できます。KubernetesのService Discoveryと連携し、動的なサービスの管理も可能です。
### 充実したドキュメントとコミュニティ
Kongは、公式ドキュメントが充実しており、コミュニティも活発です。基本的には何か問題があっても情報が見つからないといったケースには出会っていません。

## Kongの辛いところ
### 設定の複雑さ
Kongの設定は、YAML形式で行います。プラグインの設定も複雑になりがちで、初心者にとっては学習コストが高い場合があります。
運用が安定するまでは、設定が意図通り機能しているのかを確認するのにかなり時間を費やすことがありました。

### バージョンアップ時の影響
Kongは、頻繁にバージョンアップが行われます。バージョンアップに伴い、設定やプラグインの変更が必要になる場合があります。
私たちのチームはKong関連のプロダクトを複数組み合わせているため、そのバージョン毎の組み合わせと頻度には注意を払いつつ運用をしてきています。
ただし、Kong Gateway 3.4以降LTSによって安定した運用が可能になってきています。

### エラーログを止める術がない場合がある
正常に動作しており、利用状況としては問題ない場合でもエラーログが出力されるため、運用上許容すべきエラーログを運用ドキュメントにまとめたり、量の多いものはDatadogで上除外する形の運用を実施しています。
見逃してはいけないエラーログと運用上許容数エラーログの判別には慎重な判断が求められます。
（ただ、実際は動いていれば許容するという方向に流れがちではあります。）

## 4年間運用して感じたこと
### Kong Pluginの柔軟性とパフォーマンス
Kong Pluginは公式のものはLuaによる実装ですが、Go言語やPytohn、JavaScriptでも記述できます。私たちは、Go言語で高性能なカスタムプラグインを開発し、特定の要件に対応してきました。

### Kong Helm Chartの便利さ
Kong Helm Chartを利用することで、Kubernetesへの導入が非常に簡単になります。また、リリースノートには、Breaking Changeが丁寧に記載されているため、バージョンアップ時の影響を事前に把握できます。

### nginxの機能との親和性
Kongは、nginxを内包しているため、nginxで利用していた機能をそのまま利用できます。例えば、log formatを既存のシステムと合わせることで、ログ解析の効率化を図ることができます。

## まとめ
書き出してみると、当たり障りのない使い方をしているのかもしれませんが、Kongという素晴らしい製品に助けられた四年間であったと考えられます。
できる範囲で、恩恵を受けた分はKong コミュニティにもお返し出来たらと考えこの記事を作成しました。

Kongの導入を検討されている方の参考になれば幸いです。

_上記は、私がKong Gatewayを運用してきた個人的な経験と見解に基づいたものです。所属組織の見解とは異なる場合があります。_
GAになったElastic Cloud Serverless の料金を測ってみた (続編)

今月12月についにGAリリースとなったElastic Cloud Serverlessはどのくらいの料金なのか？
実際にデータを投入して計測してみました。

まだ読んでない方は[前回の記事](https://qiita.com/nobuhikosekiya/items/01b67501b53387fdf6fd)からお読みください。

# Searchプロジェクトのその後

前回の記事から暫く環境を放置していて、改めて料金を確認してみると、Search (Elasticsearch)プロジェクトの方の料金もDec 12以降は費用が発生していないように見えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109197/0d578b6c-3647-7b10-7fe4-649ff3665470.png)

Dec 12以降クローズアップすると、非常にわずかな金額がかかっていといるという状況でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109197/d9b3408f-acbf-94eb-8e8e-c60b1ef36577.png)

この数日の間で0.0026 ECU ( =$0.0026、0.40円くらい）かかっていますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109197/aeac42b9-aebc-3660-e9db-f0d11a8668e2.png)


# ログを検索してみた
3つのプロジェクトについて、それぞれKibanaのDiscoverを使ってログを閲覧してみました。以下はSearchプロジェクトの例です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109197/7681ab63-5cf4-8c6c-d2e3-21f68d393e37.png)

ObservabilityとSecurityは、検索操作によって追加の費用がかかることは発生しない料金体系なので費用0ですが、Searchの方は検索によって使用されるコンピュートパワーをVCUという表現を使って課金が発生するのがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109197/3b60d587-60da-99a1-cfbc-83c603156f4a.png)

Searchプロジェクトの中の管理画面を見ると、操作したタイミングの1時間の中で0.6667 VCUが使われていたことがわかります。（1 VCUが1GB RAM分のコンピュートなので、それが1時間未満の分、今回使われていたというようなイメージかと思います）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109197/268ea5d9-58c9-b284-cb3f-dc69a258b984.png)

# おわり
Searchプロジェクトの料金の完全な動きについては掴みきれないところがありますが、検索をかければ費用が従量的にかかり、検索をしなければほとんどかからない、という特徴は見えたかと思います。
Xcodeで作成したコードをGitHubにpush

Xcodeで作成したコードをGitHubにpushしたので
手順をメモしておきます

## 1. GitHubリポジトリの作成
GitHubにログインして、リポジトリを作成
最初の注意点は以下の通りです
 - README fileは作成すべき
 - Xcodeで作成したiPhoneアプリならgitignoreはswiftにすべき
 - licenseはとりあえずMITにしておけば良い

## 2. GitHubにリポジトリをプッシュ
### (a) ターミナルを使用
#### 1.プロジェクトフォルダに移動
```
cd path/to/your/project
```

#### 2.GitHubリポジトリをリモートリポジトリとして設定
```
git remote add origin https://github.com/username/repository.git
```

#### 3.変更をステージング＆コミット


ここで、そのまま、pushしようとすると
リポジトリ作成時に作成したファイルが原因で
エラーが発生してしまうため
merge（デフォルト）すなわち、リモートブランチの変更をローカルに統合し
新しい「マージコミット」を作成する必要があります。
```
git config pull.rebase false
```

また、さらに面倒なのですが
履歴を統合するために、--allow-unrelated-historiesオプションを使用します。
```
git pull origin main --allow-unrelated-histories
```

ようやくステージングとコミットができます
```
git add .
git commit -m "Initial commit"
```

#### 4.コードをGitHubにプッシュ
```
git push -u origin main
```

ここでGitHubのIDとPersonal Access Token（以下PAT）を求められます

Settings > Developer settings > Personal access tokensで新トークンを生成します。
![スクリーンショット 2024-12-16 18.58.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2790258/3e505a28-95c8-f6fe-36a4-90e366b51592.png)

「Contents」にRead/Write権限を付与します
![スクリーンショット 2024-12-16 18.58.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2790258/990e4773-07d5-7c4c-9d61-f8e713c59118.png)

ユーザーネームは、githubのアカウント名
パスワードに、生成したFine-grained personal access tokensをコピーして
ペーストします

上手くいくとこんな感じです
![スクリーンショット 2024-12-16 19.00.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2790258/422dc455-74ed-8df1-5a9d-174730eba492.png)

以上です。
Dockerで、discord.jsのbotを動かす

# Dockerを使ってDiscord.jsのBotを動かす

DiscordのBotを構築したことがある人なら、環境設定やライブラリのバージョンコントロールに問題を感じたことがあるかもしれません。Dockerを使用することで、これらの問題を治め、アプリを簡単に配布しやすくなります。今回は、Dockerを使ってDiscord.jsのBotを動かす方法を紹介します。

## この記事の目的

- Dockerイメージを使ってDiscord.jsのBotを動かす
- Node.js環境を構築するためにDockerfileを作成
- Botのコードを実行するためのコンテナ設定

## 実装ステップ

### 1. プロジェクトファイルの準備

以下の構成のディレクトリを用意します。

```
my-discord-bot/
├── bot.js
├── package.json
└── Dockerfile
```

#### bot.js

こちらには簡単なDiscord.jsのBotコードを記載します。

```javascript
const { Client, GatewayIntentBits } = require('discord.js');
const client = new Client({ intents: [GatewayIntentBits.Guilds] });

client.once('ready', () => {
    console.log('Ready!');
});

client.on('messageCreate', message => {
    if (message.content === 'ping') {
        message.reply('pong');
    }
});

client.login('YOUR_BOT_TOKEN');
```

#### package.json

プロジェクトの依存関係を定義します。

```json
{
  "name": "my-discord-bot",
  "version": "1.0.0",
  "main": "bot.js",
  "scripts": {
    "start": "node bot.js"
  },
  "dependencies": {
    "discord.js": "^14.0.0"
  }
}
```

### 2. Dockerfileの作成

Dockerイメージを作成するためのDockerfileを用意します。

```Dockerfile
# ベースイメージにNode.jsを使用
FROM node:18

# アプリケーションディレクトリをコンテナにコピー
WORKDIR /usr/src/app

# package.jsonをコピー
COPY package.json ./

# 依存関係をインストール
RUN npm install

# コードをコピー
COPY . .

# Botを実行
CMD [ "npm", "start" ]
```

### 3. Dockerイメージの作成と実行

下記のコマンドを実行します。

1. Dockerイメージの作成

```bash
docker build -t my-discord-bot .
```

2. Dockerコンテナの起動

```bash
docker run -d my-discord-bot
```

### 4. 動作確認

ボットがオンラインになり、チャンネル内で`ping`と打ち込むと、`pong`と復答するはずです。

## おわりに

Dockerを使用することで、構築した環境を別のマシンでも再現できるので、開発やテストが滿切になります。DockerとDiscord.jsを利用して、自分のボットをさらに充実させましょう。
Bolt.newのOSS版「Bolt.diy」をローカルLLMで動かしてみる

今回はAIフルスタック開発で人気のあるBolt.newのOSS版「Bolt.diy」をローカル環境に構築します。
せっかくなのでローカルLLMを使用したアプリ開発にチャレンジしてみようと思います。

Bolt.diyの構築手順は[公式ドキュメント](https://stackblitz-labs.github.io/bolt.diy/)を元に進めていくので詳細を確認されたい方はこちらを参考にしてください。
ローカルLLMは筆者の環境ではGPUがないため、CPUで動かすことができる「[LMStudio](https://lmstudio.ai/)」を使用します。LMStudioのインストール手順については割愛します。

## Bolt.diyとは？
Bolt.diy は AI を活用した Web 開発エージェントで、ブラウザから直接フルスタック アプリケーションをプロンプト、実行、編集、デプロイが可能です。
https://stackblitz-labs.github.io/bolt.diy/

## 環境
- Windows11（RAM 32GB）
- Docker Desktop
- LMStudio
- bolt.diy（v0.0.3）

## 環境構築
### 1. LMStudioの起動
LMStudioを起動し、モデルをセットします。今回は「Llama3-Elyza」で試してみます。
CORSを有効化し、「Start Server」で起動しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356313/e5a8fbc4-1cf4-ca66-0035-d3a93527d97b.png)


### 2. リポジトリのクローン
Bolt.diyのリポジトリをクローンします。
``` 
git clone -b stable https://github.com/stackblitz-labs/bolt.diy  
``` 
### 3. LMStudioのURLを設定
.env.localを作成し、LLMStudioのURLを設定します。LMStudioを使用せず、OpenAI等を使用したい場合はそれぞれのAPIキーを設定してください。
``` 
cd bolt.diy
cp .env.example .env.local
```

ホスト上のLMStudioと接続するため、host.docker.internalを指定します。
```.env.local
# Get LMStudio Base URL from LM Studio Developer Console
# Make sure to enable CORS
# Example: http://localhost:1234
LMSTUDIO_API_BASE_URL=http://host.docker.internal:1234
```
### 3. build & 起動
続いて以下のコマンドでbuildを実行してください。
```
docker build . --target bolt-ai-development
```
buildが正常に終了しましたら、以下のコマンドで起動しましょう！
```
docker-compose --profile development up -d
```
以下のメッセージが出力されればOKです。
```
[+] Running 2/2
 ✔ Network boltdiy_default      Created                                                         0.2s 
 ✔ Container boltdiy-app-dev-1  Started
```
ブラウザから`http://localhost:5173/`にアクセスするとbolt.diyの画面が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356313/0097f9fd-9004-3ed2-4c67-95014eb4310d.png)

### 4. Bolt.diyをローカルLLMで動かしてみる
では、ローカルLLMでbolt.diyを動かしてみましょう。
プルダウンから「LMStudio」を選択して作りたいアプリを入力します。モデルは指定しなくてもLMStudioでセットされたモデルが使用されます。
今回は簡単な電卓アプリが作れるか試してみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356313/442085c9-7747-3c0c-6ba8-ea223806f09e.png)

ローカルLLMが頑張って出力しているのをPCファンの音で実感をしつつ、じっくり待っているとなんとかそれっぽいのを作ってくれました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356313/65660472-e131-72eb-647f-c405e77f1971.png)

viteで作ってくれたので`npm install`と`npm install -D vite`をTerminalから実行して準備完了！
早速動かしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356313/359b8646-965a-2cc0-c019-b723493da8e3.png)
ちょっと想像してた電卓とは違いますが、とりあえず計算してくれるアプリが作れたようです。
ちなみに計算してみたら画面遷移して真っ白な画面が表示されました笑

### 5. まとめ
今回はローカルでbolt.diyを構築し、ローカルLLMで動かすというローカル尽くしの構成でチャレンジしてみました。
実用性があるかと言われると正直首をかしげるところではありますが、楽しくチャレンジすることができました。
bolt.diyのプロンプトやLMStudio側の設定次第では、精度を上げられるかもしれませんので引き続き検証していきたいと思います。
四則演算クソアプリでみる見えないエラーへの注意のすゝめ

## しっかり指定してくれなきゃわかんないでしょうが！
プログラミングを利用すれば人がやるより比較しようがないくらい効率的に処理を行ってくれるってやっぱ最高。

**と、思うじゃない？**

別にケチ付けようってわけじゃぁございやせん。今の世の中プログラミングがなきゃ回んないのも事実でございます。

「じゃ、なんで『と、思うじゃない？』なんて言うの？」ってところが今回のミソ。まぁそんなこと求めるなって話ですが、「プログラムは融通が利かない」、これなんですよね。

欲しい答えを得るためには適切なプログラムを組まなくてはならない。あっちは「えぇ？これほんま合ってますのん？実はお客さんこんなこと求めてるんじゃないんですか？」なぁんて言ってくれない。「あんたがこう書いたからそれに従って出力しただけでしょうが！」とご立腹。

どういうこと？こういうこと。具体例に行ってみましょう。
## 5÷3は1
タイトルは後程回収するとしてとりあえず四則演算用のアプリケーションを作成。
前回ご紹介した『**Windowsフォームアプリケーション**』先生にまた出張ってもらいましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944350/da6fd521-a069-dfc4-a0e9-58aed03ee3f0.png)
というわけでできたアプリケーションがこんな感じ。いい感じでしょう？
やっぱり『**Windowsフォームアプリケーション**』先生は偉大だなぁ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944350/0958e8d1-ce3f-6e01-b699-9a6617022924.png)


さぁ、ボタンを押せば四則演算の開始です。今回は値1を5、値2を3として計算しましょう。

というわけでぽちっとな。
5+3=8
5-3=2
5×3=15
「5÷3」は・・・割り切れない？1.66666？御冗談を。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944350/c37f87e3-a547-7007-be84-64a0d5f3aa51.png)


答えは1!
・・・何を馬鹿なと思うわけです。

ここでタイトル回収ですね。なぜ答えが1となるのか、実際にコードを見てみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944350/807cdf6d-5b92-0514-eba0-6333d63eba94.png)
さぁさぁ、Convert.ToInt32の所にご注目。textをint型に変更していますね。

これがネック！int型は整数しか扱えない。小数？知らない子ですね。

整数しか扱えない世界線で割り算を行うとどうなるか、0方向に丸め込んだ結果を出してきます。例えば5÷3であれば2より1のほうが0に近いため1、-5÷3であれば-2より-1のほうが0に近いため-1が結果として出力されます。

まぁ、商はたしかに正しいかもしれませんが、余りもないですし算数・数学ができる皆さんは違和感を覚えるかもしれません。でもこれがint型。整数でしか表現できない悲しき定め。

では欲しい答えを得るためにはどうするか。選択肢は3つかな？
①割り切れないと教える
→クソアプリ作成のために今回やる

②余りも表示する
→演算子？として「%」を追加してそれも表示するboxを作る

③小数点以下まで表示する
→double型にする

って感じですかな。それじゃクソアプリを作りましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944350/640c0c49-ec6e-f7e9-96d8-da5a3773a81d.png)
コードはこんな感じ。余りが0でなかった場合に渾身の「割り切れないぜ！」を表示して、0だったら割った値を表示する。というわけで再度ポチッとな
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944350/0ad9d334-f2de-6115-2623-5b07265fa312.png)
出ましたね、渾身の「割り切れないぜ！」。ここでもう一個確認しときましょう。割れる場合なら？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944350/49d7bb9a-626a-802c-c44e-e4992c6a0ce4.png)
ちゃぁんと割った値が出てきてくれましたね。めでたしめでたし。

## 何が！言いたいって！！言うんだ！！！
「え？おしまい？」、はいおしまいです。

言いたいことは、最初にも言いましたが「プログラムは融通が利かない」ということ。

こっちの求めていることを正確に記述しないと、プログラムは違った答えを返してくるかもしれません。でもこれでいいんです。

融通が利くプログラムなんて嫌でしょう？それこそ「あ、こう思ったんで勝手にこっちで解答変えときました！」なんてたまったもんじゃありません。

**いつだってエラーを起こすのは自分が問題。ただ本当の問題は、エラーに気付かないこと。**

今回具体例として挙げた四則演算クソアプリ、答えが1だろうとエラーは別に吐いてくれません。自分が気付かなければ間違ったままになってしまう。

上手くいっていると思ってもどこかに異変がないかと探す、感覚的には『**8番出口**』に近いか？良いゲームが配信されたものです。
【Python】AlembicでDateTime型のデフォルト値を挿入時の現在時刻にする方法

# 概要
Pythonアプリで、SQLAlchemyとAlembicを利用してMySQLのDBを利用しています。
`DateTime`型のカラムのデフォルト値をレコード作成時の「現在時刻」にする方法が、いくつかあったので紹介します。

### 前提
db：mysql8.0
python：3.12
alembic：1.13.2
SQLAlchemy：2.0.32

# ①`server_default=func.now()`を指定する方法
以下のようなモデル定義があるとします。

```py
class SampleTable(Base):
    __tablename__ = 'sample_table'
    id = Column(Integer, primary_key=True, autoincrement=True)
    created_at = Column(DateTime, nullable=False, server_default=func.now())
```

上記のように`server_default=func.now()`と指定すると、
マイグレーション(`alembic revision --autogenerate`実行)時に生成されるマイグレーションファイルでは、

```py
sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False)
```

と記載されました。
`sa.text('now()'`と認識されるのですね。

基本、これで問題ないと思います。

`func.now()`は、SQLAlchemyの`func`モジュールを使用して、DBの現在時刻を取得する関数です。

Alembicのドキュメントにも`server_default`というパラメータと関数`func.now()`を使っている記述がありました。

https://alembic.sqlalchemy.org/en/latest/ops.html#alembic.operations.Operations.alter_column.params.server_default

```py
from alembic import op
from sqlalchemy import Column, TIMESTAMP, func

# specify "DEFAULT NOW" along with the column add
op.add_column(
    "account",
    Column("timestamp", TIMESTAMP, server_default=func.now()),
)
```

上記のように、公式ドキュメントでは、`server_default=func.now()`を推奨しているようです。

ただ、ネットで調べてみると、他にも実現方法があるとのことで、ついでに検証してみました。

### ②`server_default=text('now()')`を指定する方法

まずは以下。
マイグレーションファイルで生成された`text('now()')`をそのままモデル定義で入れてみます。

```py
class SampleTable(Base):
    __tablename__ = 'sample_table'
    id = Column(Integer, primary_key=True, autoincrement=True)
    created_at = Column(DateTime, nullable=False, server_default=text('now()'))
```

結果、マイグレーションファイルには先ほどと同じように`server_default=sa.text('now()')`が記載されていました。

```py
sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
```

作成したテーブルに、試しに`created_at`の値に何も入れずにレコードを挿入すると、現在時刻になっていることを確認できました。
直接SQLを指定してあげてもいいのですね。

### ③`server_default=func.current_timestamp()`を指定する方法
また、`current_timestamp`を使った方法もあるとのことで、以下のモデル定義にしてみます。


```py
class SampleTable(Base):
    __tablename__ = 'sample_table'
    created_at = Column(DateTime, nullable=False, server_default=func.current_timestamp())
```

これでマイグレーションファイルを生成すると...

```py
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
```

というようになりました。
先ほどとはマイグレーションファイルの記述方法が異なりますが、
こちらもレコード挿入時に現在時刻になっていることを確認できました。

ということで、結論、
上記で挙げた方法であれば、マイグレーション時に自動で現在時刻というように読み取ってくれるようです。

私は公式docにある`server_default=func.now()`を採用しました。

## 備考
一点、注意点があるとすれば...

モデル定義で

```py
class SampleTable(Base):
    __tablename__ = 'sample_table'
    created_at = Column(DateTime, nullable=False, default=func.now())
```

というように、`server_default`ではなく`default`とすると、これはデフォルトのオプションパラメータとして認識してくれません。このままマイグレートして、`created_at`未指定でレコード挿入すると以下のエラーになります。


> SQLエラー [1364] [HY000]: Field 'created_at' doesn't have a default value
エラーメッセージを読み解くための6つの心得

プログラミングを始めたばかりの新人プログラマにとって、エラーメッセージは難解で厄介な存在に思えるかもしれません。

プログラムを実行した際にエラーが発生すると、どうしても焦ってしまい、その内容を深く読まずに試行錯誤を重ねてしまいがちです。しかし、エラーメッセージには問題解決のための重要な手がかりが詰まっています。

エラーが発生したときにどのように対処すれば効率的に問題を解決できるか、そして次回以降のエラー解決にも応用できるようになるための考え方ついて解説します。

## 1. まずは立ち止まる

エラーが出たとき、最初にすべきことは立ち止まることです。焦ってコードをいじり始めるまえに、画面に表示されたエラーメッセージをじっくりと読みましょう。エラーの内容を読み飛ばしてしまうと、原因を見落としてしまい、余計な時間を費やしてしまいます。

## 2. エラーメッセージの構造を理解する

エラーメッセージには一般的に以下のような構造があります。

- **エラーの種類**
 例: `SyntaxError`, `NullPointerException`, `ArgumentError` など。これが何を意味するのかを調べることが解決の糸口になります。
- **エラーの詳細情報**
 どのような問題が発生したのかが説明されています。
 例: `unexpected end of input` や `undefined method foo for nil:NilClass`
- **発生箇所**
  エラーが発生したコードの行番号やファイル名が記載されています
  例: `app/models/user.rb:42`

エラーメッセージ全体をみてそれぞれの要素を確認することで、問題の原因を特定しやすくなります。

## 3. 再現性を確認する

同じエラーが再現するかどうかを確認することも重要です。一度発生したエラーが再現可能であれば、何が原因でエラーが起きているのかを絞り込む手がかりになります。

- 入力データや設定を確認する
- 同じ操作やコード実行でエラーが再び発生するかを試す

再現性を確認することで、偶然のバグや環境依存の問題かどうかを切り分けられます。

## 4. エラーを調べる

エラーの種類や詳細情報をインターネットで検索してみましょう。同じエラーに遭遇した人が解決方法を共有しているケースが多々あります。

検索する際のポイント

- エラーの種類とキーワードを組み合わせる
   例: `Ruby NoMethodError undefined method`
- 必要に応じて、使用しているフレームワークやライブラリの名前も加える
  例: `Rails ActiveRecord RecordNotFound`

## 5. 原因を特定して修正する

エラーの原因を特定したら、それを修正します。修正を行った後は必ず再度プログラムを実行し、エラーが解消されたことを確認しましょう。

- 修正内容を最小限にする
  一度に多くの変更を加えると、どの変更が効果をもたらしたのか分からなくなることがあります
- 修正後に再びテストを行い、同じエラーが発生しないことを確認する

## 6. 次に備える

エラーを解決した後は、その経験を活かして次回以降に備えましょう。

- 原因と解決方法を記録する
  - エラー解決ログを残しておくと、似たような問題が発生したときに素早く対応できます
- エラーの背景を理解する
  - なぜそのエラーが発生したのかを学び、同じミスを繰り返さないようにします

## まとめ

- エラーメッセージを単なる障害物でおわらせない
- 焦らずに立ち止まり、エラーの内容をしっかりと読み解いて効率的に問題を解決するスキルが身につける

このプロセスを繰り返すことで、エラーに対処する力だけでなく、プログラマとしての成長にもつながります。

ぜひ、次にエラーに遭遇したときには、この記事を参考に落ち着いて対処してみてください。
LangChainの長期メモリー機能：LangMemについて 1/2

最近しばらくLangChainに触れていなかったのですが、昨日ふと公式ブログを見たところ、LangGraph（LangChainのエージェント構築機能）に「長期メモリ機能」が追加されたようです。この機能はなかなか面白そうですので、共有したいと思います。

https://blog.langchain.dev/launching-long-term-memory-support-in-langgraph/


ブログ記事によると、LLMとの会話で用いられるメモリには大きく2種類あります。
1つは短期メモリ（on-memory）で、これは現在の会話セッション中の内容を保持するものです。一般的な手法としては、会話終了ごとに比較的軽量なLLMで前回までの対話を要約し、その要約を次回以降の応答生成時に参照します。そして新たな会話が終わるたびに、またその要約を更新していくわけです。こうすることで、長い対話でも一貫した文脈を保持できるようにします。

2つ目は長期メモリ、いわゆる「クロススレッドメモリ（Cross-Thread Memory）」で、これは過去の会話履歴を蓄積しておくことで、セッションを跨いだ記憶を実現する仕組みです。短期メモリよりは、以前の対話内容を参照しつつ、より深い文脈理解に基づいた応答が可能になります。

LangChainが公開された長期メモリ機能の実装例⇩

https://github.com/langchain-ai/memory-agent/blob/main/src/memory_agent/graph.py

仕組み自体はシンプルです。過去の対話内容を「メモリストア」に格納し、ベクトル化して保存します。そして新たに応答を生成する際には、このメモリストアから関連度の高いメモリチャンクを検索して参照します。たとえば、直近3つのユーザークエリを使用し、関連度が高い10件のメモリチャンクを抽出して、それらを踏まえて回答を生成します。

さらに、LangChainはこのメモリストアへのアクセスをエージェントとして組み込んで、必要に応じてそのエージェントを呼び出せるようにしています。⇩

![屏幕截图 2024-12-15 101332.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/d8f91bd2-5827-091c-9017-0bbd54d1c5bd.png)

この長期メモリ機能は非常に汎用的であり、LangChainのブログによれば、将来的にはLangGraphの標準エージェントとして組み込まれる予定とのことです。最近ちょっと試してみたいと思います。

興味ある方：

https://blog.langchain.dev/launching-long-term-memory-support-in-langgraph/
キントーンの基本知識

# はじめに

この記事はキントーンについて学習した内容を記録した備忘録です。
誤りがあった場合は適宜修正します

## キントーンとJavaScript

キントーンは、ドラッグ&ドロップによる操作で簡単に入力フォームとデータベースを作成できるクラウド型の業務改善ツールです。
プログラミングの知識がなくても、ドラッグ＆ドロップでカスタマイズ可能な入力フォームを作成することができます。

ただし、フィールドに対する入力規則（例: メールアドレスフィールドに日本語や不正な形式の文字列が入力された場合にエラーを発生させる）を含め、単純な入力フォーム標準機能では提供されていません。
これを実現するには、JavaScriptで独自に実装するか、メールアドレス形式のチェックを行うプラグインをインストールする必要があります。

## JavaScriptで実装が必要なケース

- フィールドに対する細かいバリデーション
    - メールアドレスの形式チェック
    - 電話番号のフォーマット
    - 特定の文字列や数値範囲のチェック など
- フィールド値の自動計算や自動入力
    - 入力値から自動で別のフィールドを計算
    - 日付フィールドの値を元に別フィールドへ曜日を表示
- 入力データのリアルタイム検証
    - 入力中にエラーを即時に表示させる
- 特定条件に基づく動的なフォーム表示制御
    - あるフィールドの値によって別のフィールドを非表示にする
- 保存後の自動処理
    - レコードが保存された後に別のシステムやAPIと連携して通知を送信

## プラグインで実装できること
- 簡易なフィールドバリデーション
    - メールアドレス形式のチェック（特定のプラグイン使用時）
- データの自動計算
    - フィールド同士の値を足し合わせる自動計算プラグイン
- データの外部サービス連携
    - Google スプレッドシート
    - Slack
    - LINEなどのサービス連携
- 既存機能の拡張
    - カレンダー表示
    - グラフ表示などを簡単に追加


## キントーンのイベント処理について

https://qiita.com/EasyCoder/items/8296e0dd59c4a7b54169