OmniAICreator/Qiita-1.07M huggingface dataset:
IT企業の就職活動

# はじめに
今年ももうすぐ終わりますね。新年を迎えるとともに就職活動という避けられない壁があり不安に感じています。せっかくなので、就職活動についていろいろ調べてまとめていきたいと思います。
　
## 就職活動概要
　まず初めに就活のスケジュールを見ていきましょう。

 　
 ![25schedule.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636254/a4aeae55-9f6d-f756-89ef-bf6f53fc5b3a.jpeg)
　
　　　　　　　　　　　　　　　　[< 理系ナビ　２０２５より >](https://rikeinavi.com/25/?utm_source=Google&utm_campaign=new_brand&utm_medium=cpc&gad_source=1&gclid=EAIaIQobChMI-N_Emt2IgwMVXxJ7Bx0DMwb5EAAYAiAAEgKxJvD_BwE)
 

 　
 　大まかな流れは採用情報が公開される３月までにインターンや企業研究をして、そこから選考が始まるようですね。６月から採用選考とありますが、５月末時点で約７割の就活生が内定をもらっているということで４月５月で就活は終わらせたいですね。２年制の学生は１年強で就職先が決まると考えるとかなりスピーディーでやることが多く感じます。

 　
### IT業界に求められること

１．学習意欲が高いこと

　IT業界だけにいえることではないですがとても必要なことだと思います。仕事を始めてから覚えることがとても多く、学生時代よりも学ぶことの質と量のどちらも格段にレベルが上がるので自分自身が学ぶ姿勢出なければいけません。

　
２．積極的なコミュニケーション
　
　IT企業はパソコンに向かっていることがほとんどだと思っていましたが意外に他の社員とコミュニケーションをとる機会は少なくありません。インターンに参加した際にも感じましたが、会議やレビューなどで話すことがあるので積極的なコミュニケーションが必要不可欠です。

  　
３．セキュリティーへの意識
　IT企業は情報セキュリティーが特に厳しいようです。社員一人でもコンプライアンスに対する意識がないと大きな事態を巻き起こしてしまうこともあります。なので皆さん気を付けましょう。


   　
#### おわりに
　今回は就職活動への意識を高めることを考えこの記事を書いてみました。今の自分がすべきことが明確になりいい機会だったと思います。また、個人的に先輩方の就職活動報告書に目を通してみましたが、適正検査や面接に対して対策不足と語る人が多くみられました。先輩の助言をもとに頑張りたいと思います。
Android Studioでフォントを指定する方法

## 背景
カスタムフォントを使いたい。

## 設定方法
https://developer.android.com/jetpack/compose/text/fonts?hl=ja#set-font

指定フォントの準備→ダウンロードしておく
https://fonts.google.com/specimen/M+PLUS+Rounded+1c?subset=japanese&noto.script=Jpan

res/にfontフォルダを作成し、小文字にリネームした指定フォントを配置する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245300/1fdda5a7-030e-a84d-d92d-3e7ef1630605.png)

FontLoader objectを作成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245300/e811f063-4579-a46e-a765-87a6b97049fa.png)

[fontFamily](https://developer.android.com/jetpack/compose/text/fonts?hl=ja#set-font:~:text=%E7%A2%BA%E8%AA%8D%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82-,FontFamily%20%E3%82%92%E5%AE%9A%E7%BE%A9%E3%81%97%E3%81%BE%E3%81%99%E3%80%82,-//%20...%0A%C2%A0import)で呼び出す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245300/357f38b1-4f80-f713-16ea-e75d2acfbe7c.png)

## 適用前
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245300/253c15d5-26af-f03b-f3f9-836ba3bb0f5e.png)

## 適用後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245300/e0ae2d97-4008-0e47-6cf1-2e9a33f1e2db.png)
ABC332 E - Lucky bag 解説

# 概要
2023年12月10日(日)に開催された[ABC332](https://atcoder.jp/contests/abc332)の解説(といいつつ公式解説の補足がメイン)。

# 問題
https://atcoder.jp/contests/abc332/tasks/abc332_e
## 本文
* $N$個のグッズがあり、それぞれの重さは $W_i (1 \leq i \leq N)$である。
* これらのグッズを $D$個以内の袋に仕分けたい。「以内」なので、グッズが入っていない袋が存在してもよい。**但し、袋に入っていないグッズは存在してはならない。**
* 袋ごとのグッズの重さの合計を$x_1, x_2, \ldots ,x_D$としたとき、平均$\bar{x}=\frac{1}{D}\left(x_1+x_2+ \ldots +x_D\right)$, 分散$V=\frac{1}{D}\sum\limits_{i=1}^D \left(x_i - \bar{x} \right)^2$で定義される分散$V$の最小値を求めよ。
## 制約
* $2 \leq D \leq N \leq 15$
* $1 \leq W_i \leq 10^8$

# 解説
問題を一目見て、直感的にその時点で袋に入れているグッズの集合と何袋に分けたかの2次元で管理するbitDPができそうと感じる。制約の小ささや、どの順番でグッズを袋に入れても最終的に袋に入っているグッズの構成が同じなら結果が変化しないことが、そう考える根拠。
しかし、大きな問題がある。それは、単に分散を最小化しようとすると、各時点での各袋の重量の平均が変化するという点。分散の定義に出てくる項のうち、各袋に入っている重さの合計の二乗和は最小化できるが、平均の方が問題。
ここで、この問題の重要なポイントの一つは、$\bar{x}$が定数であること。なぜならば、必ずすべてのグッズが袋に入っていなければならないという問題の条件から、$\bar{x}=\frac{1}{D}\left(x_1+x_2+ \ldots +x_D\right) = \frac{1}{D}\left( W_1 + W_2 + \ldots + W_N \right)$ が成り立つため。
したがって、各時点での各袋のグッズの重さの合計から$\bar{x}$を差し引いたものの二乗和の最小値に対してbitDPを考えれば、最後に全グッズを$D$袋に分けたときのDPの値を$D$で割ることで、分散$V$が求まる。
ここまでわかれば話は簡単で、詳細は[公式解説](https://atcoder.jp/contests/abc332/editorial/7904)に譲るが、
$S$をこれまでに袋詰めしたグッズの添字の集合、$k$を$k$袋に分けるとして$DP[S][k]$をその時の各袋の重さの合計から$\bar{x}$を差し引いたものの二乗和の最小値として、bitDPを考えれば、$DP[all_S][D]$($all_S$はグッズ$N$個の添字からなる全体集合)を見ることで分散が計算できるようになる。

DPの初期化は、1袋に詰める場合、すなわち$DP[S][1]$($S$は$all_S$の任意の部分集合)から始める。この時、$S$のすべてのグッズを1袋に詰めるので計算は簡単で、$DP[S][1]=\left(\sum\limits_{s \in S} W_s-\bar{x}\right)^2$ となる。
ここからは$k=2,3,\ldots,D$と順に遷移するが、この際には$DP[S][k]=\min\limits_{T \subseteq S}(DP[S-T][k-1]+DP[T][1])$とすればOK。ここで$S-T$は差集合を意味する。
この遷移のお気持ちは、グッズの集合$S$を$k$袋に分けるときには、部分集合$T$を避けて$k-1$袋に分ける場合と、弾いた$T$を1袋に入れた場合を加算するという意味。これを部分集合全体にわたって計算し、最小値で更新する。
$k-2$袋と2袋に分ける場合などを考える必要はないのか？ともなるが、$k-2$袋に分けたときの最小値は$k-1$袋に分けるときへの遷移で既に反映されているので、$k-1$だけ考えておけば大丈夫。

最後に、数値誤差に気を付けつつ $DP[all_S][D]/D$にあたる値を出力すればよい。

## DPの初期値の設定はどうするの？
上記は公式解説にも記載されている内容。ただ、公式解説には、DPの初期値をどう設定すべきかが文面からはわかりづらい。具体的には$DP[0][1]$をどう設定すべきか？という点。これはすなわち0個のグッズを1袋に分けることを意味するが、この問題ではグッズの入っていない袋を許容するため、グッズの重さの和が0の袋が1つあると考え、$DP[0][1]=(0-\bar{x})^2$とすればよい。
冷静に考えればこれでしかないが、DPを用いて最小値を計算するような問題では、最初にDPの全体を巨大な数字で初期化してあげることも多いので、このあたりの初期値設定などは注意して行わねばならないと感じた。今回は、0個のグッズが$d$袋を占めているとき、残り$N$個のグッズを$D-d$袋に分配してあげる必要がある。つまり、グッズが入っていない袋にも意味があるので、適当な値で初期化するのは妥当ではないということになる。普段最小値を求めるDPで盤面を巨大な値で初期化していいのは、それが問題設定の中で実現不可能だから。何も入っていない袋の重さを0として扱う以上、それに適した値を設定する必要がある。
Gitと本番に乖離が発生していたのに気が付かなかった話

## 初めに

この記事は[本番環境などでやらかしちゃった人Advent Calendar 2023](https://qiita.com/advent-calendar/2023/yarakashi)の13日目の記事です。

https://qiita.com/advent-calendar/2023/yarakashi

年末も近づくにつれていろいろ作業が多くなり、うっかりやらかさないように自戒の念を込めて書きます。
ちょっと前職のビジネスの話にも触れるのでかなり内容はぼかしています。

## 背景

外注で開発して社内で管理していたシステムがあり、それを先輩の退職がきっかけで引き継ぐことになりました。

このシステムにはレポート機能が存在し、そのレポートに出力される計測値でユーザの料金が変動するといったビジネス特性も持っています。
この値は料金にかかわるので、レポートだけは正確に必ず出さなければならないと引継ぎで教えられました。

コード管理はGitLabで行われていたのですが、本番への適用はサーバーに直接ファイルを手動で置かないといけないという感じで、CI/CDとかはありませんでした。

## 事の発端

システムを一部改修するとの話がビジネス側から持ち上がり、いつものように外注先に変更内容を伝えて開発してもらい、その変更をサーバーに適用しました。
一応コードのレビューや検証も実施し、システムのコードをアップデートしました。
アップデートされた部分も確認し、よし！という感じで作業を終えました。

## レポートが出ない！

二週間後、営業から電話が飛んできました。

「レポートが出力されてないです！」

そんな馬鹿な。と思い確認をすると確かにレポートが出ていません。
毎日確認するようなシステムではないので発見が遅れました。

## 原因

原因は差し替えたファイルにありました。
ファイルを差し替える際に一応日付を入れてバックアップを取ってあったので差分を確認すると、外注先に依頼していた変更点以外にも変更点が。

先輩がコードに手を加えて、GitLabにアップしてなかったんですね…

しかも超重要なレポートの部分だけ。

確かにビジネスロジック部分だから外注はあれだったのかな…
無邪気にdiff取らないで適用した自分も悪いですが、さすがにこれは…となったのを覚えています。

## その後

レポート自体はログ等から生成ができたので、何とかなりました。（かなり大変でしたが。）
何とか利用料の計算の日には間に合ったので安堵したのを覚えています。

## 反省点&今に活きていること

### 変更を手動で適用する際には必ずDiffを取ってからやる。

これは当たり前かもしれないですが、変更点がそこしかないかはちゃんと確認すべきでした。

GitLabから自動で本番デプロイが組まれていない時点で本番とGitでの乖離が発生している可能性が高いと今では感じています。

### 自動でデプロイが組める場合は絶対に組む

今回はあとから引き継いだのでしょうがないのですが、今は新しく何か開発をする際には絶対に自動でデプロイをするようにしています。

## まとめ

この事件はコードの管理体制とかいろいろありますが、CI/CDがちゃんと組まれて自動でテストされ、自動でデプロイがされていれば起こらなかった事故だなと思っています。

今年の年末にもリリースがあり、一部手作業でやらなければならない作業が実はあったりするので、この事件を常に頭の片隅に置きながら、良い年明けを迎えたいなと思います。
Cisco WiFi-AP 802.1x 認証 の 設定 と 簡易テスト

Windows の NPS Server と連携して、RADIUS で、802.1x 認証をさせたときの Cisco AP側の設定内容です。
あとで、NPS側の設定を記事化するので、そこから 本ページへリンクする予定です。

検証に使用した機器
Cisco AIR-AP1832I-Q-K9

# 802.1x 認証機器の設定
1. WiFi AP の設定画面に接続
https://10.16.47.240
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/961f5270-0b9a-a6e3-d510-5702a0cb0418.png)
　<br>
1. ログイン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/3b1b345c-1133-e427-cfb1-8c1ccc3d3ef9.png)
　<br>
1. RADIUSサーバー (NPSサーバー) の IPアドレスと、RADIUSシークレットを入力
※「共有秘密鍵」が RADIUSシークレット の事を示しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/1f5f4b9a-7657-f225-6d9e-086f1cca8e1b.png)

