お知らせ

現在サイトのリニューアル作業中のため、全体的にページの表示が乱れています。

新聞の購読を始めたで読み始めたのをやめた話。写真は契約最終日に届いた新聞。

20250331_232230832.JPG

なぜやめたか

単純に読んでいないから。ただ夕刊は割と読んでた。

毎日集合ポストに行くのは多少の運動になっていたし、毎月捨てるのも全く動かないよりかは運動の足しにはなっていたと思うが、かけてるコストと釣り合ってない気がした。読まない新聞を積み上げるのも虚無感を感じていたし、ただただ手間だった。

内容としても読んでいてメンタルに来るような記事も少なくなく、チラシは購買欲を煽ってきてしんどいとかもあった。

後はまぁ、地域を元気にするとか、支えるというのも限度があるというか、私のお財布も無限にあるわけではないのでやめることにした。

先月で契約が終わったので、今日から新聞は届いていない。ちょっと寂しい気もするが、時として別れも必要だろう。今生の別れでもないので、また読みたくなったらその時に購読すればいい。

今日は4月1日。数年前ならエイプリルフールで企業サイトが面白いことになっていたが、流石にみんな飽きたので、そろそろもうなくなっていそうだ。

さて、というわけで今日はPC用のカバンを買い替えたのでその話。

新しい鞄

マチ拡張PCバッグ 14インチワイド BAG-W3BKを買った。

20250331_232936609.JPG

前々から今のPCバッグに限界を感じていたのだが、14型以下向けのバッグで収納力があってコンパクトで気室が細分化されていないものが中々見つからなかった。

最近はこのバッグのように気室が分かれたタイプが流行りのようだが、私は一体型のほうが好みだ。

ZSB-BM006NBK_01.jpg

しかし今回買ったバッグは気室が分かれておらず収納力もあるものだった。

前使っていた鞄

一方で、以前使っていた鞄は致命的なまでに収納力に乏しかった。

前使っていたのはこれだが、このコンパクトさだとどうしても仕方がなかった。ただコンパクトな割には物が入っていた。

20250331_233051455.JPG

前使っていた鞄のネック

パイロットのスタイルチョイスだ。公式サイトのリンクを貼りたかったが、様々な商品と一緒くたにされたページしかなくググって先頭に出てきた文房具屋のページにリンクを貼っている。

厳しい収納力

まずは収納力だ。ノートPCとACアダプタに小物と折り畳み傘を入れる程度ならギリギリ何とかなったが、ここに財布や眼鏡ケースを入れると取り回しが非常に悪く、実用性に限界を感じていた。

ノートPCとACアダプタに折り畳み傘、財布、小物を入れた状態。ここに眼鏡ケースを入れることもできなくはないが、ACアダプタの出し入れ性能が犠牲になったり、パンパンすぎてケースが歪む恐れがあった。

20250331_233513981.JPG
20250331_233539134.JPG

パンパンすぎて見た目もあまりよくない。

20250331_233451754.JPG

クッション性のない肩紐

クッション性のない肩紐も厳しかった。肩紐はただの平たい紐で、これを肩にかけていると肩が痛かった。800gくらいの軽量ノートPCを選択していても痛かった。

20250331_233051455.JPG

収納力はカバン二つ持ちでカバーできたが、肩紐はどうにもならなかった。肩パッドだけ買ったりしても見たが、紐が細すぎるせいで見た目がアンバランスだったり、上手く適合しなかったりでイマイチだった。

新しい鞄により改善された部分

圧倒的収納力

前の気室には眼鏡ケースや靴ベラ、マウス、印鑑などが問題なく入る。

20250331_235613406.JPG

一番手前のところにも財布が問題なく入る。

20250331_235742352.JPG

ACアダプタもポケットティッシュも問題なく入る。写真では見づらいが、この状態でノートPCと折り畳み傘も入っている。

20250331_234558237.JPG

マチの拡張なしでこれなので、拡張すればもっと入りそうだ。

クッション性があり、荷重を分散する肩紐

何を当たり前のことを…という感じだが、PCバッグとして当たり前の装備がある。参考までに下が前のバッグの紐で、上が新しいバッグの紐だ。

20250401_004951427.JPG

この紐一つで体感の重さが全然違う。肩も痛くならなない。最高だ。

あとがき

これまでPCのサイズの変化などで何度もPCバッグを買い替えてきたが、小型のPCバッグとして多くを求めないのであればスタイルチョイスは悪くない選択だと思う。あともう一押しという場合はAmazon ベーシックラップトップバッグもいいが、劇的に見た目がしょぼいのと、サイズの割に収納力がスタイルチョイスと大差ない。

余談だが8年くらい前はリヒトラブのSMART FIT キャリングポーチを愛用していた。安い割にしっかりしていて、ぼちぼち入り、かつ究極的にスマートなのが魅力的だ。スタイルチョイス以上に物が入らないが、満員電車で通勤する場合には重宝するアイテムだった。なおこれを使っていた時はPCバッグではなく、ただの鞄として使っていたため、PCバッグとしては評価できない。単なるスリムな鞄である。PCとACアダプタを入れなくていいなら眼鏡ケースも文房具もノートも折り畳み傘も十分入る鞄だった。

