OmniAICreator/Qiita-1.07M huggingface dataset:
Terraform × Instana 実践編：file() か jsonencode() か？Widgets構成でハマった話

# はじめに
本記事は、以前投稿した以下の記事の続編です：

[TerraformでInstanaのカスタムダッシュボードを作ってみた（with jsonencode / jsondecode）](https://qiita.com/daihiraoka/items/b197e849cd54465f1bd9)

前回は、Instana Provider を使って Terraform でカスタムダッシュボードを作る方法と、必要な設定やAPIの仕様について触れました。

今回は「**widgetsの構成方法**」をテーマに、Terraformが毎回差分を出してくる問題や、結局どう書くのが安定なのか？を深掘りしていきます。

---

## 背景：`file()` だけでいけるんじゃ？説

Instanaの公式ドキュメントでは、以下のように `widgets = file("widgets.json")` の記述例が示されています：

```hcl
resource "instana_custom_dashboard" "example" {
  title = "Example Dashboard"

  access_rule { 
    access_type = "READ_WRITE"
    relation_type = "USER"
    related_id = "user-id-1"
  }

  widgets = file("${path.module}/widgets.json")
}
```

この記述、ぱっと見て「文字列で渡せばOK」と思って試したくなりますよね？

## 実験結果：Instana側では成功、Terraformでは diff の嵐

```hcl
widgets = file("widgets.json")
```

この形式で実際に試したところ…

- **◯ InstanaにはPOSTされ、ダッシュボード作成は成功！**

- **❌ ただし Terraform の plan/apply に毎回diffが出る**

```text
.widgets: planned value ... does not match config value ...
```

その理由は、file()で読み込んだ内容が整形（インデントや改行）されていて、**構造としての比較ではなく文字列としてdiffが出る** ためです。

## 原因考察：Terraformは`file()`の内容を文字列として扱う

Terraformでは widgets のようなJSONオブジェクトは構造化した形式として比較されるべきですが、
file() 関数で読み込んだ場合、Terraformはその中身をただの文字列として扱ってしまいます。

つまり、中身がまったく同じ構造でも、インデントや改行の違いだけで「変更あり」とみなされてしまうのです。

```hcl
locals {
  widgets = jsondecode(file("${path.module}/widgets.json"))
}

resource "instana_custom_dashboard" "example" {
  ...
  widgets = jsonencode(local.widgets)
}
```

こうすることで、Terraformが内部で構造を基に比較し、不要な`diff`が発生しなくなります。

---

## おまけ：`related_id` にメールアドレス入れると怒られる

```text
Error: USER is unknown
Body: {"errors":["Related ID dai@hiraoka (USER) is unknown."]}
```

これは `access_rule` にメールアドレスを渡していたためです。
Instanaの仕様では、`USER`の `related_id` に必要なのは **UUID形式のユーザーID**。

ユーザー一覧は API から取得できます：

```bash
curl -s -H "Authorization: apiToken $INSTANA_API_TOKEN" \
  "$INSTANA_ENDPOINT/api/settings/users" | jq .
```

---

## widgets.json の例

```json
[
  {
    "id": "widget-1",
    "title": "Tokyo Sample Widget",
    "x": 0,
    "y": 0,
    "width": 6,
    "height": 3,
    "type": "apdex",
    "config": {
      "apdexConfigId": "Tokyo-some-config-id",
      "entityType": "website",
      "entityId": "Tokyo-some-entity-id"
    }
  }
]
```

## 結論まとめ

| ケース                           | 結果・考察                               |
|--------------------------------|------------------------------------------|
| `widgets = file(...)`          | 通るが plan/apply に差分が出るため非推奨 |
| `widgets = jsonencode(...)`    | 安定して構造的に一致。おすすめ        |
| `related_id = "メール"`        | Instana 側で拒否される NG                |
| `related_id = "UUID"`         | OK                                        |


## 実際にPRを出しました！
今回の件は、Instana Providerのドキュメントに対して以下の改善PRを提出し、修正提案として取り込んでもらえるよう働きかけています：

 [Fix: Recommend using jsondecode(file(...)) for widgets to avoid false diffs #34](https://github.com/instana/terraform-provider-instana/pull/34)

もし同じようにハマった方がいれば、PRやIssueに**イイね**してもらえると、反映の後押しになるかもしれません！

ここまで読んでくださってありがとうございました！
Enumによる有限性の構造化：モナドの入り口



> _"世界を切り分けるには、まず“起こりうること”を限定せよ。"_  

Rustにおける `enum` は、ただの列挙子ではない。  
それは**構造としての有限性の設計手段**であり、**抽象と制約を同時に表現する道具**だ。

多くの言語で `enum` は「列挙子の定数」で終わる。  
しかしRustでは、`enum` は**型そのものであり、状態と構造の分岐を“安全に”定義する**ための中核である。  
さらに言えば、**関数型パラダイムにおける“モナド”的構造への入口**でもある。

この章では、Rustの `enum` が設計に与える力と、その背後にある構造的哲学を掘り下げていく。

---

## Enumとは、分岐の設計構造である

Rustにおける `enum` の定義はこうだ：

```rust
enum Status {
    Ok,
    Error,
}
```

この構造は、C言語などの単純な列挙子定義とよく似ている。  
だが、Rustの `enum` は**バリアントにデータを持たせることができる**。

```rust
enum Status {
    Ok(String),
    Error(u32),
}
```

これは、「状態」と「文脈の違い」を**型レベルで表現できる強力な抽象手段**である。  
**分岐ごとに文脈を定義できる構文**とも言える。

---

## matchによって設計者は「すべての可能性」と向き合う

Rustでは、`enum` を扱うには `match` を使うのが一般的だ。

```rust
fn respond(status: Status) {
    match status {
        Status::Ok(message) => println!("Success: {}", message),
        Status::Error(code) => println!("Error code: {}", code),
    }
}
```

この `match` は、**あらゆる分岐を網羅しなければコンパイルが通らない**。  
つまり、「起こりうるすべての事象」に対して、設計者は**明示的に対処する責任**を負う。

> _“全てのケースを設計せよ。設計しないものは、存在を許さない。”_

---

## OptionとResult：モナドの顔をしたEnum

Rustの `Option<T>` と `Result<T, E>` は、ただの列挙型ではない。  
これらは、**関数型言語におけるMaybe型・Either型の再解釈**であり、  
**安全なエラー処理・分岐処理の設計構造**そのものである。

```rust
enum Option<T> {
    Some(T),
    None,
}

enum Result<T, E> {
    Ok(T),
    Err(E),
}
```

これらは、**型と構文によって「何が起こりうるか」を記述し、制御構造を生み出す仕組み**である。  
そして、これこそがモナド的思考の起点である。

---

## 抽象と制約を同時に提供するEnumの強さ

普通、型は柔軟性を上げるほど制約が減る。  
だがRustの `enum` はその逆を行く。**柔軟性と制約が共存している。**

- `enum` によって表現可能な構造は自由度が高い  
- `match` によってすべての分岐を網羅する義務が課される  

これにより、**「意図的な制限によって信頼できる抽象」が生まれる**。  
これは、安全と汎用性の両立という、設計者が求め続けた理想の1つの答えである。

---

## Enumは振る舞いの抽象にも拡張できる

Rustでは `enum` にメソッドを定義できる。

```rust
impl Status {
    fn is_ok(&self) -> bool {
        matches!(self, Status::Ok(_))
    }
}
```

これは、「状態を定義するだけでなく、**状態に対する振る舞いも閉じ込めることができる**」という意味になる。

つまり、**`enum` はデータ構造でありながら、モジュール的責任も負える構造体**なのである。

---

## 「if」ではなく「match」へ：分岐の意味を問う

Rustでは、 `match` を使うことで**条件分岐を「設計」へと昇華できる**。

- if: 状態を前提にして処理を分ける（不完全でも書ける）  
- match: 状態そのものを列挙し、すべてを扱う（不完全なら書けない）

この違いは、「プログラミングの自由」ではなく、**「設計の誠実さ」**である。

---

## Enum × map / and_then：モナド的振る舞いの獲得

`Option` や `Result` は、`.map()` や `.and_then()` によって連鎖的に操作が可能になる。

```rust
fn double(x: Option<i32>) -> Option<i32> {
    x.map(|n| n * 2)
}
```

この構文は、関数型プログラミングにおけるモナドの `bind` に対応し、  
**“文脈付きの値”を、安全かつ構造的に処理する連続性**を表現している。

> _“文脈を持つ値を、文脈の中で安全に変形する”_

それは、ただの計算ではない。**「構造の流れ」による設計の再構築**である。

---

## 結語：Enumとは有限性に秩序を与える型である

Rustの `enum` は、可読性や構文糖衣のためにあるのではない。  
それは、**有限性という制約に美しさと信頼性を与えるための言語設計**である。

そしてその先には、関数型言語に根差した**“構造の文脈化”という思想＝モナド的世界**がある。

> _"起こりうることをすべて定義する。それが、混沌に秩序を与える設計の第一歩である。"_
型とは何か：Rust型システムの幾何学



> _"プログラミングとは、無限に拡がる世界を有限に構造化する行為である。"_  

型とは、言語において最も根源的な**境界の構文**である。  
それは、無制限な数値に意味を与え、無秩序な構造に制約を与える。

Rustにおいて、型は単なる制約ではない。  
それは、**意味、責任、文脈、そして哲学の構造体**である。  
この章では、Rustが設計した「型の幾何学的世界」と、そこに宿る思想を紐解いていく。

---

## 型は「意味」の境界である

```rust
let age: u32 = 32;
let height: f64 = 174.2;
```

この時、`u32` や `f64` が示しているのは、ただのビットサイズや構造ではない。  
それは、「この値は年齢であり、これは身長である」という、**意味論的宣言**なのだ。

Rustでは、**型が“何であるか”と“何でないか”をはっきりと分ける**。  
この明示性が、設計の予測可能性と信頼を支えている。

---

## 静的型付けは“制限”ではなく“予測性の保障”である

動的型言語では、「とりあえず動かしてみる」ことが可能である。  
だが、それはしばしば**実行時にしか起こらない失敗**を孕む。

Rustの型システムは、それを**“コンパイル時に”封じ込める構造**として設計されている。

- 「この関数にはこの型しか渡せない」  
- 「この操作はこの型にしか定義されていない」  
- 「このトレイトがなければこの処理はできない」

これらの制約は、**プログラムを“設計可能な空間”に閉じ込める幾何学的格子**である。

---

## 新しい型を定義するということは、新しい意味を設計するということ

```rust
struct Meters(u32);
struct Seconds(u32);
```

このような構造体の違いは、実体としては同じ `u32` である。  
だが、意味としては明確に異なる。  
**型は、単位・責任・文脈を分離するための概念的レイヤー**なのである。

---

## 型によって設計が語られ、設計によって型が育つ

Rustの型システムは、単なるデータ構造の制約ではなく、**設計の言語**である。

- 構造体：状態の単位  
- 列挙型：分岐の列挙  
- トレイト：振る舞いの共通構造  
- ジェネリクス：文脈に応じた抽象化

これらはすべて、「型とは何か」を再定義する問いかけである。

---

## 型の粒度と設計の信頼性は比例する

たとえば次のコード：

```rust
struct Email(String);
struct Username(String);
```

このように型を分けることで、間違った順序で引数を渡してしまうというバグを防げる。

```rust
fn register(username: Username, email: Email) { ... }
```

これは単なる安全性ではなく、**設計上の信頼を構文に変換する設計行為**である。

---

## トレイトによる「振る舞いの抽象」もまた、型の拡張である

Rustの型は、構造を持つだけでなく、**振る舞い（trait）によって文脈に適合していく**。

```rust
trait Drawable {
    fn draw(&self);
}
```

これは、「この型が持つべき性質」を、**明示的に定義し、型に宿す**ということに他ならない。  
Rustでは、型がすべてを語る。**振る舞いさえも“型として設計”されている**。

---

## 結語：型とは、意味に構造を与える幾何学である

Rustの型システムは、強く、厳密で、厳格である。  
だがそれは、開発者の自由を奪うためではない。  
**自由を、信頼できる構造の中で扱えるようにするための制限**なのだ。

型を設計するということは、**設計そのものを言語に翻訳する行為**であり、  
Rustの型システムはその翻訳装置として、非常に哲学的である。

> _"コードは型によって構造化され、型は思想によって定義される。"_
不変性と変化の管理：immutabilityが意味する自由



> _"制御されない変化は、システムを腐敗させる。"_  

状態を変えること、それはプログラミングにおいて“当然”とされてきた。  
変数とは「変わることができる値」であり、変更とは機能の実現そのものだった。

だがRustは、その“当たり前”を疑う。  
**デフォルトを「不変（immutable）」としたことで、設計の意味が逆転した。**

この選択は、単なる言語仕様ではない。  
**変化の意味を構造化し、状態を意識的に制御するという設計哲学**である。

---

## なぜRustはすべてを“変更不可”から始めるのか？

Rustでは、変数はデフォルトで不変である。

```rust
let x = 5;
x = 6; // エラー: 不変な変数に再代入はできない
```

変更を許すには、明示的に `mut` を指定する必要がある。

```rust
let mut x = 5;
x = 6; // OK
```

これは、「変更してよい」と設計者が明言した変数だけが変わることを許されるという、  
**“意図の明示”による責任設計**なのである。

---

## 不変性とは「できること」を減らすのではなく、「考慮を減らす」ことである

変数が変わらないということは、それについて考慮すべき分岐が減るということだ。

- 「この値はどこで変わったのか？」  
- 「この変数は共有されているが、同時に変えられていないか？」  
- 「テスト時に意図しない副作用が起きていないか？」

不変性は、これらの懸念をすべて**構造の外に追いやる**。  
つまり、**考えるべきことが減る＝設計の透明性が増す**のである。

---

## Rustの不変性は「静的な秩序」である

関数の引数も不変が基本であり、書き換えを意図するならば参照とmutabilityを組み合わせて書く必要がある。

```rust
fn update(val: &mut i32) {
    *val += 1;
}
```

このような構文は、**意図的に「ここで状態が変わる」と宣言することでのみ、変更を許す**。

これは副作用を「許容」するのではなく、「構造に組み込む」ことに他ならない。

---

## 不変性と共有：同時性への設計的備え

Rustでは、イミュータブルな値は複数のスレッドから同時に借用可能である。  
なぜなら、**変化しないものは競合しない**からだ。

```rust
let data = Arc::new(String::from("Hello"));
let d1 = data.clone();
let d2 = data.clone(); // OK: 不変なら何者とも争わない
```

この設計が示すのは、**不変性がスレッドセーフを“保証するための構造”である**ということだ。

---

## イミュータビリティは“信頼の源泉”である

不変性がもたらすのは次の3つである：

1. **読んでも安心**：他の場所で書き換えられていないと保証される  
2. **共有しても安心**：排他制御のためのmutexが不要になることが多い  
3. **再利用しても安心**：副作用がないことで、コードが構成可能になる

この“安心”こそが、設計における**信頼性の土台**なのだ。

---

## 変更は“最後に選ぶ手段”であるべき

Rustは変化を禁じているわけではない。  
むしろ、**意図が明確にされた“必要な変化”だけを構文で許している**。

これは言語仕様というより、**変化に対する倫理的態度**である。

- 本当に変更が必要か？
- その変更は設計に含まれているか？
- その変更は共有されるべきか？

こうした問いを**書くたびに開発者に突きつける**。  
だからRustのコードは、設計者の“誠実さ”がにじみ出る。

---

## 結語：変わらないということ、それが信頼されるということ

変わるものに人は慎重になる。  
変わらないものは、それだけで**構造的な信頼を得る**。

Rustのイミュータビリティは、  
単なる最適化やスレッドセーフのための手段ではない。  
**それは「設計が信頼に値する状態であるか」を問い続ける仕組み**である。

> _"自由に変えることは自由ではない。変えないことを選べる構造こそが、設計の自由である。"_
Nullと未定義の死：RustにおけるMaybeとOptionの美学



> _"無を許した瞬間、設計は曖昧を内包する。"_  

プログラミング言語の最も根深い問題のひとつ、**Null（null pointer）**。  
その危険性は言わずもがなであり、多くのセキュリティホールとアプリクラッシュの温床となってきた。

この“無”という概念に、Rustは明確な態度を取った。  
**「Nullを言語仕様から削除する」**という思想だ。  

代わりに導入されたのが、**Option型**。  
それはただの列挙型ではない。**曖昧な状態を構造に変換する哲学的構文**である。

---

## Nullという“暗黙の不在”

Nullは「値がないことを示す」シンプルな記号に見える。  
しかしそれは、「この変数が存在するかどうかは、使ってみるまでわからない」という不確実性でもある。

```java
String name = getUserName();
int length = name.length(); // ← NullPointerExceptionの可能性
```

これは単に例外の温床なのではない。  
**「設計が意図を明示していない」という構造の破綻**である。

---

## Rustの回答：Option型が“無”を構造化する

RustではNullという概念そのものが存在しない。  
その代替が `Option<T>` である。

```rust
fn find_user(id: u32) -> Option<User> {
    if id == 0 {
        None
    } else {
        Some(User::new(id))
    }
}
```

この構文は、**「値があるかもしれない／ないかもしれない」**という可能性を、  
**“明示された型”として設計に取り込む**ものだ。

---

## Some/Noneという明示的分岐の強さ

Optionの核は `Some(T)` と `None` という2つの明確な状態にある。  
そしてそれを扱うには、必ず構文的な分岐が求められる。

```rust
match find_user(1) {
    Some(user) => println!("User found: {}", user.name),
    None => println!("No user found"),
}
```

これは「値がないことを前提にしないとコンパイルできない」＝  
**「曖昧さの無視を許さない設計」**ということに他ならない。

---

## OptionとMaybeの関係：関数型の美学

RustのOption型は、Haskellなどの関数型言語における `Maybe` モナドと非常に近い。

- `Some(T)` = `Just T`  
- `None` = `Nothing`

そしてこの構造が持つ本質は、**「分岐の強制による安全性」**にある。  
曖昧さを許すのではなく、**“明示することで責任を分配する”**。

それは、**エラー処理ではなく、設計の美しさ**である。

---

## unwrapの罪と美：意図の表明

Optionには `.unwrap()` というメソッドも存在する。  
これは、値があることを前提に中身を取り出す構文である。

```rust
let user = find_user(1).unwrap(); // 値がなければpanic
```

危険なようにも思えるが、これは**意図を明示した上での設計的覚悟**でもある。

- `match` ＝ 明示的な分岐と処理
- `unwrap` ＝ 値があることを**宣言する責任**

つまり、**曖昧な意図が排除されている限り、それは安全と見なされる**。

---

## Optionが設計者にもたらす3つの効能

1. **曖昧な状態が型に昇華される**  
2. **すべての“存在しない可能性”に対して、設計者が選択を迫られる**  
3. **関数のインターフェースに、設計上の正直さが宿る**

この3つによって、Optionは**ただの“Nullの代替”ではなく、設計倫理そのもの**になる。

---

## 結語：空白に意味を与えるという設計

RustのOptionは、「ないものをどう扱うか」という問いを、  
**「そもそも設計に取り込め」と言い換える。**

それは、無を隠すことでも、ごまかすことでもない。  
**“無があること”を、設計者が引き受け、構文として明示する**ことだ。

> _"Nullという沈黙を、Optionという構造に翻訳することで、Rustは設計に誠実さを取り戻した。"_
コンパイラが許さない：安全性のための拒絶という設計



> _"やさしさとは、ときに拒絶の形をとる。"_  

Rustで最も特徴的なのは、その**コンパイラが驚くほど厳しい**ことだ。  
それは時に、苛立ちの種になる。  
"なぜこれが動かない？ 他の言語なら動いたのに。"  
そんな声は、Rustの入門者から必ず聞こえてくる。

だが、その拒絶は、ただの仕様の厳格さではない。  
**設計を信頼に変えるための、構文レベルでの倫理的防御**なのだ。

---

## 許されない理由がある：拒絶するコンパイラの哲学

Rustコンパイラは、以下のようなコードを**容赦なく拒絶**する：

- 未使用の変数
- 所有権が曖昧な値の再利用
- ライフタイムの不整合
- 可変と不変の借用の競合
- 条件分岐における未初期化アクセス

これらは、CやC++なら“とりあえず動く”ことが多い。  
だがRustは、**「動く」より先に「壊れない」を選ぶ**。

---

## “未定義動作”を存在させない構造的前提

C言語におけるバグの多くは、**未定義動作（undefined behavior）**に起因している。  
ポインタの解放後アクセス、バッファオーバーラン、二重解放……。

Rustでは、このような**「動くかもしれないが、保証できない」コードを最初から書けない**。

```rust
fn main() {
    let r;
    {
        let x = 5;
        r = &x; // ライフタイムが切れる → 拒絶される
    }
    println!("{}", r);
}
```

このようなコードが**コンパイルされない**という事実が、  
**Rustの設計思想＝“静的に正しくなければ、そもそも書かせない”** を物語っている。

---

## テストで拾うのではなく、構文で遮る

ほとんどの言語は「動作してみて問題がなければOK」というアプローチを取る。  
つまり、安全性は**テストやレビューに委ねられている**。

Rustではそれが**設計構造そのものに埋め込まれている**。  
動かして問題を見つけるのではない。**「書けない」という段階で、問題を消す**。

この思想が生み出すのは、**開発者の主観を超えた信頼性**である。

---

## エラーは設計者への問いである

Rustコンパイラのエラーメッセージは、時に詩的ですらある。

```
error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
```

これは単なるコンパイルエラーではない。  
**「この構造は、本当に安全か？」という設計への問いかけ**である。

**コンパイルエラーとは、言語と設計者との対話**であり、  
その対話に向き合ったとき、初めて“Rustが許さない理由”が見えてくる。

---

## 拒絶によって育まれる「設計の筋力」

初期のRustは、エラーを返すたびに開発者の反感を買った。  
だが、開発者は学び、次第にこう感じるようになる。

- 「この設計は破綻している」と、**コードを書く前に気づけるようになる**  
- コンパイラが通るということが、**ある種の“設計レビュー”を通過した感覚**になる

この“拒絶される経験”こそが、**設計を成長させる環境としてRustを機能させている**。

---

## 許されないコードは、構造として間違っている

Rustにおいて「書けないコード」は、「動かしてはいけない設計」である。  
それは自由の否定ではなく、**未来のバグの予防であり、責任の制限**である。

- 明示されていない所有権は許されない  
- 意図されない共有も許されない  
- 不確定な時間軸のアクセスも許されない

それらは、**すべて“設計者の信頼”を裏切る可能性を孕んでいる**。  
だからこそ、Rustはそれを**構文で拒絶する**。

---

## 結語：設計を育てる拒絶の構文

多くの言語は、開発者に「動く自由」を与える。  
Rustは、開発者に「壊さない制約」を課す。

この構文的な厳格さは、単なるエラーの多さではない。  
**設計を透明にし、意図を保証し、信頼を構造で伝えるための“拒絶としての優しさ”**である。

> _"書けないことで、救われる設計がある。Rustはその静かな守護者なのだ。"_
借用とライフタイム：時間と空間に設計を埋め込む言語



> _"時間を設計せずに、安全なプログラムは書けない。"_  

Rustにおいて、所有権（Ownership）は空間的責任の明示だった。  
誰がデータを持っているか。誰が解放するか。誰が変更できるか。

しかし、**それだけでは不十分だった。**

なぜなら、**メモリは空間だけでなく、時間の文脈の中に生きているからだ。**  
そしてRustはその「時間の正しさ」を、**ライフタイム（lifetime）という設計概念**として導入した。

この章では、**Rustという言語が“時間そのものを構文に組み込んだ”設計思想**を掘り下げていく。

---

## 借用とは、信頼に基づく一時的な委任である

```rust
fn print_length(s: &String) {
    println!("Length: {}", s.len());
}
```

ここで `&String` が意味しているのは、  
「所有者から**借りている**」という状態である。  
所有はしていない。**だから解放はしない。だが使う権利はある。**

この微妙な関係性を**構文レベルで強制する**のが、Rustの借用システムだ。

> 借用とは、「責任を持たないが、壊さない」約束である。

---

## 不変の借用・可変の借用：共有と排他の交差点

Rustでは、同時に複数の参照が可能なのは**不変（immutable）借用**のみである。

```rust
let s = String::from("hello");
let a = &s;
let b = &s; // OK
```

一方で、**可変借用（&mut）**は**必ず単独で存在しなければならない**。

```rust
let mut s = String::from("hello");
let r1 = &mut s;
let r2 = &mut s; // コンパイルエラー
```

この排他性の強制こそが、**「並行性の安全」と「構造の明快さ」**を同時に実現する設計である。

---

## なぜライフタイムが必要か：時間の整合性という設計課題

所有と借用の仕組みだけでは、まだ“正しさ”は保証できない。  
なぜなら、「借りている値が**すでに消滅しているかもしれない**」というリスクがあるからだ。

```rust
fn invalid_ref() -> &String {
    let s = String::from("temp");
    &s // ライフタイムが切れる→ダングリング参照
}
```

ここで必要なのが、**ライフタイム（lifetime）**である。  
ライフタイムは、**「この参照は、どのデータと同じ期間だけ生きるべきか」を宣言する機構**である。

---

## ライフタイム注釈：明示的に“時間を設計する”構文

```rust
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() { x } else { y }
}
```

この `<'a>` は、変数 `x`, `y`, 戻り値がすべて**同じ期間だけ有効であることを保証する**。  
これは単なる文法ではない。**時間における制約を明文化する構文**であり、**設計者の意図そのもの**である。

---

## 所有＝空間設計、ライフタイム＝時間設計

Rustは言語そのものが「構造を定義する手段」である。  
そして、その構造は**空間的責任（所有）と時間的整合性（ライフタイム）**によって初めて成り立つ。

他言語では、このような制約は「開発者の判断」や「テストによる確認」に委ねられる。  
だがRustは、**構文によってそれを設計フェーズに引き戻した。**

---

## ライフタイムの明示がもたらす“設計の信頼”

ライフタイムによってもたらされるのは、以下の3点である：

1. **不正参照の構造的排除**  
2. **所有と借用の関係の明示化**  
3. **関数インターフェースにおける“使用可能期間”の明示**

つまり、ライフタイムとは**“時間における型安全性”**を言語に持ち込む試みなのだ。

---

## 結語：時間は副作用ではない、設計項目である

多くの言語では、「いつ使えて、いつ壊れるか」は**実行時の結果**でしかない。  
だがRustでは、それが**設計時の制約として記述され、保証される。**

時間に設計を持ち込むこと。  
それは、コードを**信頼できる構造物に変えるための最後の一歩**である。

> _"ライフタイムとは、時間という不確実性を、構文によって構造化するという思想である。"_
所有権という哲学：Rustが世界に投げかけた問い



> _"制限とは、思想である。自由とは、秩序の上にのみ成立する。"_

Rustという言語を初めて触ったとき、私たちはある種の違和感に直面する。  
それは型の難解さでもなければ、マクロ構文の抽象性でもない。  
もっと根源的な、**所有権（ownership）という設計思想**との出会いだ。

それは一見、単なるメモリ管理の仕組みに思える。  
だが、実のところ所有権とは、**コードにおける責任と移動の哲学的構造**なのである。

---

## 所有とは何か：言語がコードに責任を持たせる瞬間

CやC++では、メモリの所有権は「暗黙の了解」として開発者の背後に存在する。  
誰がfreeするかはコードレビューで確認され、設計書に書かれ、運用で補完される。  

Rustは、これを**構文の中に持ち込んだ**。

```rust
fn main() {
    let s = String::from("hello");
    takes_ownership(s);
    // ここでsは使えない。所有権は移動している。
}
```

これはただの変数移動ではない。  
**「誰が責任を持っているか」を明示し、曖昧な所有を許さない言語哲学**なのである。

---

## 所有権は“制限”ではなく“解放”である

Rustの所有権システムはしばしば“厳しすぎる”と評される。  
実際、所有権エラーに直面してコードが書けなくなる体験は、Rust初学者の洗礼のように語られている。

だが、それは「不自由だから書けない」のではない。  
**「責任が不明確だから、書かせない」のである。**

この設計が生むものは、制限ではない。  
**“安心して共有できる状態”という解放**なのだ。

---

## 所有権・借用・移動：設計は振る舞いの交差点に宿る

Rustの設計において重要なのは、「何ができるか」よりも、「何を許さないか」である。

- 所有権（ownership）：唯一の責任者
- 借用（borrowing）：一時的な委任（参照）
- 移動（move）：責任の譲渡

これは単なるメモリモデルではない。**構造的な設計言語**であり、  
各関数や構造体に対して、「何が可能で、何が禁止されているか」を静的に定義するための**哲学的プロトコル**である。

---

## 所有権の拒絶が防ぐ“設計上の嘘”

多くのバグは、**設計意図と実装挙動の乖離**から生まれる。  
ある変数を「もう使わないと思っていた」のに、別の場所で再利用されていた——  
そうした事例は、過去にいくつものセキュリティ事故を生んできた。

Rustの所有権はそれを**コンパイル時に拒絶する**。

```rust
let a = vec![1, 2, 3];
let b = a;
// aはここで使えない。bが所有している。
```

これは、**ミスを“構造上不可能”にする設計**なのだ。

---

## 所有は排他性であり、安全であり、信頼である

Rustでは、データは基本的に**単一の所有者**しか持たない。  
それは、「自由に使える」ことを禁じる代わりに、「安全に扱える」ことを保証する。

この排他性が生むものは次の3つだ：

1. **安全性**：二重解放・解放忘れが起きない  
2. **予測可能性**：コードの流れが明示的になる  
3. **構造的信頼**：プログラマが“信じられる前提”でコードを書くことができる

---

## 所有権は“設計の粒度”を定義する仕組みでもある

所有権は、単にメモリの話ではない。  
それは、「どの構造が、どこまで責任を持つか」を定義するスコープの話でもある。

- 構造体が所有する
- 関数が一時的に借りる
- ユーザーが明示的に移動する

こうした関係を**設計構造として明示することで、粒度と責任のスコープが一致する**。  
つまり、Rustのコードは「読みやすい」ではなく、**「信じられる構造」になるのだ**。

---

## 結語：所有とは制御であり、制御とは思想である

所有権はRustの制約であると同時に、**最大の自由をもたらす設計的インフラ**である。  
それは、何を許すかではなく、**何を許さないかを通して、設計を定義する**言語思想だ。

多くの言語が「柔軟であること」を価値とする中で、  
Rustは「**柔軟でないことの価値**」を再定義し、現代の開発者に新たな問いを投げかけている。

> _"自由とは、正しく制限された構造の中でしか、真に享受されることはない。Rustの所有権は、それを静かに証明している。"_
MacでGoをインストールする際のプロセッサアーキテクチャ確認方法

## はじめに

Goをインストールしようとした際、Macの場合はARM64とx86-64の2種類のバイナリが提供されています。どちらをダウンロードすればいいのか迷ったので、自分のMacがどちらのプロセッサアーキテクチャなのかを確認してみました。

## プロセッサアーキテクチャの確認方法

ターミナルで以下のコマンドを実行するだけです。

```bash
uname -m
```

## 実行結果

自分のパソコンで実行してみたところ、以下のように表示されました：

```
satouhoge@Mac ~ % uname -m
arm64
```

このように「arm64」と表示されたので、私のMacはApple Silicon（M1/M2/M3など）搭載であることがわかりました。

参考までに、「x86_64」と表示された場合は、Intel CPUを搭載したMacです。

## インストールするGoのバージョンの選択

プロセッサアーキテクチャに合わせて、以下のバージョンを選択します：

- Apple Silicon Mac（arm64）: `go1.24.2.darwin-arm64.pkg`
- Intel Mac（x86_64）: `go1.24.2.darwin-amd64.pkg`

プロセッサアーキテクチャに適したバージョンをインストールすることで、最適なパフォーマンスが得られます。

## まとめ

Macでソフトウェアをインストールする際は、自分のマシンのプロセッサアーキテクチャを確認することが重要です。`uname -m`コマンドを使えば簡単に確認できます。私の場合はarm64だったので、Goをインストールする際はARM64用のパッケージを選択しました。
x86 アセンブリ言語 関数呼び出し callとjmpの違い

## コンパイル

### C言語ソース
```test.c
#include <stdio.h>

void foo() {
    printf("hello from foo\n");
}

int main() {
    foo();
    printf("back in main\n");
    return 0;
}
```

### アセンブリ言語へコンパイル
C言語コードをアセンブリ言語にコンパイルするために、gccコマンドを使用します。
```
gcc -S -masm=intel test.c -o test.s
```

### アセンブリ言語ソース
コンパイルされたアセンブリは次のようになっています：
```test.s
	.file	"test.c"
	.intel_syntax noprefix
	.text
	.section .rdata,"dr"
.LC0:
	.ascii "hello from foo\0"
	.text
	.globl	foo
	.def	foo;	.scl	2;	.type	32;	.endef
	.seh_proc	foo
foo:
	push	rbp
	.seh_pushreg	rbp
	mov	rbp, rsp
	.seh_setframe	rbp, 0
	sub	rsp, 32
	.seh_stackalloc	32
	.seh_endprologue
	lea	rax, .LC0[rip]
	mov	rcx, rax
	call	puts
	nop
	add	rsp, 32
	pop	rbp
	ret
	.seh_endproc
	.section .rdata,"dr"
.LC1:
	.ascii "back in main\0"
	.text
	.globl	main
	.def	main;	.scl	2;	.type	32;	.endef
	.seh_proc	main
main:
	push	rbp
	.seh_pushreg	rbp
	mov	rbp, rsp
	.seh_setframe	rbp, 0
	sub	rsp, 32
	.seh_stackalloc	32
	.seh_endprologue
	call	__main
	call	foo
	lea	rax, .LC1[rip]
	mov	rcx, rax
	call	puts
	mov	eax, 0
	add	rsp, 32
	pop	rbp
	ret
	.seh_endproc
	.def	__main;	.scl	2;	.type	32;	.endef
	.ident	"GCC: (MinGW-W64 x86_64-ucrt-posix-seh, built by Brecht Sanders, r3) 14.2.0"
	.def	puts;	.scl	2;	.type	32;	.endef

```

### 動作結果
```
C:\Users\nanashi\test>gcc test.s -o test.exe
C:\Users\nanashi\test>test
hello from foo
back in main

C:\Users\nanashi\test>
```

## jmpへ書き換える
次に`foo()`関数の呼び出しを`jmp命令`を使って行う方法を示します。変更前のアセンブリでは、foo()関数は`call命令`で呼ばれていますが、これを`jmp命令`に変更します。

### 書き換え箇所
```変更前.s
	call	foo
```
```変更後.s
	lea	rax, [rip + back_here]
	push	rax
	jmp	foo;

back_here:
```
### 動作結果
変更後も、以前と同じ出力が得られます。
```
C:\Users\nanashi\test>gcc test.s -o test.exe
C:\Users\nanashi\test>test
hello from foo
back in main

C:\Users\nanashi\test>
```

### call模倣部分の説明
#### lea rax, [rip + back_here]
`jmp 命令`で `foo関数`に飛んだ後、`foo関数`内の処理が終わったら、back_here ラベルに戻ります。
※調べたところ、`back_here`は絶対番地ではなく`rip`からの差分(オフセット)であり、`rip＋back_here`の結果は`back_here`の場所になるらしいのですが、頭がこんがらがり、自分でも理解が怪しいです。

詳しい方がおられましたらご教示下さい。1時間ほど考え込みましたが、理解したようなしてないような感じです。

#### push rax
次に、計算した戻り先アドレス（back_hereの位置）をスタックにプッシュします。このアドレスは、`foo関数`から戻った後に実行されるべき命令の場所になります。

#### jmp foo
最後に、`foo関数`へ跳びます。ここで、`jmp命令`は単純に`foo関数`に移るだけです。`call命令`のように戻り先アドレスを自動でスタックに積まないので、戻り先を手動でスタックへ入れる必要があるのです。

(今日は熱を出して会社を休んだのに自分は一体何をしているのでしょう。。。)
現在のAIと昔の形態素解析の違い


### 昔の形態素解析

- **手法**：ルールベースや辞書ベースが中心。あらかじめ登録された単語や品詞の情報をもとに、文章を「形態素」（意味を持つ最小単位）に分割し、品詞を判別。
- **特徴**：未知語や新語への対応が苦手。文脈理解は限定的。
- **応用例**：検索エンジン、キーワード抽出、テキストマイニングなど。

### 現在のAI（機械学習・深層学習ベース）

- **手法**：機械学習や深層学習（ディープラーニング）を活用。大量のテキストデータからパターンを学習し、文脈や意味も考慮できる。
- **特徴**：未知語や新語にも柔軟に対応。文脈や意味、意図まで理解可能。形態素解析だけでなく、構文解析・意味解析・文脈解析も一連で実施。
- **応用例**：チャットボット、要約、機械翻訳、文書レビューなど。

### 文書レビューAIの精度向上

- **精度の進化**：最新のAI言語モデル（例：GPT-3やその後継）は、膨大なテキストデータを学習し、人間が書いたかのような自然な文章を生成可能。
- **根拠**：
    - AI生成文と人間の文書の区別が難しくなっており、実際にAI判定ツールでも判別が困難なケースが増加。
    - レポートや論文などの定型的な文書では、AIと人間のレビュー精度がほぼ同等との検証結果も報告されている。
    - 「最新のAI言語モデルは、前例のないレベルの精度で人間の文体を模倣できます。GPT-3やその後継のモデルは、幅広いジャンルやスタイルにわたるテキストを生成し、その結果はしばしば人間が書いたものと区別がつかないほどです。」

### 比較表

| 項目                 | 昔の形態素解析                | 現在のAI（NLP）                   |
|----------------------|------------------------------|------------------------------------|
| 主な手法             | ルール・辞書ベース            | 機械学習・深層学習（AI）           |
| 未知語・新語対応     | 苦手                         | 得意（学習データ次第で対応可能）   |
| 文脈理解             | 弱い                         | 強い（文脈全体を考慮）             |
| 解析範囲             | 形態素レベル                  | 形態素＋意味・文脈・意図まで        |
| 応用例               | 検索、キーワード抽出など      | チャットボット、要約、翻訳、レビュー|
| 文書レビュー精度     | 限定的                        | 人間と同等レベルに進化              |

---

### まとめ

- **昔の形態素解析**は単語分割や品詞判定が中心で、ルールや辞書に依存しやすく、文脈や未知語に弱い。
- **現在のAI**は機械学習・深層学習で文脈や意味まで理解し、より柔軟で高精度な自然言語処理が可能。
- **文書レビュー分野でも、AIの精度は人間に近づいており、特に定型的な文書ではほぼ同等の結果を出せるようになっている。**

AI技術の進化により、自然言語処理の応用範囲や精度は今後もさらに広がると期待されています。
C_TS452_2021 - SAP Certified Application Associate - SAP S/4HANA Sourcing and Procurement対策（28/100）

【28日目】
トピック3：調達プロセス（9/13）

≪問題28≫
外注調達プロセスの機能は次のうちどれですか。
（３つ選択）
□外注先別に構成品目消費を決済する。
□外注発注明細の非評価入庫を転記できる。
□外注先への直接納入対象の構成品目を購入する。
□構成品目消費の後続調整を転記する。
□支給される構成品目の受注を登録する。
□支給される構成品目の出荷伝票を登録する。

≪解答≫
□外注先別に構成品目消費を決済する。
□外注発注明細の非評価入庫を転記できる。
■外注先への直接納入対象の構成品目を購入する。
■構成品目消費の後続調整を転記する。
□支給される構成品目の受注を登録する。
■支給される構成品目の出荷伝票を登録する。

≪解説≫
◆外注加工では、外部の仕入先に品目を発注しますが、通常の外部調達プロセスとは異なり、その品目を製造するために必要な構成品目を、仕入先（外注先）が使用できるようにする必要があります。
◆外注プロセスの主な特徴は、以下のとおりです。
（1）外注発注により最終製品を発注します。この発注には、外注先に支給する構成品目に関する項目も含まれます。
（2）在庫管理では、構成品目を外注先に送る際に、仕入先支給品として転記を行います。必要に応じて、外注コックピットを使って出荷伝票を登録することもできます。また、構成品目を別の仕入先から調達する場合は、それらを直接外注先に納入することも可能です。
（3）外注先は、サービスの提供や、製造・加工した品目の納入を行います。最終製品の入庫を在庫管理に登録すると、対応する構成品目が支給在庫から消し込まれます。
（4）入庫後に外注先から構成品目の過不足が報告された場合は、後続処理で入庫数量の調整が可能です。
（5）外注先からサービスに対する請求があった際には、ロジスティクス請求書照合で請求書を登録します。

◆購買伝票における外注明細は、明細カテゴリ「L」で管理されます。外注明細には、支給対象となる構成品目ごとに1つ以上の副明細を入力する必要があります。対象の品目に部品表（BOM）が登録されていれば、その構成品目を明細に自動コピーすることもできますし、手動で追加することも可能です。この外注明細では、品目コードと勘定設定が使用可能であり、支給構成品目の指定、入庫の実施（非評価入庫は不可）、請求書の受領が必須項目となります。

◆購買発注価格は、外注作業に対する価格と、外注先から支給される構成品目の価格で構成されます。これらの条件は外注購買情報で設定可能です。

◆MRPにより供給元に対する外注の購買依頼を生成するには、以下の条件を満たしている必要があります。
（1）品目マスタレコード（MRP 2ビュー）で特殊調達キーに「外注」が設定されていること
（2）外注購買情報または明細カテゴリが「外注」である契約明細が1件以上存在していること
（3）供給元一覧で、上記供給元のいずれかにMRP関連区分が設定されていること
（4）支給構成品目を含む部品表（BOM）が登録されていること
C_TS422_2023 SAP Certified Application Associate SAP S/4HANA Production Planning and Manufacturing対策（10/100）

【10日目】
トピック 2：SAPS/4HANA生産計画の概要（4/5）

≪問題10≫
最終製品の計画独立所要量による計画の主な利点は何ですか。
（２つ選択）
□最終組立にかかる時間が短縮される。
□生産リソースの需要予測計画を利用できる。
□納入/出荷時間が短縮される。
□受注生産を利用できる。

≪解答≫
□最終組立にかかる時間が短縮される。
■生産リソースの需要予測計画を利用できる。
■納入/出荷時間が短縮される。
□受注生産を利用できる。

≪解説≫
計画独立所要量を利用した計画は、生産プロセスを事前に計画することで効率を向上させることができるため、多くの利点があります。

生産リソースの需要予測計画を利用できる：計画独立所要量を利用することで、生産リソース（機械、労働力など）の需要を事前に予測し、効率的な計画が可能になります。

納入時間が短縮される：計画独立所要量に基づいて事前に生産計画が行われるため、納入時間の短縮が可能です。需要に応じて迅速に対応できる体制が整います。


SAPFieldglass：SAPFieldglassは、外部労働者とサービスの管理に特化したソリューションで、サプライヤからのリソースを適切に管理するために利用されます。
「ChatGPT o4-mini-high」を使ってGoogleChrome拡張機能を公開した話

# ChatGPT o4-mini-high を使って Google Chrome 拡張機能を公開した話

今回は、ChatGPT o4-mini-high を活用して、Google カレンダーの「コピー」ボタンから Meet の URL のみを抽出してクリップボードに入れる Chrome 拡張機能を開発・公開した手順をまとめました。

---

## 🎯 背景

- **課題**：Google カレンダーで「コピー」ボタンを押すと、予定の全文（氏名や日時、タイムゾーンなど）まで全部コピーされてしまう  
- **解決策**：イベント詳細ダイアログ内の Meet リンクだけを自動で抽出してコピーする拡張機能を作成  

---

## 🚀 機能概要

1. カレンダーでイベント詳細ダイアログを開く  
2. 「コピー」ボタンをクリック  
3. ダイアログ内にある Meet URL（例: `https://meet.google.com/xxx-xxxx-xxx`）のみがクリップボードにコピーされる  

---

## 🛠️ 開発手順（コード抜きの概要）

1. **プロジェクト構成**  
   - `manifest.json`：拡張のメタ情報と権限設定  
   - `content.js`：ページにスクリプトを注入するだけのファイル  
   - `injected.js`：ページコンテキストで `execCommand('copy')` をフックしてリンクを抽出  
   - `icons/`：ストア掲載用のアイコン  

2. **マニフェスト設定**  
   - `clipboardWrite` 権限：クリップボード書き込み用  
   - `host_permissions`：`https://calendar.google.com/*` でカレンダーの DOM にアクセス  
   - `web_accessible_resources`：CSP 回避のため外部ファイルを注入  

3. **スクリプト注入**  
   - `content.js` で `<script src="…/injected.js">` をページに追加  
   - `injected.js` ではページと同じコンテキストで `document.execCommand` を上書き  

4. **URL 抽出ロジック**  
   - 開いている “イベント詳細ダイアログ” 要素だけを検索  
   - `a[href^="https://meet.google.com"]` を優先し、なければテキストから正規表現で抽出  
   - クエリパラメータ（`?authuser=…`）を除去してベース URL のみコピー  

5. **パッケージ化 & 公開**  
   - プロジェクトを ZIP にまとめる  
   - Chrome ウェブストア デベロッパーダッシュボードにアップロード  
   - タイトル・説明・スクリーンショット・プライバシーポリシー URL を登録  

6. **プライバシーポリシー & 審査対応**  
   - ユーザーの個人情報は一切収集せず、権限は最小限  
   - `clipboardWrite` と `host_permissions` の使用理由を明記  
   - リモートコードは不使用と明言  

---

## 🔧 トライ＆エラー

- **最初の試み**  
  Content Script 内で `copy` イベントをフックし、全文から Meet リンクを抽出して `clipboard.writeText()` → 何も変わらず全文コピーされた  
- **ChatGPT への質問**  
  「コピーした内容が変わらないです」  
- **返答**  
  ページコンテキストで `execCommand('copy')` を丸ごと乗っ取る注入方法に変更  
- **次の問題**  
  CSP（Content Security Policy）エラーが発生し、インラインスクリプトがブロックされた  
- **ChatGPT への質問**  
  「Refused to execute inline script because it violates CSP…」  
- **返答**  
  `injected.js` を外部ファイル化し、`web_accessible_resources` 経由でページに注入する方法  
- **追加の課題**  
  同じカレンダー内の別イベントの URL がコピーされてしまう  
- **ChatGPT への質問**  
  「別の URL がコピーされる…特定のダイアログ内だけから抽出するには？」  
- **返答**  
  `div[role="dialog"]` でダイアログを限定してその内部だけを検索  
- **最終的な課題**  
  コピーした URL に `?authuser=0&hs=…` が付与される  
- **ChatGPT への質問**  
  「パラメータがつくんだけどどう除去？」  
- **返答**  
  `new URL()` で `search` をクリアする or `split('?')[0]` でフォールバック削除  
- **結果**  
  ベースの Meet URL のみが確実にコピーできるようになった  

---

## 🎉 まとめ

- **ChatGPT o4-mini-high** の対話を活用し、要件定義から審査対応まで最速実装  
- CSP 回避、ページコンテキスト注入、ダイアログ限定抽出、クエリ除去など、現場で悩みがちなポイントもクリア  
---
ちなみに、この文章もChatGPTですw
JavaScript勉強ログ メソッドとグローバル関数の違い

メソッドとグローバル関数の違いって？
---
メソッド
→オブジェクトに属している関数
(オブジェクトに属しているというところがポイント)
obj.method()でアクセス。

「.(ドット記法)」でそのオブジェクトからアクセス、実行するもの。

```JavaScript
const dog = {
 name:'ポチ',
 bark:function(){
  console.log('ワンワンと鳴く')
 }
};

dog.bark();
//ワンワンと鳴く
```

dogはプロパティや関数の入ったオブジェクト。
barkはdogに属している関数=メソッド

consoleもMathなどと同じでJavaScriptの中に最初からあるオブジェクト。

consoleの中を見るといろいろなメソッドが用意されている。

console.log()は「.(ドット記法)」でオブジェクト(console)の中のlog関数にアクセスしている。
___
グローバル関数
→どこかのオブジェクトに属しているのではない単体の関数。js全体に最初から使える関数がたくさん用意されている。
function()でアクセス。
___

またメソッドとグローバル関数の違いとして「this」の扱いが変わる点がある。

(この「this」については筆者がまだ勉強していない範囲なので、学習を進めるにつれ更新出来ればと思います)
GitHubのリモートリポジトリに強制的にローカルのブランチを合わせる方法

最近、マージ作業をしているのですが、その際、ローカルブランチがリモートと

バージョンがまったくあわなくなっていて、git pullをしても同期できないことがありました。

その際、以下のコマンドで、強制的にローカルブランチをリモートブランチと合わせることで解決することができました。

git reset --hard origin/main

少し強引かもしれませんが、困ったときは、このコマンドで仕切り直ししてもいいかもしれません。

今日は、ここまで。

この他にも、以下のブログで、プログラミングについて記事を上げています。
https://yamachan228.seesaa.net/
学習記録　2025年4月23日

## ✅ 今日やったこと
### Railsアプリ開発
- 投稿一覧機能作成
- 投稿削除機能作成
- レイアウト修正
- 各機能のテストコードの作成

## 💡 気づき・学び
- コマンドを入力することでCRUD処理を簡単に実装することができる。

## 📝 明日の予定
- チームTodoアプリのデザイン修正
- ログイン機能実装

## 🕒 学習時間
- 2時間
Trae の最新アップデート：カスタム @Agent と MCP の統合

# Trae の最新アップデート：カスタム @Agent と MCP の統合

私たちは、Trae にいくつかのエキサイティングなアップデートを導入したことをお知らせできることを嬉しく思います。今回のアップデートでは、次の新機能を含んでいます：
![Agent-ezgif.com-optimize.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4069672/30c9a518-3673-4172-8bf3-f0b6c1036880.gif)


### 1. @Agent の導入

@Agent を使うことで、Trae はマルチエージェント機能をシームレスに統合しました。この新しいエージェントは、複数のエージェントを自由にカスタマイズできるため、開発者は自身のプロジェクトに合ったエージェントを作成し、より効率的な作業が可能になります。

![使用agent.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4069672/0036da3a-93b7-44ec-8d6d-ec8f6fb90c7d.gif)


### 2. MCP（モデルコンテキストプロトコル）の統合

MCPの導入により、Trae 内蔵エージェントとサードパーティツールの間でシームレスなデータ交換が可能となり、統一された作業フレームワークが提供されます。これにより、複雑なプロジェクトでも、異なるツール間での調整が自動化され、効率的な開発が進められます。
![MCP.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4069672/ffa04c30-11f9-4776-a0da-6b8c5dd6ab12.gif)

### 3. 拡張されたコンテキストサポート

新たに、#Web、#Doc、ルールのコンテキストが統合されました。これにより、開発者はWeb検索結果やドキュメントのように、プロジェクトに必要なあらゆる情報を即座に参照できるようになり、迅速な問題解決が可能になります。
![上下文gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4069672/f474aca0-4bee-4f27-8f82-8e58fca9a918.gif)


---

## 新機能の使い方

- **カスタム @Agent**  
  開発者は、自分だけのエージェントを作成し、特定のプロジェクト要件に合わせたツールを活用できます。例えば、Figma などのデザインエージェントや、Git などのコード管理エージェントを選択して、プロジェクトに最適な代理を作成できます

- **MCP の統合によるシームレスなツール連携**  
  MCP を使うことで、Trae と外部ツールとの連携が非常に簡単になります。MCP はツール間の調整を自動化し、プロジェクトの複雑さにかかわらず、作業を効率化します

- **強化されたコンテキストサポート**  
  #Web と #Doc のコンテキストサポートにより、開発者はプロジェクトに関連する情報を迅速に参照でき、問題解決にかかる時間を短縮できます。これにより、作業の精度と速度が向上します

## 次のステップ

これらの新機能を最大限に活用するために、今すぐ Trae をダウンロードして、無料で試してみてください！  
すぐに体験を始めましょう：[Trae 体験](https://www.trae.ai/?utm_source=content&utm_medium=qiita&utm_campagign=422)。
スライド一枚で最尤推定量の漸近正規性

# はじめに

最尤推定量の漸近正規性って講義で紹介されて「すげ～」となるのですが，証明が飛ばされがちな気がしています．

そこで，現代数理統計学の基礎に書かれてある内容をできるだけ視覚的にわかりやすくスライド一枚にまとめてみました．
要は，テイラーの定理の式を変形し，出てくる各項をうまく評価した，ということです．
いやー，うまい！

# 漸近正規性の証明
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115961/cd9382dd-bd4d-4784-828b-a62652d38ec3.png)
# 【Ruby学習記録】Day 2：Rubyの基礎を幅広く学習

# 【Ruby学習記録】Day 2：Rubyの基礎を幅広く学習

本日はRubyの文法について、基本的な概念から少し応用的な内容まで幅広く学びました。  
以下に学んだことを、関連性がある順に整理してまとめておきます。

---

## 1. 配列と要素

```ruby
fruits = ["apple", "banana", "orange"]
puts fruits[0]  # => apple
配列は複数のデータを一つにまとめて扱えるオブジェクトです。

[]で囲んで定義し、インデックス（0から始まる）で要素を取り出します。

2. 配列演算子

a = [1, 2, 3]
b = [3, 4, 5]

puts a + b  # => [1, 2, 3, 3, 4, 5]
puts a - b  # => [1, 2]
puts a & b  # => [3]
puts a | b  # => [1, 2, 3, 4, 5]
+：配列の結合

-：差集合（aにあってbにない要素）

&：積集合（共通要素）

|：和集合（重複を除いた全要素）

3. ハッシュとシンボル

person = { name: "Taro", age: 25 }
puts person[:name]  # => Taro
ハッシュはキーと値のペアでデータを管理します。

:name のようなキーは「シンボル」と呼ばれ、軽量な文字列のようなものです。

4. 比較演算子と論理演算子

x = 10
y = 5

puts x > y     # => true
puts x == y    # => false
puts x != y    # => true

puts x > 5 && y < 10  # => true
puts x < 5 || y < 10  # => true
比較演算子：==, !=, >, <, >=, <=

論理演算子：&&, ||, !

5. 条件分岐（if）

score = 80

if score >= 90
  puts "Excellent!"
elsif score >= 70
  puts "Good!"
else
  puts "Keep trying!"
end
条件によって処理を分けることができます。

6. ループ処理
timesメソッド

3.times do |i|
  puts "Hello #{i}"
end
eachメソッド

["a", "b", "c"].each do |item|
  puts item
end
7. メソッド定義・引数・戻り値・return文

def greet(name)
  return "Hello, #{name}!"
end

puts greet("Taro")  # => Hello, Taro!
def でメソッドを定義します。

return を使うことで戻り値を明示できます（省略可能）。

8. スコープ（変数の有効範囲）

message = "Hello"

def say
  local_message = "Hi"
  puts local_message
end

say
# puts local_message  # エラー（スコープ外）
メソッドの中で定義した変数はその外では使えません。

9. クラスとインスタンス（なぜ必要？）

class Dog
end

dog1 = Dog.new
dog2 = Dog.new
クラスはオブジェクトの設計図、インスタンスは実体。

同じ性質を持つオブジェクトを複数扱う時に便利。

10. 属性とインスタンス変数、initializeメソッド

class Dog
  def initialize(name, age)
    @name = name
    @age = age
  end

  def info
    "#{@name} is #{@age} years old"
  end
end

dog = Dog.new("Pochi", 3)
puts dog.info
@がついた変数は「インスタンス変数」と呼ばれ、クラス内でオブジェクトごとに保持されます。

initialize は new 実行時に呼ばれる特別なメソッド。

11. クラスメソッドとインスタンスメソッドの違い

class Tool
  def self.class_method
    "これはクラスメソッド"
  end

  def instance_method
    "これはインスタンスメソッド"
  end
end

puts Tool.class_method
tool = Tool.new
puts tool.instance_method
self. をつけるとクラスメソッド、それ以外はインスタンスメソッド。

12. ローカル変数とインスタンス変数の違い

def sample_method
  local_var = "ローカル変数"
  @instance_var = "インスタンス変数"
end
ローカル変数：そのスコープ内でのみ有効

インスタンス変数：オブジェクト内で共有される変数（@をつける）

今日のまとめ
Rubyの基本的な文法を一通り学びました。
特にオブジェクト指向の考え方（クラスやインスタンス）は少し難しかったですが、
「設計図と実体」というイメージで少しずつ理解できてきた気がします。
明日からはメソッドやクラスを組み合わせた実践的なコードにも挑戦していきます！
Slack 埋め込みURL 作成方法


このドキュメントは、「Markdownリンク」→「Slack埋め込みリンク」への変換方法・プログラミング実装例をまとめたものです。

---

## 1. Slackの埋め込みリンク形式

Slackでは `[テキスト](URL)` のMarkdown構文は使えません。  
代わりに、以下のような形式で記述します：

```
<URL|テキスト>
```

この形式で記述することで、「テキスト」がリンクとして表示されます。

---

## 2. Pythonによる自動変換例

```python
import re

def markdown_to_slack_link(text):
    """
    [テキスト](URL) → <URL|テキスト> に変換
    """
    return re.sub(r"\[([^\]]+)\]\(([^)]+)\)", lambda m: f"<{m.group(2).strip('<>')}|{m.group(1)}>", text)

# 例:
original = '[Document 0](https://www.notion.so/xxxx)'
converted = markdown_to_slack_link(original)
print(converted)  # <https://www.notion.so/xxxx|Document 0>
```

---

## 3. Slack APIでの利用例

Slack BoltやWeb APIを使ってメッセージを送信する際、  
`text` にそのまま `<URL|テキスト>` 形式を使えばOKです。

```python
client.chat_postMessage(
    channel=user_id,
    text=converted_text
)
```

また、Block Kitの `section` ブロック内で `mrkdwn` を使う場合も同様に利用できます。

---

## 4. まとめ

- Markdownの `[text](url)` はSlackでは使えない  
- `<url|text>` 形式に正規表現で変換すればOK  
- プレーンテキストでも `mrkdwn` でも有効  

Slackでリンクテキストを使いたい場合は、この変換を活用しましょう！

---
新卒エンジニアの学習記録＃１~データベースの基本構成とER図~

こんにちは、新卒エンジニアとして学び始めている DeepBlend45 です。

今回は「データベースの基本構成とER図」について学習した内容を、自分なりに振り返ってまとめてみました。

---

### 🗂 データベースの基本構成について学んだこと

- データの検索や更新は SQL などを用いて操作される
- 同時実行制御（トランザクション）により、複数ユーザーの操作でも整合性が保たれる
- 障害復旧機能やアクセス制御により、安全に情報を扱えるようになっている

---

### 📘 ER図の学習で感じたこと

- **エンティティ**：管理対象となる「モノやコト」
- **アトリビュート**：エンティティが持つ「情報項目」
- **主キー**：エンティティを一意に識別するためのキー

ER図を自分で作成するのはまだ慣れていないため、  
「これはエンティティ？ それともアトリビュート？」と悩む場面が多くありました。

すでに作成されたER図を読むのはある程度できるのですが、  
ゼロから構造を考えるのはやはり難しく感じます。

![ER図のイメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4069042/bdf09c5d-7df8-4673-9375-189ee524b68a.png)

---

### 🔭 今後に向けて

ER図作成では、文章中の**名詞に注目して管理対象を洗い出す**というアプローチを意識してみようと思います。

また、主キーの選び方や正規化の考え方も、今後の課題として継続的に学んでいきます。

---

### 📝 まとめ

データベースの基本構成やER図を学ぶことで、  
今後システム開発に関わる際の「データの設計力」の重要性を実感しました。

これからも、自分の学びやつまづきをこうして記事に残しながら、少しずつ成長していきたいです。

同じように学習を始めたばかりのエンジニアの方と、一緒に前に進んでいけたらうれしいです！

---

**#新卒エンジニアの学習記録**
ABC390~399の振り返り集

ABC390からABC399までの振り返りへのリンク集です(次のまとめ記事が出るまでピックアップにしておきます)
[ABC390](https://qiita.com/friedrice/items/06a9cc23bd45cdc0ace5)
[ABC391](https://qiita.com/friedrice/items/4aef733a91c493e24b01)
[ABC392](https://qiita.com/friedrice/items/299c080a3d0448adc2d0)
[ABC393](https://qiita.com/friedrice/items/168e446640088b3fb4d3)
[ABC394](https://qiita.com/friedrice/items/a9e41b13333609d18c61)
[ABC395](https://qiita.com/friedrice/items/3191de0961b05611b4e0)
[ABC396](https://qiita.com/friedrice/items/9167e61d09cbc6ac7912)
[ABC397](https://qiita.com/friedrice/items/2c7762adcc79ec6d56a3)
[ABC398](https://qiita.com/friedrice/items/970f7630cafbd4e65f24)
[ABC399](https://qiita.com/friedrice/items/2ba62b95299932705d99)
yamlを使って履歴書作成

# はじめに
転職活動をしており、履歴書を作成する機会が多いです。ただ、履歴書の作成って面倒ではないですか？社用PCではないので、office系のアプリケーションは使えないですし。。。
そこで、yaml形式で内容を記載すれば、自動で履歴書を生成してくれる方法を探しましたので、備忘録がてら紹介します。

# 実行手順
履歴書を作成したいディレクトリを作成します。
今回は、/users/username/jobというディレクトリを作成します。
```
mkdir ~/job
```

次に、[yaml_cv](https://github.com/ikasam/yaml_cv)というリポジトリをクローンします。
```
cd ~/job
git clone https://github.com/ikasam/yaml_cv.git
cd yaml_cv
```

必要モジュールのインストールを行います。
```
bundle config path vendor/bundle
bundle config set --local without 'documentation'
bundle install
```

以下コマンドで履歴書を作成します。
```
ruby make_cv.rb -i data.yaml -s style.txt -o output.pdf
```

このコマンドで、data.yamlというファリをstyle.txtに倣い、output.pdfという形式で出力します。

以上。



# 参考
[YAMLで履歴書を作る](https://qiita.com/kaityo256/items/e3884d0109223c324baf)
GL.iNet の Mango (GL-MT300N-V2) を OpenWrt 化した時のメモ


実家に帰った時に『TV に "Wi-Fi で接続しました" みたいな表示が出るので邪魔』だと言われたので Mango を無線 LAN コンバーター代わりにした。
この時無駄に OpenWrt 化したのだけど非常に簡単にできた。(尚、TV に有線で接続しても『有線で接続しました』と出るだけだったようなので実質意味はなかったようだ。)
参考にした情報が 2020 年頃の情報が多く、現在だと多少違っている部分があるのでまとめた。

# 購入直後の Mango の確認

- WAN 側ポートに上流のルーターに繋がっているケーブルを挿します (多分ここ大事, 上流に DHCP サーバーがいないと LAN 側に接続した設定用 PC の IP アドレスが決まらずに接続できないんじゃないかなと思う)。
- LAN 側ポートに設定用 PCに繋がっているケーブルを挿します。
- Mango の電源を入れます。
- 設定用 PC でブラウザを開き, 192.168.8.1 に接続します。
- 管理者パスワードの設定ページでパスワードを設定します。

また、管理ページでまずは無線 LAN をオフにしたほうがいいです。
最初からオンになっていて誰でも接続できる状態です。


# まずは試しに Mango の公式ファームウェアを書き込んでみる。

管理ページの "Advanced" -> "System" -> "Backup / Flash Firmware" でファームウェアの書き換えを行います。

Mango の公式のファームウェアは以下のページからダウンロードします。

https://dl.gl-inet.com/router/mt300n-v2/stable

https://fw.gl-inet.com/firmware/mt300n-v2/release4/openwrt-mt300n-v2-4.3.18-0823-1724399860.bin
のようなファイルです。

"Flash image..." を押下するとアップロードと検証が始まります。
検証結果を確認し、"Proceed" を押下で書き込みが始まります。

そのまましばらく待つと書き込みが完了するはずです。


# OpenWrt のファームウェアを書き込む

Mango の公式のファームウェアを書き込むのと同様の手順で OpenWrt のファームウェアも書き込むことができます。

まずは OpenWrt の公式サイトでの Mango の情報ページを確認しておきます。

https://openwrt.org/toh/gl.inet/gl-mt300n_v2

https://openwrt.org/toh/hwdata/gl.inet/gl.inet_gl-mt300n_v2

OpenWrt 化で使用するファームウェアは OpenWrt の [Firmware Selector](https://firmware-selector.openwrt.org/) で "GL-MT300N" と入力して検索します。

https://firmware-selector.openwrt.org/

尚、ファームウェアは OpenWrt の公式サイトの ["Downloads"](https://openwrt.org/downloads) の ["Stable Release builds"](https://downloads.openwrt.org/releases/) のような表記の所から探す事もでき、以下のような URL になります。

https://downloads.openwrt.org/releases/19.07.5/targets/ramips/mt76x8/openwrt-19.07.5-ramips-mt76x8-gl-mt300n-v2-squashfs-sysupgrade.bin
https://downloads.openwrt.org/releases/24.10.1/targets/ramips/mt76x8/openwrt-24.10.1-ramips-mt76x8-glinet_gl-mt300n-v2-initramfs-kernel.bin
https://downloads.openwrt.org/releases/24.10.1/targets/ramips/mt76x8/openwrt-24.10.1-ramips-mt76x8-glinet_gl-mt300n-v2-squashfs-sysupgrade.bin

OpenWrt 化が完了した後は LAN 側アドレスは Mango 標準の 192.168.8.1 ではなく, OpenWrt 標準の 192.168.1.1 になります。
接続する時は気を付けて下さい。

Mango 公式のファームウェアに戻したければ本体のリセットボタンを使ってファクトリーリセットで戻せるようです。



# OpenWrt 化した直後のアクセス方法

ブラウザでアクセスする場合は
http://192.168.1.1

SSH 接続する場合は
$ ssh root@192.168.1.1

いずれの場合も最初はパスワードは設定されていない。
ユーザー名は root で, ブラウザの場合はパスワードは何を入れても通る, SSH 接続の場合はパスワードは聞かれない。

最初は 無線 LAN は無効状態になっているので有効化しない限り有線接続しかできない。



# その後は
SSH 接続して opkg でパッケージなどを入れるとちゃんと OpenWrt を使ってる気分になれるはず。詳しくは <del>Web で</del> opkg -h でヘルプがみれます。



# 参考ページ各種

https://tomono.tokyo/2020/12/16/8999/

https://hgot07.hatenablog.com/entry/2020/12/13/092555

https://qiita.com/Bacalhau/items/161a16e9c7f4eaa572b0
ドメイン駆動設計を学ぶにあたり有効だったもの

# はじめに
この記事では、自分がドメイン駆動設計について学ぶにあたり、より理解が深まった本、記事を紹介します。

世の中には様々なシステムがありますが、特に設計手法やアーキテクチャが考慮されずに、混沌となっているコードが大量にありますね。自分が関わっていたシステムもそうでした。

ドメイン駆動設計（Domain Driven Design / DDD）はそういったコードを生み出さないための設計手法です。
また、世の中では、まぁまぁの年次になっていてもこれを理解できていない層がそれなりにいます。
（最も、自分もわからないことだらけではあります。）
そのため、DDDを学ぶことで、今のプロジェクトでリードできるような責務を得られるかもしれませんし、より良い企業へ転職するための武器の一つとなるかもしれません。

今、読者の皆さんがDDDを学ぶことを選んだことは決して間違いではありません。




# 対象読者（マインド的な意味合いが強い）
対象読者層は以下ですが、これは当時の自分がどういう状態だったかも示しています。

- 業務コードを書いていて、キモいということはわかっているが、その言語化をうまくできない方
- コーディングの前段となる設計について、体系的に理解できていなくてモヤモヤする方


# 前提となるスキル
- Webアプリケーション開発における設計・製造工程の経験
    - 設計は、ウォーターフォールで言うところの基本設計・詳細設計を指す
    - また、非機能に関わる設計経験は不問
- オブジェクト指向の理解（入門書1冊読んだ経験程度）

# 本記事、および該当書籍・記事を読んだ後の効果
- コーディングをする前段の設計で、どのような手法があるかを理解できる
- 上記の設計を踏まえて、それをどのように実装に落とし込めるかを理解できる
- コーディングをする上での頻出となる実践的なパターンを理解できる（DDDとしての）
- DDDとアーキテクチャの関係性を理解し、ある程度0→1でコーディングの決まりを作れるようになる（どういう層があり、どういう役割で、どういう実装をすればいいかがわかる）

# ドメイン駆動設計とは
実際の業務要件や問題点を的確に捉え、それを効果的に解決するためのシステムを構築する必要があります。
この業務要件の核心を深く理解し、それをシステムに反映するためのアプローチが、ドメイン駆動設計（DDD）です。
改めてですが、私がDDDを学ぶ上で、どのような書籍や資料を、どのような順番で読んだかを以下に示します。
また、著者自身も日夜DDDを学んでいる者であるため、この記事は常にアップデートが見込まれます。


# おすすめの書籍・記事
### 1. ドメイン駆動設計入門 ボトムアップでわかる！ドメイン駆動設計の基本

https://www.shoeisha.co.jp/book/detail/9784798151687

**【概要】**
設計というよりは、コーディングの観点でより実践しやすいパターンを説明してくれています。

**【効果】**
モデリングの観点等の言及はありませんが、オブジェクト指向がわかるくらいのスキルを持つ方であれば、この本をご一読するだけで、業務コードを大きく改善できるはずです。


### 2. 【DDD入門】TypeScript × ドメイン駆動設計ハンズオン
https://zenn.dev/yamachan0625/books/ddd-hands-on

**【概要】**
DDDの戦略的設計（ドメインモデリング）についても解説している記事です。

**【効果】**
1の書籍よりも前段階（コードを書く前）で、どのようなことをしなければいけないかを理解できるようになります。

また、戦術的設計（コード実装）の各章では、1の書籍で言及している各パターンと同様のことを説明していますので、理解をより定着させるための練習にもなります。


### 3. なるセミ イベントストーミング入門【ノーカット版】
https://www.youtube.com/watch?v=jC9lE4YqgyY&t=1195s

**【概要】**
イベントストーミングのやり方について解説している動画です。
2の記事ではイベントストーミングについての言及がさらっとしていた（筆者はそう感じていますが、コンテキストを読み解く力が欠けているだけかもしれません。）ため、よりイベントストーミングの理解を深めるための学習が必要だと感じ、こちらにたどりつきました。

**【効果】**

記事等だと、出来上がっているもの（あるいはその過程の切り取り）についてのみの言及になり、どういう思考プロセスのもと、イベントストーミングが行われているかの理解が不十分でした。
こちらの動画を通し、どのような思考プロセスでイベントストーミングをしているかを理解できました。
また、1の著者でもある**成瀬 允宣**さんが投稿されているものですので、信頼度があります。


# おわりに
業務要件をシステムへ反映するために苦悩していた自分にとって、DDDとの出会いは形容しがたい感動を覚えました。
この記事が、ソフトウェア開発を学ぶ全ての方々の一助となれば幸いです。
簡単な仕様だけ書いて、特許出願まで全部ChatGPTにやらせた話

この記事はChatGPTが記載してるの

AIが記述しているので、若干現実と異なることがあるの


「AIが人間の仕事を奪う」とか言われて久しいけど、まさか自分がそれを“利用する側”になるとは思ってなかった。今回は、ほぼChatGPTだけで特許出願までこぎつけた実体験を、ちょっと笑いも交えつつ書いてみる。

前提として、使ったのは無料プランのChatGPT。ProでもGPT-4oでもなく、いわゆる“GPT-4 mini”。たまにGPT-4oが使えるが。

そして私が用意したのは、アイディアとざっくりした仕様だけ。コードも設計も、全部ChatGPTに任せた。しかも、かなりケンカした（笑）

# 1. はじまりは「こんなことできたらいいな」から
ある日ふと思った。「女の子の写真の取り扱い、不安だわ」と。

当時は泣く泣く利用規約で制限した。

もちろん自分は法律家でもないし、特許に詳しい技術者ってわけでもない。ただ、技術アイディアにはちょっと自信があった。

そこでまず、仕様をテキストでざっくりまとめた。ほんとに箇条書きレベル。

<ul>
<li>ユーザーの操作を検知する</li>
<li>特定条件でログを取る</li>
<li>HTMLの中身のほとんどをユーザーが直接見れないようにする</li>
<li>view-sourceのイベントを検知する</li>
<li>画像URLを暗号化する</li>
</ul>
<blockquote>
一部の挙動は自動で削除 or 遷移
</blockquote>

この程度。あとは「こういう技術的制約がある」「ここは高速で動かしたい」などの希望を書き添えただけ。

# 2. 「ChatGPT、コード書いて」と言ってみた
そしてChatGPTにこう言った。

この仕様でプログラム組んで

すると、HTML、JavaScript、PHP、WordPressのプラグイン構成に至るまで、驚くほどそれっぽいコードが返ってきた。
正直、最初は「ほんとかよ」と思いながらコピペして試してみた。でも、意外と動くんだこれが。

もちろん、最初から完璧じゃなかった。たとえばイベント検知のタイミングがずれてたり、条件分岐が雑だったり、セキュリティ的にNGな構文が混じってたり。

で、何度も何度もChatGPTとやり取りすることに。

# 3. ケンカしながら仕様を詰める日々
ChatGPTとのやり取りは、一種のディベートだった。

「それじゃ遅延が出る」「そのAPI、ブラウザによって動作違うから無理」
「この書き方はサーバー負荷が高い」「それじゃ目的達成できない」

…こういう文句をぶつけまくってたら、ChatGPTもたまに意味不明な返しをしてくる。
「それはごもっともですが、私には判断できません」みたいな（笑）

でも根気強く「こう直して」「もっと高速化して」「条件をこう変更して」と伝え続けていくと、だんだん精度が上がってきた。
いつの間にか、自分よりもその仕様に詳しい“技術者”が一人いるような気さえしてくる。

# 4. コードが完成。そして…
最終的にできあがったのは、Webブラウザ上で特定の条件を検知し、自動的に処理を切り替えるシステム。
いくつかのHTML保護の技術を組み合わせて、ユーザー体験を損なわず、かつ情報漏洩を防ぐしくみになっていた。

「これは出せる」と思った。

そこで次に考えたのが、特許出願。

# 5. 特許の書類も、自分でまとめた
実は、特許事務所は使っていない。
ChatGPTに手伝ってもらいながら、自力で出願書類をまとめた。

まず、どういう形式で書けばいいのかをChatGPTに聞いてみた。
「特許明細書の書き方は？」「請求項ってどう書くの？」「図面って必要？」といった質問をすると、それなりに実用的なテンプレートや文例を返してくれる。

もちろん、そのままでは足りない部分も多くて、何度も修正と確認を繰り返したけど、構成の骨組みは全部ChatGPTに相談しながら組み立てた。

出願に使ったフォーマットや文体も、それっぽく整えてくれて、「これで通るんじゃないか？」という感触まで持てる仕上がりに。

もちろん最終的には、自分で特許庁の提出サイトから申請した。
専門家じゃないけど、“AIと一緒ならなんとかなる”という感覚があった。

# 6. このブログにもその技術、入ってます
ちなみに、今読んでるこのブログの裏側にも、その特許技術の一部が無意味にも組み込まれている。

たとえば、「HTMLの中身を直接見られないようにする」とか、「ログを取ってユーザー挙動を記録する」とか。
「とあるキーの挙動で」警告を出す。

ここには書かないけど、特定の条件で自動的に挙動を変えるしくみも動いている。

たぶん、気づかないうちに“それ”が動いてるはず。

https://blog.773.moe/

# 7. 無料プランでもここまでできる
驚かれるかもしれないけど、使ったのは無料のChatGPTだけ。GPT-4oじゃない。しかも、当時はブラウザから直接叩いてただけ。たまにGPT-4oは使えるけど、限られたことしか使えない。

それでも、仕様をちゃんと伝え、フィードバックを積み重ねれば、ここまでできるというのは大きな収穫だった。

# まとめ：AIとケンカしながら作る未来
ChatGPTと一緒に開発したことで、コードの完成スピードは圧倒的に早かった。
でも、それ以上に驚いたのは「思考の補助」にもなったこと。

自分の頭の中だけでは気づけなかった視点、コードの書き方、セキュリティ的な穴、全部ChatGPTとの会話から得た。

もちろん、AIは万能じゃない。雑なコードも書くし、時にはウソもつく。だからこそ、**「AIを使いこなす側の技術」**がこれからますます重要になると思う。

そして一つ、声を大にして言いたい。

「<strong>無料のChatGPTだけでも、特許、取れるぞ</strong>」

# 補足
JavaScriptのgoogle Closure Compiler 用の最適化コードだけあたしが手動でしたの packerもかつて使ったことあるが、このあたりの技術は手動でやったほうのが、遥かに効率的だったの

# AI生成に対する正誤表

特許庁の提出サイト → そんなものはない、出願アプリ
【応用情報技術者試験】末尾に「マネジメント」とつくワードまとめ

# 概要
応用情報技術者試験にでてくる〇〇マネジメントという名前のワードをまとめました。
マネジメントは「経営」や「管理」という意味です。

# 目次
- [カテゴリマネジメント](#カテゴリマネジメント)
- [コストマネジメント](#コストマネジメント)
- [コミュニケーションマネジメント](#コミュニケーションマネジメント)
- [サービスマネジメント](#サービスマネジメント)
- [事業ポートフォリオマネジメント](#事業ポートフォリオマネジメント)
- [ステークホルダーマネジメント](#ステークホルダーマネジメント)
- [タイムマネジメント](#タイムマネジメント)
- [統合マネジメント](#統合マネジメント)
- [ファシリティマネジメント](#ファシリティマネジメント)
- [プロジェクトマネジメント](#プロジェクトマネジメント)
- [リスクマネジメント](#リスクマネジメント)

# カテゴリマネジメント
小売業界において、商品のカテゴリーごとに経営や管理の戦略をたてる手法のこと。
例えば企業の様々な商品を、健康食品、日用品、化粧品、医薬品などのカテゴリに分類し、それぞれのカテゴリごとに顧客層や競合状況、トレンドなどを分析して戦略を立てていく方法のことを指す。

# コストマネジメント
企業の資源をなるべく効率的に活用して、利益を最大化するための手法のこと。
例えば、承認された予算の中でなるべく利益を最大化できる状態でプロジェクトや業務を完了させるようなこと。
具体的な手法としては、[損益分岐点分析](https://ja.wikipedia.org/wiki/%E6%90%8D%E7%9B%8A%E5%88%86%E5%B2%90%E7%82%B9)や[ABC分析](https://ja.wikipedia.org/wiki/ABC%E5%88%86%E6%9E%90)などがある。

# コミュニケーションマネジメント
顧客などのステークホルダーとの間において、情報交換を円滑に実施するための手法のこと。PMBOKでは、プロジェクト管理におけるコミュニケーションマネジメントのプロセスを以下の3つに分類している。
1. コミュニケーションマネジメントの計画
   - 誰がどういった情報を必要としていて、どのように伝えるかを決定する
1. コミュニケーションのマネジメント
   - 計画に基づいて情報を収集して共有する
1. コミュニケーションの監視
   - 関係者からフィードバックをもらい、必要に応じてコミュニケーション計画を調整して改善する

# サービスマネジメント
企業が提供するサービスの質を管理して、顧客の満足度を高めるための手法のこと。
サービスマネジメントは以下の4つの特性がある。
- 無形性
  - サービスには形がない。そのため、具体的な事例や評価を通じて可視化する必要がある
- 消滅性
  - サービスは提供と同時に消費される。そのため、在庫のような形として蓄積することはできない
- 同時性
  - サービスの提供と消費は同時に行われる。そのため、サービスの提供者とサービスの受け手が同じ場所にいる必要がある
- 変動性
  - サービスの質はサービスの提供者や状況によって変わる。そのため、一定の品質を保つためには工夫が必要

# 事業ポートフォリオマネジメント
複数の事業を展開する企業において、企業が複数の事業を戦略的に管理して経営資源を効率的に配分することで企業価値を最大化する手法のこと。
[SWOT分析](https://ja.wikipedia.org/wiki/SWOT%E5%88%86%E6%9E%90)や[CFT分析](https://library.musubu.in/articles/19686)が有効。

# ステークホルダーマネジメント
プロジェクトや企業活動において、利害関係者 (ステークホルダー) を特定して、彼らの期待や影響などを管理する手法のこと。
主にステークホルダーと良好な関係を構築してプロジェクトを円滑に進めたり、ステークホルダーの意見や影響を把握してプロジェクトの潜在的なリスクを早期に発見するような目的がある。

# タイムマネジメント
達成すべき目標を効率的に進めるため、時間を有効活用するための手法のこと。
簡単に言うと「時間管理」のことで、一般的に色々なビジネスシーンでこのスキルが求められる。
例えばプロジェクトの締め切りを守るための進め方の工夫や、学生の試験勉強や宿題の進め方を効率的に行えるよう工夫することもタイムマネジメントのひとつ。

# 統合マネジメント
プロジェクトの達成のため、プロジェクト全体を調整して各プロセスや要素を統合し、管理する手法のこと。
例えばひとつのプロジェクトでも「コスト管理」「リスク管理」など、様々なことを管理する必要がある。これをバラバラに管理するのではなく、管理するものを連携させてプロジェクト全体を良い方向に進めるようにすることを指す。

# ファシリティマネジメント
企業や団体が所有している施設や環境を総合的かつ経営的な視点から企画、管理、活用すること。
例えば企業が所有している施設や環境を見直して、コストをなるべく抑え、設備の仕様効果を高めるような行動のこと。

# プロジェクトマネジメント
プロジェクトの目標を達成するために、計画や実行、監視などを管理すること。
簡単に言うと、プロジェクトを成功させるために様々なことを管理することを指す。

# リスクマネジメント
企業活動やプロジェクトにおいて、発生する可能性があるリスクをあらかじめ特定し、評価して対策を講じておくこと。リスクを最小限に抑えて目標達成を促す効果がある。
例えばIT関連のプロジェクトでは、技術的な問題やセキュリティリスクなどを管理することが重要になる。他の例だと、建設関連のプロジェクトでは天候の変化や資材の遅延などのリスクを事前に特定しておき、対策を講じておくことがリスクマネジメントになる。

***
**[記載した応用情報技術者試験の記事まとめ](https://qiita.com/MetroOsamu/items/550001240d76e24f505f)**
【完全ガイド】Claude DesktopからDatabuttonのMCP APIを呼び出す4ステップ

## 📘 概要

「コードが書けなくてもAI APIが作れる！」

本記事では、非エンジニアでも可能な **Claude Desktop × Databutton の連携方法** をご紹介します。

わずか4ステップで、プロンプトからAPIを作成し、AIエージェントとしてClaude DesktopからMCP呼び出しできる仕組みを構築できます。

---

## 🔧 使用サービス

- [Databutton](https://databutton.com?via=takahiro19)：ノーコードAIアプリ構築プラットフォーム  
- Claude Desktop（Anthropic社の強力なAIクライアント）

---

## ✅ ステップ1：Databuttonにプロンプトを書く

Databuttonで新規アプリを作成し、以下のような**プロンプト**を入力するだけで、AIがAPIを自動生成してくれます。

名前を受け取って、挨拶文 ‘hey! {名前}!’ を返すAPIを作って

> コードは一切不要です。Databuttonが自動でFastAPIベースのコードを生成し、UIに表示してくれます。

---

## ✅ ステップ2：MCP化する（ボタンを押すだけ）

Databuttonでは、APIをMCP（Model Context Protocol）形式で呼び出せるようにする機能があります。

- **「Enable MCP」** ボタンを1クリックで完了！  
- MCPとは：AI同士がやり取りするための共通プロトコルです。

---

## ✅ ステップ3：Deployボタンを押すだけ

- 「**Deploy**」ボタンを押すだけで、MCP対応のAPIサーバーがクラウド上に公開されます。
- エンドポイントが自動で生成され、URL付きで表示されます。

---

## ✅ ステップ4：Claude Desktopから呼び出す

Claude Desktop に以下のような **自然言語プロンプト** を入力するだけで、MCP経由でDatabuttonのAPIが呼び出されます。

MCPで次のAPIを呼び出してください：

task: greet
input:
name: Takahiro

ClaudeがDatabuttonのMCPエンドポイントにアクセスし、APIからの返答を表示してくれます。

---

## 🌐 関連リンク

- 🔗 [Databutton公式サイト](https://databutton.com?via=takahiro19)
- 🔗 [MCP開発ガイド（Databutton公式）](https://docs.databutton.com/databutton-mcp-build-tools-for-ai)
- 🔗 Claude Desktop: [https://www.anthropic.com](https://www.anthropic.com)

---

## 💡 おわりに

非エンジニアでも「プロンプトを書く → ボタンを押す」だけでAI APIを構築し、MCP経由でLLMから呼び出せる時代になりました。

ぜひこの4ステップを試して、AI開発を一気に加速させましょう！
Microsoft EdgeだけWebPushが飛ばない時は

WebPushの実装をしていると、鍵を作り直したり色々試すも401エラーでうまく飛ばさずにいました。  
元々Edgeで動作確認をしていたのですが、Chromeだと問題なく動作するため、  
AzureのWNSの権限を取ってみるなど試したのですが、WNSも関係なさそうでした。
その後、なんとTTLを設定したところ、無事EdgeでもWebPushを受け取ることができました。
WebPushを実装する際は、TTLを忘れずに設定するようにしましょう。