# 簡易テスト
1. WiFi機器側のテスト機能が活用できます。
この場合、認証エラーになります。
ここでのエラーメッセージは、あまり気にしないでください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/d283281e-bd68-5f42-2e61-9c5c20d708b9.png)
　<br>
1. NPS Server の イベントログには、以下のように出力されます。
正常なユーザーでは認証され、 NG なユーザー では弾かれることを確認してください。
（認証が通った場合）
「ユーザーが、一致するネットワークポリシーで有効になっていない認証方法を使用しようとしました。」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/25491a11-2d1a-be08-67fb-b11d22aa6273.png)

（存在するユーザーで、パスワードを間違えた場合 or 存在しないユーザー）
ユーザー資格情報の不一致のため、認証に失敗しました。入力したユーザー名が既存のユーザーアカウントにマップされていないか、パスワードが間違っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/d12b2429-4d79-b867-4a81-92ab059bfbff.png)

ひとまず、上記を参考に 正常なユーザーでは認証され、 NG なユーザーでは弾かれていることが確認できれば、RADIUS としての連携はちゃんと動いています。

# NPS サーバーから応答がない場合
以下のようなエラーがでます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1619637/75587d3b-0153-0ecd-a25e-95a5d0801db6.png)
この場合は、イベントログ側にも何もログが残りません。
WiFi-AP と、NPSサーバー間で、疎通さえ出来ない場合や、 NPS サーバー側の ファイアウォールで RADIUSプロトコル（UDP:1812) がブロックされている場合などが考えられます。
そのあたりを疑って、トラブルシューティングを実施してみましょう。
Next.js(App router)でContentfulのMarkdownをHTMLで出力する(Remark/Rehype)

年の瀬の迫る今日この頃、いかがお過ごしでしょうか。
モロ([@moro_is](https://twitter.com/moro_is))です。

トレンドに翻弄されて`WordPress->Nuxt(+WordPress REST API)->Gatsby(Contentful)`と反復横跳びがごとく無駄に移行し続けてきたブログを、そろそろ**Next.jsに移行したら今度こそ当面安泰では**、と目論むもなかなか時間が取れずすっかり放置してしまっていましたが、さすがにそろそろ着手しないといつまでも経っても中身を更新できません(**ガワが良い感じになっていないと中身も触る気になれないタイプ**)。

やることが山積みではあるのですが、ここでは少しでも進捗を稼ぐべく、Contentfulの「Text(Markdown)」をNext.js(App Router)でHTML出力するところをやりました。

# ContentfulのText(Markdown)とは

Content Model内のフィールドで使用できる「Text」の入力形式のひとつ「Markdown」のこと。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76653/21fd65ed-7465-ab23-3862-c10069688c9d.png)

どちらかというと「Rich text」のほうが主流なのかあまり情報が出てこない印象でした。

# Unified(Remark/Rehype)周りのライブラリをインストールする

```
yarn add unified remark-parse remark-rehype rehype-stringify
```

全然詳しくないのでほぼ下記の受け売りです。

https://qiita.com/sankentou/items/f8eadb5722f3b39bbbf8

# 良い感じに変換するUtilsを作る

``` uilts/markdown.ts
import { unified } from "unified";
import remarkParse from "remark-parse";
import remarkRehype from "remark-rehype";
import rehypeStringify from "rehype-stringify";

export const markdownToHtml = async (markdown: string): Promise<string> => {
  const result = await unified()
    .use(remarkParse)
    .use(remarkRehype)
    .use(rehypeStringify)
    .process(markdown);

  return String(result.value);
};
```

下記を参考にさせてもらっています。

https://zenn.dev/sandyman/articles/4d83443404fcc9

目次をはじめカスタマイズの幅はかなり広そうなので追々ちゃんとやる。

# app配下の記事ページで読み込む


``` app/[slug]/page.tsx
import { markdownToHtml } from "@/utils/markdown";

//(中略)

async function PostPage({ params }: PostPageProps) {
  const post = await fetchPost({
    slug: params.slug,
    preview: draftMode().isEnabled,
  });

  if (!post) {
    return notFound();
  }

  const content = post.content ? await markdownToHtml(post.content) : "";

  return (
    <main>
      <h1>{post.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: content }} />
    </main>
  );
}

//(後略)
```

以上です。

MarkdownをHTMLに変換するところさえできてしまえばもうできたも同然ですね。
年内に何とかしたい気持ちでいっぱいです。

良いお年を！
DNSってなに？

## DNSとは？
IPアドレスとドメイン名を紐付け、通信先の機器（サーバー）を見つけ出す仕組みのこと

## 前提知識

### IPアドレスとは？
こちらの記事がおすすめです

https://qiita.com/Naughty1029/items/cfc63591d014cc0ffd76

### ドメイン名
`https://www.google.com`の`www.google.com`の部分のこと

IPアドレスの`000.00.00.00`のような形式だと、人間は覚えることが困難なのでドメイン名を設定して利用しやすくしている。

IPアドレス=緯度経度（緯度: 35.685175 経度: 139.7528)
ドメイン名=インターネット上の住所（東京都千代田区皇居外苑１−１)
上記のように覚えるとわかりやすい

#### トップレベルドメイン(TLD)
`https://www.google.com`の`com`の部分のこと

#### セカンドレベルドメイン(2LD)
`https://www.google.com`の`google`の部分のこと

#### サードレベルドメイン(3LD)
`https://www.google.com`の`www`の部分のこと

## DNSについて詳しく

![authoritative-server.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206155/46f8bab0-74c1-2dbd-2e29-a183d14525e6.png)
> 引用：https://jprs.jp/glossary/index.php?ID=0145

### 権威サーバー（DNSコンテンツサーバ）
DNSは複数の権威DNSサーバーが階層的に接続されている
- ルートサーバー（トップレベルドメイン(TLD)）
    - セカンドレベルドメイン(2LD)
        - サードレベルドメイン(3LD)
            - ...

#### フルサービスリゾルバー（キャッシュDNSサーバー）
ユーザーがアクセスした各ドメインの権威DNSサーバーを再帰的に返す

トップレベルドメイン→セカンドレベルドメイン→サードレベルドメイン→... の順に検索され、ゾーンファイルにIPアドレスが保存されていればIPアドレスを　なければ次に検索が必要な権威サーバーを返す

:pencil: 大半の場合プロパイダが設置している