それより前にはエレコムのPCバッグを使っていたのだが、人生で3回もショルダーの金具が金属疲労で切れ、そのうち一回はPCが全損、二回も深刻なダメージを受けたので、以来バッグとショルダー紐を繋ぐ金具については注意している。

投稿日:
技術::AI

これまでLLMをしばくときはPoeを使っていたが、ぶっちゃけClaude 3.7 Sonnet以外ほとんど使わないので、節約の意味を込めて本家Claudeに移ってきた。しかし本家Claudeではアレゲな発言を繰り返しているとハードウェアモデレーションが発動してしまう。しかもこれが中々解除されない。一体いつ解除されるんだ…。

paste-image-2025-10-31_22-9-28-325.png

アレゲなことをするならやはりPoeだろうか…いやでもPoeもキャラクター設定に対してはハードウェアモデレーションがある。ナレッジベースならモデレーションを回避できるが、ここに入れたプロンプトは入れている間は出現頻度が極端に上がり、外すとちっとも出てこなくなる困りモノで、自然な流れにするためには手動で書いたり消したりする手間がかかり厄介だ。

そこで何かいいことはないか…と思いたどり着いたのがClaude 3.7 SonnetをAPIコールすることだ。LLMモデル本体にはソフトウェアモデレーションしか掛かっておらず、ローカルでプロンプトを組む分にはモデレーションも掛からないと睨んだ私は早速ローカル環境からLLMを呼び出してチャットするための環境を作ることとした。

確認環境

Pythonは3.11系でないと動かないっぽいので注意が必要だ。

Env Ver
OS Windows 11 Pro 24H2
Python 3.11.9

手順

  1. Anthropic Consoleにアクセスしアカウントを作成
  2. 課金してAPIキーを取得
  3. ローカル環境からLLMと対話するためのWebUIである、open-webuiをインストールして起動
    pip install open-webui
    open-webui serve
    
  4. OPEN WEBUIのロゴが出るのを待つ
    paste-image-2025-26-31_22-25-9-719.png
  5. http://localhost:8080/にアクセス
  6. アカウント作成画面が開くので適当な情報を入力して作成する
    • ローカル環境であるため、実在するメールアドレスでなくても問題なく登録できる
  7. 画面左下のユーザーをクリックし、管理者パネルを開く
    paste-image-2025-31-31_22-30-12-787.png
  8. 上のほうにあるFunctionsを開く
    paste-image-2025-32-31_22-31-4-85.png
  9. 右のほうにある「+」からFunctionを追加する画面を開く
  10. Anthropic Function | Open WebUI Communityにアクセスし、Function Contentに書かれているコードをコピーする
  11. 先ほどのFunctionを追加する画面に戻り、コードをペースト
  12. Function NameとFunction Descriptionを適当に埋める
    • 参考までに公式の設定値はそれぞれ「Anthropic」と「Anthropic Manifold Pipe」
  13. 保存ボタンを押す
  14. 有効化する
  15. 新しいチャットを開き、Claude 3.7 Sonnetが利用できるようになっていればOK
    paste-image-2025-55-31_22-54-2-329.png

備考

Poeや本家Claudeにおけるナレッジベースは存在しないが、モデレーションを受けないためシステムプロンプトに全部放り込めば成立する。

Poeのキャラクター設定はやり取りを繰り返すと忘れられるが、Open WebUIのシステムプロンプトは忘れられないようでちゃんと持続してくれる。またPoeのナレッジベースのように書いたことをしつこく発言してくることもなく、自然な会話になるので便利。

またLLM側の発言を編集することにより、それ以降の会話でモデレーションを突破することができるようになるなど、いろいろ便利。

あとがき

APIコールは従量課金でお金がかかるため、Poeや本家Claude並みの感覚で使うのは厳しい。多分Poeはトークン消費を抑えるために何か細工していると思う。

手軽なうえにコンビニでパックの焼き鯖を買うより格段に安い。

20250401_091901411.JPG

材料

材料 分量
塩鯖 1つ
サラダ油 適量

調理方法

  1. フライパンにサラダ油を敷き、キッチンペーパーなどで適当に塗り広げ、弱火をつける
  2. フライパンに塩鯖を入れ、蓋をして蒸し焼きにする
  3. 一分半くらいしたら、ひっくり返し、もう片面も一分半くらい蒸し焼きにする

備考

焼き魚全般に使えるレシピだが、焼き時間は魚の厚みや大きさでも変わるので適宜変える。

蒸し焼きにするときにキッチンタオルを使うと洗い物が減らせる。

20250401_091405331.JPG

燃えることがあるので目を離さないこと。

投稿日:
開発::設計ライブラリ::Next.js