##### キャッシュ
一度検索されたドメインはキャッシュされる
DNSレコードのTTLで有効期限が設定されており、すでにキャッシュ情報があれば権威DNSサーバーへ検索は行わず、IPアドレスを返す

#### ゾーンファイル
ゾーン内のDNSレコードを保存したテキストファイル

#### DNSレコード
ドメインの種類やIPアドレスなどを設定しておけるレコード

| レコード種別 | 内容 |
|:-----------------:|:------------------:|
|A　|　ドメイン名とIPアドレス　を登録する|
|AAAA　|IPv6アドレス用のAレコード。　|
|CNAME　|Aレコードの別名を設定できる　エイリアスのような物　|
|NS　|サブドメインで問い合わせる時に使用する　ドメインのネームサーバを登録する　|
|PTR　|IPアドレスとドメイン名を登録する　|
|MX　|メールで使用する　@の後ろを登録する　|
| SOA |ゾーンファイルの中身|
デービー

[インターネット老人会の魔法書 Advent Calendar 2023](https://qiita.com/advent-calendar/2023/ancient-internet) の2日目の記事です。

# DB

【意味】 Databaseの略語
【発音記号】 díːbíː

----

「ディービー」が「イービー」と聞き間違われるのを防ぐためなのか、**古のエンジニアは「D」を「デー」と呼びます**。
**「Database」** は **「デービー」** です。
「12:00」を「ひとふたまるまる」と呼ぶようなものでしょうか。

この発音に慣れると、日本語を話せる外国人エンジニアと話す時に困ります。
いくら相手が日本語上手だとしても、「D」を「デー」と呼ぶ古の文化まで知っているとは限りません。

近年外国人エンジニアと一緒に仕事する人も多いと思うので、 素直にそのまま **「ディービー」** と読みましょう。
Databricksノートブックにおけるinputの活用

Databricksを使い続けて3年経って、Databricksノートブックで普通に`input`を使えることを初めて知りました。

https://www.python.jp/train/string/input.html

[Databricks SDK for Python](https://docs.databricks.com/ja/dev-tools/sdk-python.html)を使います。

```py
%pip install databricks-sdk --upgrade
dbutils.library.restartPython()
```

以下のように入力を受け付けたい場所で`input`を使います。ジョブを作成する際にパラメータを指定します。

```py
from databricks.sdk import WorkspaceClient
from databricks.sdk.service.jobs import Task, NotebookTask, Source

w = WorkspaceClient()

job_name            = input("ジョブの名称 (例 my-job): ")
description         = input("ジョブの説明文 (例 My job): ")
existing_cluster_id = input("ジョブを実行するワークスペースの既存クラスターID (例 1234-567890-ab123cd4): ")
notebook_path       = input("実行するノートブックのワークスペースパス (例 /Users/someone@example.com/my-notebook): ")
task_key            = input("ジョブのタスクに適用するキー(タスク名) (for example, my-key): ")

print("ジョブの作成を試みます。お待ちください...\n")

j = w.jobs.create(
  name = job_name,
  tasks = [
    Task(
      description = description,
      existing_cluster_id = existing_cluster_id,
      notebook_task = NotebookTask(
        base_parameters = {"n_estimators": 50},
        notebook_path = notebook_path,
        source = Source("WORKSPACE")
      ),
      task_key = task_key
    )
  ]
)

print(f"View the job at {w.config.host}/#job/{j.job_id}\n")
```

上のセルを実行すると入力ボックスが表示されます。値を入力してEnterを押します。
![Screenshot 2023-12-12 at 9.46.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/b33e110d-0c93-1498-4bb1-b2d933849e26.png)

順次入力していきます。
![Screenshot 2023-12-12 at 9.47.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/64d5ebd7-f5c8-9eca-2377-171a87c99d33.png)

全て入力するとジョブが作成されます。
![Screenshot 2023-12-12 at 9.48.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/665c29be-cedf-03b4-0535-0c8632bdbe71.png)

指定した内容でジョブが作成されました！
![Screenshot 2023-12-12 at 9.49.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/edd2c229-01ce-46e7-8ecf-f6072d05a8bb.png)

パラメータをクイックに変更して試行錯誤したい場合には有効ですね。って、もっと早く気づけという話ですが。

### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
Vancouverの気になる新機能をまとめてみた

Vancouverにバージョンアップしたので新機能をまとめてみました！
普段はITSMを使用しているのでそっち寄りの観点です。

# インシデントの要約

追加コメントや作業メモを見返すのが億劫な方にはうってつけの新機能

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629160/47c11eda-a516-059e-f4c8-8d228eea4880.png)

* インシデントレコードのバナーに要約が表示
* 作業メモに追加したり、要約自体を折りたたむことも可能
* フィードバックボタン:thumbsup_tone1:や要約のコピーも可能

:::note info
作業メモや追加コメントが少ないと出来ません。
ごちゃごちゃしたインシデントを要約してもらいましょう。
:::

# チャットの要約
長々したチャットの会話を要約してくれる日が来るなんて想像してなかったですね！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629160/1df4a845-19aa-9bcf-ce3d-aff0af3a8c20.png)


* 仮想エージェントチャットを要約
* エージェントに、リクエスタの仮想エージェントのチャット履歴の概要を提供して、エージェントは対話全体の概要を生成して保存

:::note info
条件
* 会話が終わったとき。

* エージェントがエージェント チャット/summarizeでクイック アクションを使用するとき。

* ユーザーが[Chat Summarization]を選択するか、 [Now Assist]パネルでsummarize chat[Ask Now Assist to]を入力したとき。

* インタラクションが仮想エージェントからライブ エージェントに転送され、会話の長さが少なくとも 6 行になるとき。
:::

 # 解決メモの生成
 正直、解決メモ記するの面倒だったので個人的に嬉しいです。。
 
 * インシデントの解決メモを自動的に更新
 * 問題を解決するために実行した手順の概要を提供することで、解決メモの品質を向上

<font color="Red">**インシデントの解決ボタンを選択すると自動的に解決メモにインシデントの解決内容が反映！** </font>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629160/5547d69f-2a9a-5b6e-d5af-8c2ed6cac31e.png)


 # Now Assist for Search
 色々とナレッジ記事を開いて探さなくても良い時代になるんですね。。


 * Now LLMを使用して、サービス ポータル、仮想エージェント、従業員センター、およびグローバル検索で見つかったナレッジ記事から実用的な Q&A Genius Result の回答を抽出

 * ユーザーが検索で質問を送信すると、AI Search はトップのナレッジ記事の結果を取得して要約
 
 * 要約された記事はユーザーの検索結果を拡張し、実用的な Q&A Genius Result 回答カードとして表示
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629160/11869472-996c-728c-0f8c-9dcd04c490fd.png)

 # Text to Code
夢の市民開発には不可欠な機能ですね。

* 開発者はプロンプトを入力して、テキストのコードおよびコード補完の提案を取得
* AI で生成されたコード提案を確認した後、開発者はその提案を承認または却下
* 承認すると、コードがスクリプトに追加され、レビューに基づいて必要な編集が可能
* 拒否すると、コードはスクリプトに追加されず、プロンプトを言い換えて新しいコード提案を生成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629160/1173a1d6-7777-15b4-2324-373cd975b2a6.png)

:::note warn
**今まで紹介した機能は全てNowAssistプラグインをインストールする必要があります**
:::

## さぁ、NowAssistをインストールしよう！
インストール方法については各自でご確認ください。
実際にNowAssistを使用された方はコメントで感想待ってます。
価格設定は以下になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629160/2a961f2b-f3a0-649f-45bd-8bbb2d5530c1.png)

:::note info
現在１$は136円(FXレート)ぐらいですが、来年は140円台になるかも。。
:::



## 参考
[製品ドキュメント](https://support.servicenow.com/now/en/pages/automation-store?id=ns_automation_store&catalog_sys_id=3747ae79db5d270037015e77dc96193a)
【初心者】Amazon Route53 でドメインを取得する

# 1. はじめに
- 結構AWSの仕事をしているが、自分でパブリックドメインを取得したことがなかった。
- Route53のルーティング設定を用いて負荷分散/冗長化を図るような仕事があり、検証環境作成のため初めてドメインを取得したため、今更ながら手順をまとめておく。

# 2. やったこと
- Route53で、パブリックドメインを申請・取得する。
- 適当なレコードを登録し、インターネットから名前解決できることを確認する。

# 3. 構成図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/e79efed2-2613-0dac-cd40-d86479917f43.png)



# 4. 手順

## 4.1 ドメインの登録

- Route53のトップ画面 -> 「開始する」 -> 「ドメインを登録」を選択する。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/335242fe-1ec7-2230-2df4-8c1584e428ea.png)

- 取得したいドメイン名候補を入力し、空きを確認する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/ca1d0cfc-4512-d515-214e-812009008d86.png)

- 希望のドメイン名(本記事内ではxxxxx.netとする)を選択し、料金を確認して「チェックアウトに進む」を選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/3b038b18-17aa-255a-b1ed-e49b24340113.png)

- 今回は検証用途のため、自動更新はオフとする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/100b25c9-e5ea-7773-78eb-1884c3a7db4a.png)

- 連絡先(氏名、住所、メールアドレス)を入力する。ここで入力した内容がwhoisで検索可能になるのを抑止するため、「xxxxx.netの連絡先のプライバシー保護をオンにする」をチェックする。「次へ」を押すと入力内容の確認画面が出るため、確認後に「送信」を選択して、登録申請処理を行う。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/cfedfce3-bc7f-ab0a-b24e-cc241a5482ce.png)

- 「ドメイン」-> 「リクエスト」で、新規申請したドメインが「進行中」になるのを確認する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/54d8194f-61df-6ba1-1ea0-4a55afd7bbe3.png)

- 登録したメールアドレスに確認メール(タイトル：Verify your email address for xxxxx.net.)が来るので、本文中の確認用リンクをクリックする。


- その後、「ドメイン」-> 「リクエスト」で、新規申請したドメインが「成功」になるのを確認する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/f835d105-e538-db38-db5a-07d0e2f56982.png)

- 登録したドメインでのパブリックホストゾーンが自動作成される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/e497fa52-7ed6-83bf-7142-d5bf83670177.png)

## 4.2 レコードの登録

- パブリックホストゾーンの画面にて、「レコードを作成」を選択する。あらかじめElastic IPをアタッチ済のインスタンスを用意しておき、そのElastic IPをAレコードとして登録する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/5e7a0263-5535-7e09-3451-64600ac53c16.png)


- ホストゾーンにAレコードが追加されたことを確認する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/99461de5-787b-0cb4-2a3b-7bdff12c6fdf.png)

## 4.3 動作確認

- インターネット経由で名前解決ができることを確認する。FQDNを用いてpingやsshが可能になる。

```
[ec2-user@ip-10-0-0-156 ~]$ dig mksamba-instance.xxxxx.net

; <<>> DiG 9.16.38-RH <<>> mksamba-instance.xxxxx.net
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28257
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;mksamba-instance.xxxxx.net.        IN      A

;; ANSWER SECTION:
mksamba-instance.xxxxx.net. 300 IN  A       xx.xx.xx.142

;; Query time: 70 msec
;; SERVER: 10.0.0.2#53(10.0.0.2)
;; WHEN: Mon Dec 11 14:50:11 UTC 2023
;; MSG SIZE  rcvd: 75
```

# 5. 所感 
- 自分で自由にできるドメインがあると楽しい！ ルーティングポリシーの検証などを深堀していきたい。
AI-102試験対策のまとめ「Text Analytics for healthコンテナの検証」

## はじめに
Azure AI Engineer Associate(AI-102)取得に向けた勉強でまとめた内容を本記事では投稿しています。
試験範囲の内容を私が勉強していく中で、
・忘れてしまっていた内容
・他の知識と絡めて理解した方が良い内容
・Microsoft Learnの読解に苦戦した内容
などをできるだけ分かりやすく簡潔にまとめることを意識しています。
Azureの勉強を一から始め、AI-102取得を目指している方の参考になれば幸いです。
※本記事の内容が必ず試験に出るわけではないこと、ご注意ください
※勉強しながら投稿しているため、追加で学んだことがあれば随時投稿内容を更新します。

## 試験対策のまとめ
### Text Analytics for healthコンテナの検証
* コンテナを使うことで、独自のインフラでText Analytics for health APIをホスト可能
* コンテナには、RESTベースのクエリ予測エンドポイントAPIが用意されている
* 次の各種の要求URLを使用して、コンテナが実行中であることを確認可能
    | 要求URL例 | 目的 |
    | --- | --- |
    | `http://localhost:5000` | コンテナにはホームページが用意されている |
    | `http://localhost:5000/ready` | ・GETで要求 <br>・コンテナがモデルに対するクエリを受け取る準備ができていることを確認 |
    | `http://localhost:5000/status` | ・GETで要求 <br>・コンテナ起動に使用されたAPIの有効性を確認 <br>・エンドポイントクエリを発生させない |
    | `http://licalhost:5000/swagger` | ・コードを一切記述せずに、設定をWebベースのHTMLフォームに入力したりクエリを実行可能 <br>・クエリから戻った後、HTTPヘッダーとHTTP本文の必要な形式を示すサンプルCURLコマンドが得られる |
※要求URL例の`http://localhost:5000`は使用するコンテナの外部IPアドレスと公開ポートを基に変更

* 参考
    - https://learn.microsoft.com/ja-jp/azure/ai-services/language-service/text-analytics-for-health/how-to/use-containers?tabs=language#validate-that-a-container-is-running

## 次の試験対策のまとめ
* **AI-102試験対策のまとめ「カスタムニューラル音声のトレーニングデータの種類」**

https://qiita.com/fsd-jume/items/f2c0a52c4d779daccc47

## 学習内容をまとめたページの一覧

https://qiita.com/fsd-jume/items/65aba5d5514e023fd66d
Datadogに乗り換え失敗し、NewRelicに戻ってきた話

## はじめに
本記事では、Datadogへの移行を試みたものの、課金体系の誤解からNewRelicに戻ることになった経緯を共有します。この経験が監視ツール選定に役立つことを期待しています。

## Datadogへの移行を決めた理由

### コストカットの目的
Datadogへの移行は主にコスト削減を目的としていました。Datadogの料金体系は使用量に応じたものであり、ユーザー数に基づく課金ではなかったため、私たちのプロダクトに適していると判断しました。NewRelicではAPMとエラー検知のみを利用していたため、Datadogへの移行はユーザー数の追加とコスト削減を可能にしました。また、多くのユーザーがDatadogを利用していることも、移行を決断する大きな要因でした。

## 課金体系の誤解

### Index Spanの誤解
Datadogのテスト期間中は問題がなかったものの、本格的な使用開始時にIndex Spanに関連する通信料が予想外に高いことが判明しました。これはログデータ量に基づく課金で、当初の理解が不十分だったため、予期せぬ高額な請求が発生しました。Datadogの営業との連携のもと、テスト期間中は月額のコミットメントフィーのみという理解で進めていましたが、実際は異なっていたことが残念でした。

結果として、Datadogを継続してもNewRelicと同等のコストがかかることが明らかになりました。Index Spanの検知率を変更することも考えましたが、それにより検知できるエラーが減るため断念しました。コスト削減を目指しましたが、モニタリング環境を悪化させるつもりはありませんでした。

## NewRelicへの回帰

### 課金体系のシンプルさ
NewRelicに戻ってきて、課金体系のシンプルさが改めて魅力的に感じられます。ユーザー数に基づく課金は割高に感じることもありますが、新機能の追加に伴う追加料金の心配がない点は大きなメリットです。特にSREチームを設ける場合、NewRelicは万能ツールとして非常に有用です。

### UIの好み
UIの見やすさもNewRelicの魅力の一つです。特にグラフ表示やダークモードの色合いはNewRelicの方が好きです。今年はWebコンソール画面の表示速度改善も大きく改善されて、軽快に動作するようになったと思っています。

### APMアクセスとNewRelic Logsの活用
NewRelicではAPMの閲覧にはユーザーの追加が必要ですが、NewRelic Logsとダッシュボードの活用により、無料ユーザーでも重要なエラー箇所を効果的に確認できます。これにより、効率的かつコスト効果の高いシステム監視が可能になりました。BigQueryの利用を減らすことでコスト削減も実現しましたし、ログの検索速度もNewRelic Logsの方が格段に早いです。

## 結論
DatadogとNewRelicの移行経験から、コストカットを目的とした移行は軽率な判断であり、余計なコストがかかってしまったと反省しています。移行するに際しても課金体系への理解は必要であり、公式ドキュメントやユーザーグループなど多方面から情報を仕入れる必要性を改めて感じています。

今は、NewRelicを使っている場合、わざわざ他のツールに移行するメリットは少ないと感じています。監視ツールそのものをコストカットすることは考えず、代わりにNewRelicを使って既存のインフラコスト（AWS、GCP）を下げることに取り組む方が建設的だと思っています。

*NewRelicだけではないですが、私のところでは円安効果により12~14%、インフラコスト増になりそうでしたが、逆に15~18%くらいのコストカットができました。このあたりもどこかで共有できればと思います。
useEffectが２回実行される

:::note alert
この記事の情報は間違っています！詳しくはコメントをご覧ください！
筆者のuseEffectの知見が深まり次第修正いたします
:::
# はじめに
Reactで天気予報APIを使おうと思って、useEffectで困った。

# 問題
useEffectを使ってAPI接続し、結果を表示するというプログラムで、２回データを取得していた。
![スクリーンショット 2023-12-12 093211.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582046/441d2d7e-f219-28fd-90f3-c85f1cde578b.png)
問題のソースコード
```
useEffect(() => {
        const access_weather = async () => {
            const response = await fetch(
                'https://api.openweathermap.org'
            )
            const body = await response.json()
            console.log(body)
        }
        access_weather()
    }, [])
```

# 解決方法
クリーンアップ関数を書く
useEffect内に書いた関数の下にreturnでアロー関数を書くだけ
```
useEffect(() => {
        const access_weather = async () => {
            const response = await fetch(
                'https://api.openweathermap.org'
            )
            const body = await response.json()
            console.log(body)
        }
        //↓↓↓↓↓↓↓↓↓↓↓↓
        return () => {
            access_weather()
        }
        //↑↑↑↑↑↑↑↑↑↑↑↑
    }, [])
```
![スクリーンショット 2023-12-12 092841.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582046/fef1f10c-61b1-2c8a-a686-508affee2937.png)
ちゃんと１回だけ取ってるね

# おわりに
なんかReact18の、StrictModeの追加機能によるものらしい。
strictModeは、主に開発時に用いられるもので、通常時より厳格にエラーチェックすることで潜在的なエラーを発見しやすくするモードなんだって。
開発環境時の話だから本番環境では１回しか呼ばれないのかな？
    
# 参考
https://qiita.com/yuuu9617/items/94a89fe9f43b61567a95

https://qiita.com/asahina820/items/665c55594cfd55e6f14a

https://kabeuchi.me/blogs/2023-01-21-001

https://zenn.dev/takeharu/scraps/d14cf9d4239ec4
Swiftのバージョン互換性（5.9.2 beta）