Next.jsの全体設計を考えるときに疎結合性やテスト容易性を達成するときに考えているアーキテクチャについて簡単に書いてみる。

Page Router向けに作っていて、API Routesについては考慮していない。過去にこれに近い設計で開発していたことがあったが、単体テストによるデグレードや不具合、仕様漏れの検出はよくできていたと思う。今回書いたものは過去に考案し、開発していたもののブラッシュアップになる。

アーキテクチャ図

基本的に各レイヤー間はTypeScriptのtypeで仕切り、依存性を逆転させることで、テスト容易性や疎結合性を重視している。

next-js-arch.png

ディレクトリ構成

アーキテクチャ図にないlibrariesが登場するが、これは汎用的な共通処理だ。

src
  ├─adaptors
  │  └─User
  │     ├─index.spec.ts
  │     └─index.ts
  ├─components
  │  └─form
  │      └─TextInput
  │         ├─index.spec.ts
  │         └─index.ts
  ├─libraries
  │  └─HttpClient
  │     ├─index.spec.ts
  │     └─index.ts
  ├─pages
  │  └─hoge
  │     ├─ServerSideProps.ts
  │     ├─ServerSideController.spec.ts
  │     ├─ServerSideController.ts
  │     └─index.page.ts
  └─usecaes
      └─hoge
         ├─controller.spec.ts
         ├─controller.ts
         ├─state.spec.ts
         ├─state.ts
         ├─style.scss
         ├─usecase.tsx
         ├─view.spec.tsx
         └─view.tsx

登場する各要素について

Page

画面本体。UsecaseとgetServerSidePropsを配置し、その橋渡しを行うだけの存在。

Usecase

StateとController、Viewを橋渡しする存在。

画面全体を別物にすり替える場合もここで行う。

useEffect()はここに書くが、中のロジックはController側に書く。

一見するとファサードであり、pageにべた書きしてもいいような内容だが、コードを書く時のコロケーションの観点から敢えて分離している。

また、画面のページレイアウトが全く別物になるなど劇的な変化がある場合は、この階層で分岐制御(ユースケース別の切り替え)する。

State

useState()で作った状態を定義する場所。それ以外は何もしない。

Controller

イベントハンドラによる処理を配置する場所。APIコールもここから行う。

状態については、typeを経由してState側で宣言した状態を注入して利用する。

状態を外部から注入するため、状態変化時のテストがしやすい。また画面からロジックをはがしているため、ロジック単体のテストが可能。

Adaptor

APIを呼ぶだけの存在。データの加工や例外ハンドリングは呼び元で行う。

APIを呼ぶだけの責務とすることで、複数のコンポーネントから呼ばれたときに同じAPIを呼ぶコードが重複したり、呼び出し元によってデータ加工手法を分けるなどの煩雑な実装を回避するのが目的。

テストとしては引数や戻り値、呼び出し方法が実装時から変わっていないかを見る観点のみあれば回帰テストとして機能する。

View

ほぼ純粋なJSXを書く場所。ロジックは原則として書かない。booleanを使ったDOMの切り替えは記述してよい。

制御はUsecaseでStateを合成したControllerで行う。

表示非表示の分岐のみにすることでtesting-libraryを利用したJSXの表示切替を単体テストとして実装できる。

UI Component

TextInputみたいな細かいパーツや、再利用されるフォームUIなど、UI系の共通部品。

基本的に状態は持たないが、無限ループが起きず、再利用されない状態(親に渡す必要がなく、自分自身に閉じた状態)については持ってよいと考えている。例えば、OK/CancelのあるモーダルでOKが押された時だけ呼び元に返す状態は持ってよい。

View, Controller

ページコンポーネント向けの内容に準ずる。Usecaseを持つほど大規模なコンポーネントはないと思うので、Usecaseなしで繋ぎ合わせてよいと考えている。

ServerSideProps

getServerSideProps()の中身。Page側では以下のようにして呼び出す想定。

import { execServerSideProps } from './ServerSideProps';

export const getServerSideProps = (async () => {
  execServerSideProps();
});

ServerSideController

ServerSidePropsの中で利用するロジック。APIを呼ぶ場合はAdaptorとも繋がる。

利点

  • 各レイヤーやコンポーネントでの単体テストが容易
  • MVC的な構造のため理解しやすい
  • SOLID原則で得られる利益を享受しやすい

欠点

  • ボイラープレートコードが増える
    • とはいえ、DDDよりは少ない
  • Modelに相当するものがないため、ControllerがFatになる。またModel処理の共通化ができない
    • Modelをどこに配置すべきかを検討できていない
  • typeに破壊的変更が起きると数珠繋ぎに修正が必要になり、コストが重い
    • その代わり型で各コンポーネントの関係性がわかる利点もある

あとがき

構想自体は4年前に考えたものだがアウトプットができていなかった。まだ煮詰まっていない上に考慮出来ていない部分もあるが、AppRouterの登場からだいぶ経ち、陳腐化してきそうだったので、取り敢えず吐き出した。