# 5.9.2 beataのバージョン互換性

- Xcode 15.1 に含まれる Swift のデフォルトバージョンである Swift 5.9.2 について説明
    - Xcode 15.1のビルドターゲット
        - 5.9.2
        - Swift 4.2
        - Swift 4
- Swift 4とSwift 4.2のコードをビルドするためにXcode 15.1を使用する場合
    - Swift 5.9.2の機能が利用可能
    - 5.9.2以降を使用するコードでのみ利用可能
        - 不透明な型を返す関数は、Swift 5.1 ランタイムを必要
        - try?式は、すでにオプショナルを返す式にオプショナリティの追加レベルを導入しません
        - 大きな整数リテラル初期化式は、正しい整数型であると推測
            - UInt64(0xffff_ffff_ffff) はオーバーフローするのではなく、正しい値に評価
- 同時実行
    - 5.9.2以降と対応する同時実行型を提供するSwift標準ライブラリのバージョンが必要
- Appleプラットフォームで設定するデプロイメントターゲット
    - iOS 13
    - macOS 10.15
    - tvOS 13
    - watchOS 6
- 複数のフレームワークに分割された大規模なプロジェクトがある場合
    - Swift 4から5.9.2に一度に1つのフレームワークにコードを移行できる
        - 5.9.2で書かれたターゲット
            - Swift 4.2またはSwift 4で書かれたターゲットに依存することが可能
            - 逆も同様

# 参考

- https://docs.swift.org/swift-book/documentation/the-swift-programming-language/compatibility/
importmap -> vite_rails への移行

## 参考

https://vite-ruby.netlify.app/guide/



## インストール

```rb
gem 'vite_rails'
``` 
をgemファイルに追加する。

```rb
bundle install
```
を実行して、インストール完了。

## セットアップ

```rb
bundle exec vite install
```
を実行すると、必要なファイルや変更を自動で行ってくれる

## importmap用コードの削除

これは手動で行う必要がある。


## CI

[公式ドキュメント](https://vite-ruby.netlify.app/guide/development.html#integration-tests-in-the-ci-%E2%9C%85)によると、テストを実行する前に

```bash
bin/rails assets:precompile
```

を実行することで、アセットを事前に利用可能な状態にできる。
なので、CIにこのステップを追加するだけで良い。

## デプロイ

```shell
RAILS_ENV=production bin/rails assets:precompile
```
をデプロイフローに追加すると

```rb
rails aborted!
ArgumentError: Missing `secret_key_base` for 'production' environment, set this string with `bin/rails credentials:edit` (ArgumentError)

        raise ArgumentError, "Missing `secret_key_base` for '#{Rails.env}' environment, set this string with `bin/rails credentials:edit`"
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/home/runner/work/pont/pont/config/environment.rb:7:in `<main>'
Tasks: TOP => environment
(See full trace by running task with --trace)
Error: Process completed with exit code 1.
```
みたいなエラーが出る。

RAILS_MASTER_KEY を環境変数として追加することで解決できた。
RAILS_MASTER_KEY には、master.keyの値を渡す。

```bash
RAILS_MASTER_KEY=xxxx RAILS_ENV=production bin/rails assets:precompile
```

ちなみに、

```bash
yarn install
RAILS_MASTER_KEY=xxxx RAILS_ENV=production bin/rails vite:build
```
でもok。
Swiftについて（5.9.2 beta）

# Swift

- ソフトウェアを書くための素晴らしい方法
    - 携帯電話
    - デスクトップ
    - サーバー
- 安全で、高速で、インタラクティブなプログラミング言語
- コンパイラ
    - パフォーマンスに最適化され、言語は開発に最適化
- 新しいプログラマーに優しい
    - クリプト言語のように表現力豊かで楽しい
    - 産業品質のプログラミング言語
- プレイグラウンド
    - コードを実験し、すぐに結果を見ることが可能
- 最新のプログラミング・パターンを採用
    - よくあるプログラミング・エラーの大部分を排除
        - 変数は使用前に必ず初期化
        - 配列の添字は、境界外エラーをチェック
        - 整数はオーバーフローをチェック
        - オプションは、nil 値が明示的に処理されることを保証
        - メモリは自動的に管理
        - エラーハンドリングにより、予期せぬ失敗からの回復を制御
- コンパイルされ、最新のハードウェアを最大限に活用するように最適化
- 構文と標準ライブラリ
    - 指導原則に基づいて設計
        - コードを書くための明白な方法
        - 最高のパフォーマンスを実行する必要
- 安全性と速度の組み合わせ
    - あらゆるもののための優れた選択肢
        - Hello, world!
        - オペレーティング・システム全体
- コードは書きやすく、読みやすく、保守しやすい
    - 複雑なアイデアを明確で簡潔な方法で表現
        - 強力な型推論
        - パターンマッチを現代的で軽量な構文

# 参考

- https://docs.swift.org/swift-book/documentation/the-swift-programming-language/aboutswift/
CursorでOpenAI API Keyを使う設定

# 1. OpenAI API Keyを作成
OpenAIのプラットフォームページを開き、ログイン

https://platform.openai.com/docs/overview

左のメニューでAPI keysをクリック

![スクリーンショット 2023-12-12 9.06.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/14b10d99-de8b-e7d8-2a77-e94966be08e7.png)

新しくkeyを作成

![スクリーンショット 2023-12-12 9.08.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/9334ce9e-c8b8-0d13-7ce6-2ca1e61a95fe.png)

任意の名前を入力
![スクリーンショット 2023-12-12 9.09.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/b7539ef6-e22e-d805-8032-d89109855444.png)

keyをコピー。
※一度しか表示されないため、再度コピーする際は、このkeyを削除して、再作成が必要。

![スクリーンショット 2023-12-12 9.10.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/c1b70224-d0a8-8f8a-aaf5-bfe1a116fd42.png)

# 2. OpenAI API Keyの課金設定
左のSettings/Billingをクリック

![スクリーンショット 2023-12-12 9.24.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/e006504f-bae1-b84b-b41a-1d2665981f73.png)

詳しくは以下のサイトで。

https://www.goatman.co.jp/media/chatgpt/openai-payment/

# 3. OpenAI API Keyを登録
Cursorアプリ内で、Command+Shift+Pを押し、
コマンドパレットで「Cursor: Open Settings」を入力し、設定モーダルを開く。

![スクリーンショット 2023-12-12 9.03.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/27b32384-7bdf-a843-9c26-89344acb7a6e.png)

OpenAI APIに自分のキーを入力

![スクリーンショット 2023-12-12 9.03.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/6c643537-130f-e13e-74b9-a10c1276ba6e.png)

その後、以下のように、Using Keyとなれば、OK。
※入力したKeyでエラーとなる場合は、Keyを再作成することで、認証が通ることがある。
クーロン

[インターネット老人会の魔法書 Advent Calendar 2023](https://qiita.com/advent-calendar/2023/ancient-internet) の1日目の記事です。

# cron

【意味・対訳】 UNIXのデーモンの一つで、指定の日時に特定のプログラムを起動するもの。
【発音記号】 krɑn(米国英語), krɑ:n(英国英語)

[weblio](https://ejje.weblio.jp/content/cron)より引用

----

発音記号見てもらえればわかりますが、英語的には**クラン**または**クラーン**が近い発音。
日本語的読み方でも**クロン**か**クローン**が近い発音で、近年日本語で言うならこちらの方が一般的だと思います。

しかしながら、古のエンジニアはこれを**クーロン**と呼ぶ人が多いです。
私も先輩から最初そう教わりました。
が、**cron**のスペルを見ても **"クー"** で伸びるのは変だと思います。

**クロン**という言葉に馴染みがなかったせいでしょうか。
**九龍城（くーろんじょう）** に引っ張られたのかもしれません。

はっきり否定すると老人のプライドを傷つけてしまうので、

老人「**クーロン**の設定確認しておいて」
若手「はい！**クロン**の設定確認しておきます！」

とやんわり言い換えておきましょう。
IPアドレス付与

vi /etc/sysconfig/network-scripts/ifcfg-eth0

DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.1.100
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
DNS1=8.8.8.8
DNS2=8.8.4.4

再起動


CentOS 6では、iptablesがファイアウォールの管理に使用されています。ファイアウォールを完全に無効にするには、以下の手順を実行してください：

1. **iptablesの停止:**
   ```bash
   sudo service iptables stop
   ```

2. **iptablesの無効化（再起動時にも無効にする場合）:**
   ```bash
   sudo chkconfig iptables off
   ```

3. **ip6tables（IPv6ファイアウォール）が有効な場合は、同様に停止および無効化を行います:**
   ```bash
   sudo service ip6tables stop
   sudo chkconfig ip6tables off
   ```

4. **再起動:**
   ```bash
   sudo reboot
   ```

これにより、iptablesサービスが停止され、無効化され、再起動後も無効のままとなります。ただし、ファイアウォールが無効になるため、セキュリティ上のリスクが高まることに留意してください。必要に応じて、ファイアウォールの設定を適切に構成することが推奨されます。
CloudFront + Cognito認証(cognito-at-edge)で、index.htmlを追加したい

## 概要

- CloudFrontでCognito認証したい場合は、Lambda@Edgeを使って[cognito-at-edge](https://github.com/awslabs/cognito-at-edge)を扱った記事は多い。
- 一方、CloudFrontでファイル名を含まないURLをリクエストした際にindex.htmlを追加する方法としてはCloudFront Functionsを使ったサンプルの記事が多い。([公式でも記載](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/example-function-add-index.html)されている)
- 問題点はcognito-at-edgeと同時に使いたい場合にビューワーリクエストで指定することになるため、どちらか片方しか設定できないこと。
  - オリジンリクエストでCloudFront Functionsは指定できない。
  - オリジンリクエストでLambda@Edgeは可能だが、認証系がキャッシュされてしまう？未確認だが期待する動きをしないと思われる。
- この記事では、どちらの機能も実装したLambda@Edge関数を作成し解決方法を紹介する。
- なお、Lambda@EdgeやCloudFront、Cognitoの基本的な設定方法については割愛する。

## 結論

- 以下のようにLambda@Edge関数を作成して、ビューワーリクエストで指定すれば実現できる。

```js
const { Authenticator } = require('cognito-at-edge')

const authenticator = new Authenticator({
  region: <<region>>,
  userPoolId: <<pool_id>>,
  userPoolAppId: <<app_id>>,
  userPoolDomain: <<pool_domain>>,
})

export const handler = async (event) => {
  const result = await authenticator.handle(event)
  if ('status' in result) {
    return result
  }

  var uri = result.uri
  if (uri.endsWith('/')) {
    uri += 'index.html'
  }
  else if (!uri.includes('.')) {
    uri += '/index.html'
  }
  result.uri = uri
  return result
}
```

### 解説

- まず、cognito-at-edgeの認証処理を行うために、`Authenticator`をインスタンス化する。
- その後、`Authenticator`の`handle`メソッドを呼び出すことで、認証処理を行う。
- `handle`メソッドの戻り値は、認証成功時はリクエストオブジェクトを、失敗時は画面遷移のステータスコードを持ったレスポンスオブジェクトを返す。
- そのため、戻り値に`status`プロパティがあるかどうかで、認証成功かどうかを判定できる。
- そのあとは、リクエストオブジェクトの`uri`プロパティを参照し、`/`で終わっている場合は`index.html`を追加し、拡張子がない場合は`/index.html`を追加する。

## 今後の検討課題

- ユーザ単位にページの参照可否を制御したいと思った場合に、上記Lambda@Edge関数に機能を実装する必要があるが、cognito-at-edgeは認証情報までは返してくれない。
  - cognito-at-edgeに要望を出すか、必要な機能を移植するか。（それなりにプロジェクト自体は活動されているようだが、放置されているプルリクが気になる。）
DataStreamとオンプレDBを閉域網接続する

DataStreamを使ってCloud InterconnectやVPN経由で接続されてオンプレ環境のDBかたデータを読み出す場合、以下のドキュメントで説明されているように、Reverse Proxyで通信を中継させる必要があります。
Compute Engineを使ってVMを設置して、その中にiptablesで通信を中継させる例が載っています。
しかし、VMを適切に冗長構成することを考えると、この構成はやや面倒です。

https://cloud.google.com/datastream/docs/private-connectivity#reverse-proxy

そのため、以下のような構成で接続することで、VMなしで閉域網接続を実現してみます。
DataStreamはGoogle Managed VPCに配置されており、オンプレ環境と直接繋がってはいません。
そのため、中間にあるVPCが「いい感じに」経路情報を伝搬させる必要があるので、その設定を行っていきます。

![名称未設定ファイル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74551/faa756c8-9ba7-6e58-6d6d-b550fd6adc19.png)

まずは、図の右側のExchange Custom Routesから設定していきます。

```terraform
resource "google_datastream_private_connection" "datastream_private_connection" {
  display_name          = "datastream-private-connection"
  location              = "us-central1" # 各自の環境に合わせる
  private_connection_id = "datastream-private-connection"

  vpc_peering_config {
    vpc    = "DataStreamと接続する（図中で真ん中の)VPCを指定"
    subnet = "<DataStreamに割り当てるCIDR>"
  }
}
```

この設定を適用すると、DataStreamのPrivate Connectionが作成され、VPCとの間でVPC Peering接続がなされます。

VPC Peeringの管理画面で該当のPeeringを選択して、Export custom routesをONになるように設定を変更します。

![スクリーンショット_2023-12-12_8_53_17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74551/2a76298a-6f45-1103-c76e-cc5353db8c94.png)

![スクリーンショット_2023-12-12_8_55_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74551/841d6966-455d-af67-738e-e4313bc4fcf7.png)

この設定によって、オンプレ環境のCIDR情報がDataStreamの動いているGoogle Managed VPCに伝わります。

実はまだこの設定だけではVPCがcustom routesを一方的に送っているだけであり、Google Managed VPCがそのcustom routesを受け取るかどうかはわかりません。
そのため、本来ならばGoogle Managed VPC側のPeering設定でImport custom routesをONにする必要があります。
実際にCustomer ManagedなVPC同士の接続では明示的なImportは必要です。
しかし、Google Managed VPCでは作成時にデフォルトでONになっているような挙動をしているので、ImportをONする必要はありません。

次に、図の左側のCustom Route Advertisementも設定します。
Dedicated Interconnectに紐づいているCloud RouterのBGP設定を変更します。
Cloud Routerにはカスタム経路広告機能があるので、この機能を使ってVPC外のCIDRをオンプレ側に広告します。

https://cloud.google.com/network-connectivity/docs/router/how-to/advertising-overview

```terraform
resource "google_compute_router" "router_main" {
  name    = "router_main"
  network = "VPCを指定"
  region = local.interconnect_region
  
  bgp {
    asn               = "GCPのASNを指定"
    advertise_mode    = "CUSTOM"
    advertised_groups = ["ALL_SUBNETS"]

    advertised_ip_ranges {
      range = "DataStreamのCIDRを指定"
    }
  }
}
```

これによって、オンプレ・Google Managed VPCの双方にルート情報が渡されることになり、IP到達性が達成できました。
あとはFirewallの開放やデータベースのユーザー作成などを行えば、DataStreamからDBのCDC情報を読み取ることができます。

なお、この記事を書くにあたって、以下の記事を大いに参考にさせていただきました。この場を借りてお礼申し上げます。

https://medium.com/google-cloud-jp/gcp-%E3%81%AE%E7%B4%B0%E3%81%8B%E3%81%99%E3%81%8E%E3%81%A6%E4%BC%9D%E3%82%8F%E3%82%89%E3%81%AA%E3%81%84%E3%83%8F%E3%82%A4%E3%83%96%E3%83%AA%E3%83%83%E3%83%89%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AD%E3%83%B3%E3%82%B0-14ed12ebe84d
TVTest の BS チャンネルを設定する


「TVTest + PT2 を設定」
https://qiita.com/nanbuwks/items/4f11fe6363d3db53a742
の記事中、BSチャンネルを設定するときに以下のような問題が発生していました。

> なお、ファイルを設定しても反映しなかったり、チャンネルスキャンのボタンがグレーアウトしたりします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/efe73072-725d-881e-343b-e4cd1cc29512.png)
その場合は、ファイルが不良？


とありました。その後、ボタンは押せるようになりましたが

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/80745cf6-69bc-1dd1-f619-95d0bf15cf41.png)

BSでチャンネルスキャンが途中で止まってしまいます。
そもそも、チャンネル12/13の　13 というのも数が少ないです。

その後、チャンネルスキャンがうまくいった場合でも表示されているチャンネルが少ないです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/3384d563-c34b-5847-1332-823fbb573c4a.png)

# 環境

- MS-Windows 10 Home 22H2
- TVTest TVTest-0.10.0-230927 64bit版

https://qiita.com/nanbuwks/items/4f11fe6363d3db53a742
で設定したものです
# 予備知識

BS　チャンネル設定にかかわるファイルは2つあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/bcfe4f65-d8bb-fc08-92c7-898535181662.png)

- BonDriver_PT-S.ch2
  - TVTest  のチャンネルスキャンで作られるファイル 
- BonDriver_PT-S.ChSet.txt
  - 放送波情報のファイル。TVTest のチャンネルスキャンの前に用意しておかなければならない

# 原因

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/1dfcd5a9-cb5c-0fb5-d524-63e569964eaf.png)

これは、BonDriver_PT-S.ChSet.txtに問題があるため発生します。

同梱されているファイルのままだと旧いので、ファイルを入れ替えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a0d84ab7-5dd7-6473-b1c0-c8842cf8fd6b.png)

# GetPTBonChanel 
先の記事「TVTest + PT2 を設定」では出来合いのファイルに入れ替えましたが、今回は↓こちらを利用しました。


http://www.charatsoft.com/software/bondriver_pt/index.html

TVTestは放送波再編があるたび設定ファイルをそれにあわせなければなりません。市販の家電などはそれを自動でやります。それは電波に放送波情報が載っていてそれから必要な設定を更新しているからです。
この GetPTBonChanel  は同様に電波からチャンネル情報ファイルを生成します。

 GetPTBonChanel を起動すると以下の画面になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/9b7ea396-276d-62ed-37af-06a2cb0a621a.png)

チェックを入れて、「スキャン開始」を押し、できたファイルを保管します。

# TVTest 側の作業

チャンネルスキャンをすると、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/5370ca6c-7151-aabd-5d64-8503d031c48a.png)

「BSよしもと」なども出てくるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/d0af8f7b-58b4-be11-e624-29c050608ec3.png)


出るようになりました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/9b794ec7-685a-a8b1-72c6-7661bf16ef68.png)

同じようにして、チャンネルリストに番組表が出る場合もありますが、違いはどこに？調査中です。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/1f6ead1e-bc78-2e21-ccc1-fd021e7bdbff.png)
軽深演習 #12 孫氏の兵法

### 軽深（かるしん　なんちゃって圏論） Advent Calendar 2023 12日目の記事です。

演習形式をとっているので、ぜひ　回答を試みてください。


### 前提知識　孫子の兵法

圏は、射つまり矢印が重要です。私達は、普段よく矢印をつかっています。前回の軽深演習で、射は順番としました。山本五十六の名言は確かに順番と見えます。
```mermaid
flowchart LR
A[やってみせ]-->B[言って聞かせて]-->C[ほめてやらねば]
```
有名な孫氏の兵法。敵を知って己を知るはどうでしょうか、敵と己が並列のようにも見えます。

**敵を知り、己を知れば危うからず。**
```mermaid
flowchart LR
A[敵を知り]-->C[危うからず]
B[己を知れば]-->C[危うからず]
```


さて、演習　**孫子の兵法**　も順番にかんするものです。

### 演習　有名な孫氏の兵法の【敵を知り、己を知れば危うからず】の敵と己には、順番があるのでしょうか？
圏論って面白いんじゃないかとなんとなく思えるようになりませんか？
山本五十六と孫氏の兵法の２つ名言を矢印だけで比較しています。
自衛官からエンジニアへ Elixirから始める Web開発シリーズまとめ

東京にいるけどfukuokaexのYOSUKEです。

普段は 合同会社TheWaggle で教材開発・システム開発・研修講師などマルチに活動してます。
自衛官からエンジニアシリーズのリンク集です。随時更新していきます。


## 自衛官からエンジニアへ Elixirから始める Web開発シリーズ

https://qiita.com/Yoosuke/items/7a80006631c43b27e4ff

https://qiita.com/Yoosuke/items/dd1987c655c452c3f92a

https://qiita.com/Yoosuke/items/da6553c76b0677db90fa

https://qiita.com/Yoosuke/items/6f034b9a0e7d6c0a0b75

https://qiita.com/Yoosuke/items/9d846f9a87e392084633

https://qiita.com/Yoosuke/items/5e9614741b183dad692f

https://qiita.com/Yoosuke/items/546a3e956b571a0c1e12

https://qiita.com/Yoosuke/items/70626c7eb21ea82bf30a

https://qiita.com/Yoosuke/items/f778dbf46a832e25aa8c

https://qiita.com/Yoosuke/items/8863f0e3e4791d04db67

https://qiita.com/Yoosuke/items/eaf70c06132702ccca7a

https://qiita.com/Yoosuke/items/0c6863d74f78016da99c

https://qiita.com/Yoosuke/items/4f128cb7ef5c8ac6d693

https://qiita.com/Yoosuke/items/aca3a1a6c924df94c5b9

https://qiita.com/Yoosuke/items/e36a5ba2f81b6cd79401

https://qiita.com/Yoosuke/items/fe0d0165433f752dc7b8

https://qiita.com/Yoosuke/items/3cd271133a0828a202ed

https://qiita.com/Yoosuke/items/8fa7fd5a96185cce4b13

https://qiita.com/Yoosuke/items/8de14fc1baabcb866814

https://qiita.com/Yoosuke/items/98bf4f4886d3902a0a86

https://qiita.com/Yoosuke/items/2dbb761a11ba8cec1342

https://qiita.com/Yoosuke/items/0b7141a39b33022d8053

https://qiita.com/Yoosuke/items/206fe985b50705a801ba

https://qiita.com/Yoosuke/items/e08b1fbe0d48b497476f

https://qiita.com/Yoosuke/items/382181a82e01cb532089

https://qiita.com/Yoosuke/items/3b353fa2bda301678b7b

## 裏コラム

https://qiita.com/Yoosuke/items/1d0debf55cf0cae214b1

https://qiita.com/Yoosuke/items/1e84591c7917858f4f71
スロークエリを大量発生させてサービスを落とした話

[本番環境などでやらかしちゃった人 Advent Calendar 2023](https://qiita.com/advent-calendar/2023/yarakashi)に参加しようかと思ったのですが、あちらはどちらかというとインフラ回りのトラブルのお話が中心。この話は開発よりのトラブルなのでちょっと違うかなぁということで参加は取りやめて、普通の記事として投稿します。

このトラブルは過去の職場での体験なので、現在はソースコードやドキュメントが参照できません。そのため記憶に頼って書いています。また、フェイクもあちこち入れていますので、全体として辻褄合わない話になっているかもしれません。一応、トラブルの本筋のところは外さないようには書いているつもりではありますが。その点、ご認識の上で読んでいただけると助かります。

## どういうサービスでどういう改修か

とあるユーザ投稿型のサービスで、ユニークユーザ数は100万人程度とそこそこの規模です。このサービスに以前から「お勧め投稿」という機能があったのですが、そちらの機能強化の改修でした。

今までは単純に各投稿から閲覧数が多いものをお勧めしていたのですが、もっとお勧め精度をあげようということで、いいね数もお勧めスコアに算入することになりました。また、これまでは全期間をスコア対象にしていたのですが、直近の閲覧やいいねのみに絞るようにもしました。

お勧め投稿はサービス内で単一ではなく、複数の要素の組み合わせごとに存在します。例えて言うなら「関東地方在住でアニメ好きなユーザ用のお勧め」とか「関西地方在住でITに興味があるユーザ向けのお勧め」という感じですね。要素の組み合わせは数万種程度存在します。またお勧め投稿は要素の組み合わせごとに100件程度の投稿がリストアップされていて、トータルで数百万件の投稿がお勧めされる構成になっています。

## 惨劇の状況

機能改修が完了し、テストもパス。本番環境にリリースして、意気揚々とお勧め投稿更新バッチを実行したところ、しばらくして監視アラートがあがってきました。

監視ダッシュボードを確認したところ、DB の負荷があり得ないくらいあがっていました。そして無数の 500 エラーの発生。DB から反応が返ってこないため、一部の静的ページや DB 参照しないページを除いた、ほぼ全ページがエラーとなってしまい、事実上サービス全体がダウンしてしまいました。

慌てて切り戻しを行ったところ、徐々に DB 負荷が下がり、それに伴ってページ表示も復活。10分後くらいには監視閾値も下回り、サービスは復旧しました。

## 惨劇はなぜ起こってしまったのか

一言でいうと、お勧め投稿リストを作るためのクエリが重すぎてスロークエリになってしまったためでした。同時に数万のスロークエリが DB に投げられたため、 DB が事実上ダウンしてしまったのです。

実はお勧め投稿リスト自体は DB には持っておらず、キャッシュ(memcached)に格納していました。キャッシュにデータがある場合にはそのデータを使って表示し、キャッシュの期限が切れたあとの初回アクセス時に DB にアクセスしてお勧め投稿リストを更新するという仕組みです。当然にお勧めリストの更新タイミングがバラバラになってしまいますが、それは問題ないという仕様でした。

お勧めリスト更新バッチは、このキャッシュを一気にクリアするものです。普段は散発的に更新されていたお勧めリストが一気に更新され、その全てがスロークエリになったために DB に過負荷を与えてしまったという仕組みです。

## 惨劇を起こさないためにできること

負荷試験をしっかり行うということに尽きます。が、これは言い訳になってしまうのですが、当時は本番相当の負荷試験を行う環境がありませんでした。

今回の障害は本番環境のデータ量とアクセス量が重なり合って発生したものです。しかし検証環境の DB にはスカスカのデータしか入っていなくて、まともな負荷検証が出来る状態ではありませんでした。

本番のデータコピーを検証環境にも適用しようという話は以前から出ていたのですが、ずっと先送りになってしまっていました。このあたり、開発チームとインフラチームが完全に別部署に分かれていて風通しがイマイチよくなかったというのも間接的な要因としてあげられるかもしれません。

繰り返しになりますが、検証環境が無かったというのは所詮は言い訳でして、本番と全く同じでなくても、少なくともデータ量だけでも本番相当になる疑似データを検証環境に用意して負荷検証を行うべきでした。
模倣学習~概要からLLMの話題まで~

こんにちは、NECの入江です。[NEC デジタルテクノロジー開発研究所 Advent Calendar 2023](https://qiita.com/advent-calendar/2023/nec-dt-labs)の14日目として本記事を執筆しております。

私は普段、模倣学習を用いた技術や、最近はLLM関連の応用研究などを行っています。よって今回は、模倣学習って何だ？という所から、代表手法や直近の話題について、今回は数式を省いて簡単にご紹介していこうと思います。

# 模倣学習とは？
模倣学習とは、簡単に言うと強化学習と同じ問題をお手本の行動を用いて学習する手法です。

強化学習は、環境の中で自らが探索を行い失敗と成功を繰り返しながら最適な行動を学習します。

強化学習といえばロボットやゲームなどにおいて利用されるイメージが強いと思います。というのも、強化学習では何度も失敗を繰り返しながらモデルを学習させる必要があるため、仮想的に構築したシミュレーション環境のような何度も失敗が許されるような環境を用意しなくてはなりません。

そのため、医療の現場において患者の状態に合わせた最適な治療の行動方策を強化学習で学習できないか？と考えたとしても、当然ですが探索のために治療を失敗するわけにはいきません。このように現実的な場面では、失敗が許されないことが多いです。

そこで、お手本となる行動を与えて学習させる手法が模倣学習になります。模倣学習は問題設定は強化学習と同じになりますが、探索して報酬が最大となる行動を学習する強化学習のやり方とは異なり、教師あり学習のように学習します。

![RLIL.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3615191/01637fb1-2800-9ab0-f41b-cbdcbb09f552.png)

シンプルな学習のやり方としては、お手本中にある状態を入力、行動を出力として教師あり学習で学習するBehavior Cloning(BC)があります。しかしながら、一般的に模倣学習で取り組むタスクは、多数の状態数に対して限られたお手本データ数で学習しなければならないため、BCでは学習したデータ分布外の状態に対して行動の予測が難しい、分布シフトと呼ばれる問題に苦しむことが多いです。

# 代表手法 - GAIL
模倣学習の手法の中でも代表的な手法としては、GAIL(Generative Adversarial Imitation Learning)が挙げられます。GAILは2016年のNIPSで発表された論文手法ですが、執筆時点でもよくベンチマークで比較されるような代表手法になります。
[Generative Adversarial Imitation Learning](https://arxiv.org/abs/1606.03476), 2016

GAILはGAN(Generative Adversarial Network)のように、お手本となる成功事例データを模倣して行動を生成するGeneratorと、成功実事例データと生成例データを見分けるDiscriminatorを敵対的に学習させます。すなわち、GeneratorはDiscriminatorを欺くようなお手本そっくりのデータを生成するように学習することで、高精度な模倣データを作り出すことができます。

![gail.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3615191/80f10a58-82c7-f2d1-1138-7be289b540a3.png)

# NEC技術
私たちNECではこのGAILの手法をベースとして、模倣させたくない失敗行動例のデータからも反面教師的に学習することで、成功事例の行動をより精度よく模倣する手法を開発しました。
[AIで熟練者の暗黙知を形式知へ行動模倣学習技術](https://jpn.nec.com/rd/technologies/202202/index.html)

GAILのモデルアーキテクチャをベースに、成功事例か失敗事例かを見分けるClassifierを追加導入しています。

![acil.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3615191/b997e53a-924d-83ad-7126-92855645736e.png)

Generatorは成功事例に近い行動を生成するようにClassifierと協調的に学習することから、敵対的に学習するDiscriminatorと合わせて敵対的協調模倣学習と呼んでいます。私たちはこの敵対的協調模倣学習の技術を用いて、医療の分野などで実証検証を行っています。

# 最近の話題 - 模倣学習×LLM
最後に直近話題として、著しく発展しているLLM×模倣学習の論文 について少し紹介したいと思います。

[Prompt, Plan, Perform: LLM-based Humanoid Control via Quantized Imitation Learning](https://arxiv.org/abs/2309.11359), 2023


動作を指示するコマンドを入力し、そのコマンドの指示通りにロボットが動作するようなタスクを模倣学習によって実現するのが目的です。教師データにはロボットの動作と、ラベルとしてその動作を指示するコマンドテキストが用いられます。コマンドテキストをプロンプトとしてLLMに入力し、動作の指示をプランニングさせることで、Zero-shot学習が可能になります。

![ppp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3615191/f4948977-c23d-bba9-48ba-67fc893237df.png)

図のように、模倣学習には上記のGAILのフレームワークを採用しています。
学習の流れとしては、まずコマンドテキストをエンコードしていき、スキルと呼ばれる潜在変数zに変換します。このzをGeneratorとみなせるMotion Poilicyに入力し、ロボットの動作を生成します。そして、zを入力した時(=コマンドを前提した時)の生成した動作と正しい動作をdiscriminatorに見分けさせ、GAILと同様に敵対的に学習していきます。実際には、Motion Policyは上記のdiscriminatorに見分けられなかったことによる報酬＋生成動作とお手本動作のベクトルの一致度に応じた報酬によって学習します。

# まとめ
本稿では、代表手法であるGAILを中心に、模倣学習の紹介をさせていただきました。

AIの分野においてLLM絡みの研究が急加速していますが、模倣学習もLLMと組み合わせた手法が今後増えていきそうです。

私たちも新しい模倣学習技術を応用し、より高性能で幅広い適応が可能な熟練者行動の模倣AIの開発を進めていこうと思います。
行動モデル早見表【エンジニアデザイン心理学】



「なぜ、その行動を始めたのか？」を説明するためのモデルが行動モデルである。

行動モデルは5つの要素から構成されており、これらがすべてそろわなければ行動は起きない。

この行動モデルを**CREATEアクションファネル** と呼んでいる。


- キュー `Cue` : 行動をとるためには、まずはその衝動が頭をよぎらなければならない。行動を思いつく要因は二つある。
    - 外部のキュー : 環境要因のこと。友人から電話を受け取り、ランニングに向かうなどがよい例だ。
        - ユーザーの環境の中にプロダクトを置く
        - 無視されないように、毎回ちょっと違うキューを置く
        - ユーザーのすでにやっているルーティーンから想像できるようにする
        - NG) 注意を奪い合うことで集中力が分散してしまうようなキューは避けること。
        - NG) 朝の受信トレイは渋滞してしまっているため、重要な通知でも見逃してしまう。
    - 内部のキュー : 内部の要因のこと。おなかがすいたから焼きおにぎりを食べるために行動を起こす等。
- 直観的な反応 `Reaction` : その行動における第一印象が不快である場合、行動をとらない可能性が高い
    - キューを受け取ると、以下の記事で説明した「ルーティーン」が呼び起こされる
    - https://qiita.com/minegishirei_v2/items/4dddc8d6ebd71a9d108f
    - これは無意識的な反応であり、人間はこの「反応」を認識することができない
    - 例えば、人は階段を見たときにエレベーターを連想してしまう。
    - ユーザーはあなたのアプリを見たときに、第一印象で使うかどうかを判断してしまう。
    - 平たく言えば、ここで脱落する可能性が高い。
    - 初回のユーザー体験は大事。
- 評価 `Evalution` : `キュー`によって心が行動するかどうかを決めた後、直観的は反応で脱落せずに済んだらここに来る。この段階では意識として行動の選択肢に上がっている状態。
    - ほかの選択肢をけなす : エレベーターは混んでいるし、この中の時間は遅い
    - メリットを強調する : 階段は運動になるし、やせる。
- アビリティ `Ability` : 実際に行動に取り掛かるかどうかを判断している。
    - アクションプラン : ユーザーがこれから行動するとして、どのように行動するべきか把握していなければならない。NISAを始めたければ口座の開設と結び付け方を把握している必要がある。
    - リソース : 実際に行動したいとして、口座の開設などには時間とお金とパソコンが必要だ。
    - スキル : 行動するために必要な前提条件能力が必要。口座の開設にはＩＴリテラシーが必須。
    - うまくいく確信 : 上記の能力をもって、達成できるという確信が必要。
- タイミング `Timing` : 「今」やるべきかどうかを判断している。
    - 外からの緊急性 : ex) 年末調整など
    - 内からの緊急性 : ex) おなかが痛いのでヘパリーゼを飲むなど
    - 具体性 : ex) 「木曜日の食後に年末調整をしよう」など





この行動モデルは「フォッグの行動モデル」というものを参考にしている。

上記のどれかで脱落してしまえば、実際に行動に起こされることはない。
【UEFN】１時間で島を制作した流れを紹介してみる

## 背景
UEFNはとても早くゲームが制作できそうだなと思っていました。初めての出した島も約一時間で制作できました。フォートナイトというゲームの力を借りて最低限のクオリティを保ったまま制作できるのはとても面白いことであります。

Verseという新しい言語も出てきたりとまだまだ島制作における効率化や制作フローに言及するものが少なかったのでとりあえず書き残しておこうと思います。

## 制作した物
制作時のハイライト動画もあります。
「ISLAND DRIVING」【2149-4100-3953】 
1〜16人用レースゲーム

https://x.com/KEisuke62350514/status/1708879494097092933?s=20

## 流れ
- どのようなゲーム制作するか決める
- Notionに軽くタスクをかき出す
- テンプレート島の選定
- 島のルート？のようなものを画像に書き出す
- 島全体のオブジェクト配置 or ゲームの機能を作るデバイスの配置(二人で同時に制作したのでここは作業分担しました。)

### どのようなゲーム制作するか決める
今回はバイクでただゴールを目指すゲームにしました。

### Notionにまとめる
簡単なタスクをかき出し全体マップのイメージ画像を貼る

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692976/05170798-d8c2-838d-341b-fb6bb32710ec.png)

### テンプレート島の選定
はじめから自分の制作したいもののイメージと近い島を選ぶことでオブジェクト配置の時間がカットできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692976/ee45a360-41c9-16d6-5ad5-bda08392ca14.png)

### 島の全体イメージ図をかき出す
今回は中央の島を目指して島と島の間のルートを作りました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692976/a078fd75-ffeb-a468-4af6-6d3ab3c8ff03.png)

### 島全体のオブジェクト配置
先ほどの全体イメージ図をもとにバイクが走るルートに道を配置していく作業でした。
**2人制作だったのでゴールから配置していく係とスタートから配置する係に分担してやることで二人が同時に一つのものを編集しにくくさせました。**

### ゲームの機能を作るデバイスの配置
今回はスタート、ゴール判定の機能、タイマーの機能、落ちたらリスポーンするなどの機能追加でした。

初心者の方はゲームメーカーズさんの記事がとても参考になると思います！（とてもお世話になりました。）

https://gamemakers.jp/howto-uefn/

## まとめ
### チーム制作するときの掟としては
- できるだけ細かくチェックインする。
- チェックインするときは宣言してもらい同期も細かくする
- メンバー同士で隣接したPropなどの編集、配置は極力避ける（間違えて編集状態に入りどちらかが全くそのPropの編集ができなくなる）

### 可能性
現在、私はVerseを積極的に活用することで極力配置するDeviceを少なくすることや設定する項目を少なくすることで島制作の効率化に取り組んでいます。まだコードだったりは公開できないですがタイクーンというゲーム関しては3時間以内で制作できてしまうところまで来ました。

テストコードの書き方だったりも出てきはじめていたりするのでより安定したプロジェクトをより高速に制作することができそうです。