C/C++ の文字列終端と Delphi の文字列の扱いが異なるので転生に失敗する世界線

某所で失敗したのは3日間ほどなのですが、これ意外と知られていないので流しておきます。
以前、会社にいたころに XML-DB を扱う自社製品があって、それにアクセスする I/F を作っていました。外部的には Java ライブラリを使ってアクセスするのですが、ちょっと事情があって内部的にアクセスするライブラリを C/C++ で開発することになったのです。

で、その XML-DB がですね、実は Delphi で作られていたのです!!!
いまだと Delphi という名はあまり知られていないものの 30 年近く前には、意外とメジャーな言語でした。ググると分かるのですが、Delphi のベースは Pascal です。もともと Pascal は教育言語として開発されたものなのですが、それを実用化したのが Delphi というわけです(当時は Borland 社が開発・販売していて、名前は違うのですが、ここでは Delphi に統一しておきます)。

今だと何故に Pascal 言語が? と思うかもしれませんが、まだ Java も広がっていなくて C# も出ていない時代です。Windows アプリケーションを組むとなると VC++ でがりがり組むか、Visual Basic 6.0 で GUI を組むかという時代です。
当時、クラスライブラリが乏しくて、C++ だと XML をパースするのに Xerces などの外部ライブラリを使う必要がありました。で、VB6.0 の場合は GUI は簡単に組めるのですが、この手のロジックあたりが弱くて、そういう場合は仕方がなく VC++ で組むことになります。
まあ、当時の VC++ は GUI の開発環境が貧弱で MFC のライブラリ以前だったり、その後に出てきた MFC も使いづらかったりしたのですが、そこで登場したのが Delphi だったのです。VCL と言う GUI ライブラリがあってですね、それが広く使われていたのです。
で、今で言えば科学計算を学ぶには Python が一番!!! というように、Windows アプリケーションを組むならば Delphi!!! という時代があったわけです。皆さん、わざわざ Pascal 言語を学んでいたのですね。すごい。

そういう経緯があって、ちょっと先進的な GUI だったり、ちょっと気の利いたライブラリだったりは Delphi で作られていることが多かった時代があるので、ちょっと優秀なプログラマが XML-DB を組むときに Delphi で組むのも不思議ではなかった時代があったのです。

で、悲劇はその後に起こります。

その後 Microsoft が VC++ を改良して、MFC というクラスライブラリを充実させていきました。先に書いた Xerces などのライブラリも C/C++ から使えるようになってきました。MFC のボリュームが VCL に近づき、会社の規模から見て VCL を凌駕していったわけです。

そうなると、開発者のボリュームとして、Delphi を使う人が減少してきました。VC++ の GUI 環境が整うにつれて、VB6.0 からも VC++ に流れて来たのです。最終的には C# や VB.NET に移っていくわけですが、その間に VC++ で書かれた Windows アプリケーションのコードがたくさんあります。

その時点で起こる現象として、Delphi で作られた XML-DB のライブラリを C/C++ で呼び出すことになります。つまり、遺産をうまく使っていこうという発想です。

そんな状況で Pascal を知らない C/C++ プログラマ(つまり私)が移植担当になって、調べていくとですね、あれ? 文字列の呼び出しが変? ということになります。

ご存じの通り、C/C++ の文字列の終端は NULL 文字(’\0’)になっています。

C 言語

char str[] = "Hello";

この場合、str は ‘H’, ‘e’, ‘l’, ‘l’, ‘o’, ‘\0’ という文字列になります。

ってな具合に Copilot に書いてもらうくらい簡単なものです。
じゃあ、Delphi の場合は? というと、Delphi の文字列は長さ情報を持っているのです。つまり、文字列の先頭に長さ情報が入っているわけです。

Pascal

var str: string;
str := 'Hello';

この場合、str は長さ 5 の情報と ‘H’, ‘e’, ‘l’, ‘l’, ‘o’ という文字列になります。

Pascal の場合には、NULL 終端ではなくて、長さ情報が先頭に入っているわけですね。

C 言語的に言えば

  • str[0] が文字列の先頭
  • str[-4] が文字列の長さ(4 バイト整数)

ってわけですよ。

えええ!!! 配列をマイナスにしていいのかい???

ってくらいです。C/C++ プログラマにとっては。

文字列よりも前に何かメモリが必要ってのは不思議でもありますが、ASN.1 の規約を知っていれば不思議じゃないもので(これもググってください)、規約として先頭に文字列の長さを入れることがあります。

Java や C# だと string クラスを使うのが普通ですが、C/C++ や Pascal だと文字列は配列なので、こういうことが起こるわけです。まあ、正確に言えば、配列に埋めているだけなので、ASCII なのか、Unicode なのか、UTF-8 なのか、UTF-16 なのかで終端も変わってくるんですけどね。特に Unicode の場合には wchar_t 型を使うので、2 バイトの NULL 終端になります。これも 1 バイト終端と間違えてバグる可能性大です。

C/C++ と Delphi の文字列の扱いや配列の扱いが異なるので、これを相互変換しなければなりません。さらに、この手の情報をファイルに落としたり、メモリで一括で扱うときには、NULL 終端の場合は 1 バイトなんですが、長さ情報は 4 バイト使っている !!! ってことになり、バイナリデータの扱いも変わってしまうのです。

Delphi でバイナリデータを作って C 言語で読む場合にはちょっと面倒なことになります。
配列とかすべて再定義しないといけないですからね、もう大変ですよ。

そんなわけで、当時はまだ Delphi の名残が残っていたので、まあなんとか文字列終端の違いに気が付いたものですが、さらに 30 年程経ってしまうとですね。

化石的な Delphi ライブラリが残っていて、これに遭遇するわけです。
Java でアクセスするとか、C# でアクセスするとかの問題ではありません。

なにこれ、変? なんなのこれ???

と3日間ほど悩んでも仕方がないところです。

と、まあ、このあたりは私の想像なので、実際のところはよくわかりませんが、そのあたりが垣間見れてしまったので、ちょっと面白かったです、って話です。自分のことだときついのですが、所詮、他人事ですから。ははははははは、はぁ、お疲れ様です。

カテゴリー: 開発 | C/C++ の文字列終端と Delphi の文字列の扱いが異なるので転生に失敗する世界線 はコメントを受け付けていません

生成 AI によるカクヨム小説の自動作成の解説

最初に断っておくと、この手の生成 AI による小説書きについては是でも否でもありません。先の小説の解説を見れば AI で書いてあることは明白であるし、その戦略を明示されていて、アンフェアな感じはしません。YouTube で F5 キーを押して回転数を稼いでいるわけでもないし、偽装メールアドレスを使って ☆ を使って稼いでるわけでもなさそうなので、これはこれでよいのでしょう。

実際「数で稼ぐための創作論」という形で、カクヨムの数(多分、ランキングに上がるための☆の数)を稼ぐための手法としては、非常に有効な手段であると思います。

ただし、数を稼いだからと言って、商業デビューできるとは限らないのですが、ここでは☆の数だけに注目してみます。

ハーレクインロマンスというジャンル

AI に小説を書かせるときには、登場人物やある舞台背景を設定します。当該の異世界転生の令嬢という話であるならば、そこそこの設定を書けば十分です。できるだけ、現在の流行りの設定を書くのがよいでしょう。

昔(いまでもですが)、ハーレクインロマンスというジャンルがありました。ハーレクインロマンスは、アメリカのロマンス小説の一ジャンルで、女性向けに書かれた恋愛小説です。特徴としては、裕福で魅力的な男性と普通の女性が出会い、恋愛関係に発展するというストーリーが多いことです。登場人物は典型的なキャラクターであり、男性は強くて保護者的であり、女性は魅力的で感情豊かです。物語はしばしばドラマチックで、感情的な葛藤や障害を乗り越えることがテーマとなっています…という筋書きがあらかじめ決まっています。この解説文も Copilot の拾ってきたもので、Copilot 自身もよくハーレクインロマンスの構造がわかっています。

ハーレクインでは、導入部分がどうなるのか、展開がどうなるのかというページ数がほぼ決まっています。当時は、AI というモノがなかったので、ゴーストライターがたくさん集まって、次々と似たような小説を出しています。いわゆる、昼メロのドラマの視聴者をターゲットにしたアメリカの小説ですね。もう、40年程前からあるものなので、家庭の主婦を対象にしています。そして、毎回同じメロドラマが繰り返されるのです。

これ、面白いかと言うと、まあ、1冊だとそこそこ読めるようにできているのですが、5冊ほど買って読んでみてください。できれば、同時並行で読むのがお勧めです。同時並行で読むと、登場人物たちが、どのように恋愛をして、どの部分で何かの事件に巻き込まれるのか(ちょっと覚えていないので、事件があったかどうか定かではないのですが)、どのように解決してロマンスに陥っていくのかが、ページ数で決まっているのです。だから、どんな小説家、というかライターが書いても似たような小説ができます。構成にあわせた、量産品小説ができるのです。

この作戦は、なにもハーレクインに限ったものではありません。雑誌のゼクシィやバイク雑誌、フランス書房なども似た感じで作っています。私が好きだったのは 30 年前のティーンエイジャー小説なのですが、これは学園もので、ちょうど現在の異世界転生の学園ものに近い感じです。アメリカ高校生のダンスパーティのシーンがあったり、生徒会が出てきたりします。これも定番で、どの本を読んでも似たようにダンスパーティと生徒会が出てきます。まあ、3,4冊で飽きてしまうのですが、暇つぶしにはいいです。たしか、ハヤカワ文庫であったはずなのですが、今は見当たりません。これは、当時、各出版社が作っていて、結構シリーズ化されたんですよね。漫画でいえば渡辺多恵子の「ファミリー!」が近いです。「ファミリー!」自体は量産品ではないのですが、このようなスクール生活中心の物語が、ハーレクインのように繰り返し出版されていました。たしか、中高生が漫画しか読まなくなって、小説が激減した時期で、それを盛り返そうとしてアメリカの青春小説を輸入しはじめたのが発端だと思うのですが、まあ、すぐに廃れました。SF が売れない時期で、ハヤカワもこんなのに手を出したのか、と思った次第です。まあ、その後 SF が復興したんですけどね。

そういう意味では、異世界転生のラノベブームも似たようなものですが、異世界転生の場合は設定が多様化していることと、意図的に似せてはこなかった、むしろ設定を変えて差別化してきたところに特徴があります。

量産するという占い方式

ところがですね、「数で稼ぐ~」の展開としては、これを意図的に逆にしています。

つまりは、ハーレクイーンの時代に戻して、構成を同じにしたわけですね。

さらに、カクヨムの特性として、新作リストがトップページ等に出ることを使って、似たような設定でたくさんの連載小説を AI で作るようにしました。つまり、量産したうちの 1 本が当たればよいというスタイルです。これは「占い方式」で、相談者に適当に YES/NO で答えて、YES で当たっていた方だけを残していく方式です。たくさんの同型の小説をアップしておいて、当たりだけを残せばいいのです。Web テストの A/B テストみたいな感じです。

作者のページを見ると同時並行的に10本以上の連載小説が並んでいます。どうやら、日に38本位を同時にアップしているそうなので、新作のリストが埋まってしまうという苦情も寄せられています。

人が書いた場合にはさすがに 38 本も同時には書けないのですが、生成 AI では難しくはありません。ただし、人が内容を確認するとスピードが遅くなってしまうので、内容はほぼ確認していないと思われます。

そんな中で今回は、そのうちの1本がヒットして、総合ランキングの1位になったわけです。おそらく、たびたびジャンル別のランクには上がっていたと思うのですが(過去の☆を見ると、取れそうな感じはするので)、今回話題になったのは「総合1位」という話題性でしょう。

自動生成されているので、小説の中身は問いません。

ただし、小説を読んで☆を付けている人がいるわけで、それが人の書いた小説よりもランクが上になったという事実がここにあります。

まあ、作戦的には「AI で量産する」という人間業では無理ということをやっているので、多少反則な気もしますが、それは、将棋 AI が人間に勝った、みたいなものです。まあ、読者は人間なので、判断的にも人間が凌駕したともいえます。

自動生成の実践

仕掛けがわかったところで、実践をしてみましょう。

私自身は、AI による自動小説はあまり興味がないのですが、実験的にやります。以前、まだ ChatGPT 4 あたりが出たばっかりのころに設定を使って書いてみたのですが、あまり面白いものはできませんでした。最近では、結構、キャラ付けをすると面白いことができます。

文体に関しては、例えば「村上春樹風に」とか「星新一風に」とか「夏目漱石風に」とか結構できます。今回は「庄司薫風に」してみましょう。庄司薫は「あかずきんちゃん気を付けて」などを書いた芥川賞作家です。青春小説の走りみたいな形で、薫くんシリーズは 4 冊しか出ていないのですが、当時はエポックメイキング的なところがあって、誰もが教科書的に読んだものです。

時代は大学の学生運動の頃なのですが、皆が血気さかんな時期に自制して思考することを優先した青年の話ですね。いわゆる、学生運動や当時の社会思想的な小説家たちが「行動すること」を中心とした時代へのアンチテーゼみたいなものです。

手順としては、以下のように作っています。構成については、あえて、総合1位のものをパクってきています。これは、どの小説でも構いません。

1. 曲がり角でぶつかった少女に回復魔法を使ったら不治の病と盲目なのを治してしまってめちゃくちゃ懐かれてた(夏見ナイ) – カクヨム https://kakuyomu.jp/works/822139837599758883 から、全話を抜き出します。
2. NotebookLM に突っ込んで、マインドマップを作ります。
3. 登場人物のリストを抜き出します。
4. 設定や舞台背景を抜き出します。
5. 大まかな事件を抜き出します。
6. これらを元にして、SF 風に ChatGPT に仕立てて貰います。
7. 生成された文章を、さらに ChatGPT に庄司薫風に直して貰います。

※ 登場人物の名前は著者に敬意を示すために、そのまま残してあります。
※ AI 生成そのままなので、著作権はないんですけどね。すこし手直しすると、著作権が発生します。

できあがった、小説と途中の markdown ファイルは、NotebookLM https://notebooklm.google.com/notebook/9508ee51-4a21-42d4-bf6c-856cfc9274aa に共有しておきます。

ハーレクイーンのようにバリエーションを付ける場合は、SF的展開.md のように、古代風とか中世風とかで作ってください。事件もろもろは、適当に追加すれば ChatGPT が整合性をあわせてくれます。おすすめはしませんが「数で稼ぐ~」のようにカクヨムにアップしてもいいのですが、これは自己責任でお願いします。

これ、実験的には面白い試みではあるのですが、小説的に面白いかどうかは別ですね。

さらに、商業的にデビューを目指すのであれば、全面的な AI 生成はやめておいたほうがいいと思います。文章力がつかないし、構成力も借り物にしかならないので結果的に面倒くさいです。ただし、将棋 AI のように、論理的に突き進む場合(誤字がないとか、構成的な矛盾が出ないとか)は、AI のほうが向いています。私としては、AI とのペアプロというかペアで執筆がお勧めです。誤字とか構成チェックに AI を使うとか、ところどころの定型文で AI に書いて貰うとかしたらよいでしょう。

余談ですが、LLM のモデルとしてカクヨムの 100 万本の小説が抜き出されて、それを活用して、という噂話があるんですが、これは本当かどうかはわかりません。

そのモデルを使えば、確かにカクヨム読者に特化した文体と中身が出来そうな気もするのですが、先に書いたように「量産して1本だけ当たった」状態なので、あまり意味がないです。この場合、量産して全てを当てるか、1本だけ書いて1本当てる、パターンで使うのが正しいので、今回のように10本以上の連載のうちに 1本だけ当たったというのは、確率的に質が悪いです。

それに以下の ChatGPT に書いて貰ったものを見ると分かるのですが、いまの GPT5 だと、結構書けるんですよね。こうなると、わざわざカクヨムの小説を学習させる必要もないような気がします。

以下は、自動作成した小説の第1章をサンプル的に

第1章 転移とユウキの静かな願い

帝都の夜って、星が負けるんだよな(いい勝負する日もあるけど)。二つの衛星が雲の切れ目からのぞいて、軌道リングを牛乳みたいに縁取っている。俺は六畳ちょいのモジュールで、ぬるい合成コーヒーをすすっていた。重力は薄い、眠気は濃い、みたいな感じで。

俺――ユウキ・アスカワ。前世は日本の社畜で、定時は神話、終電は日常、っていう生活。で、ある晩に限って紙を拾おうと屈んだら視界が暗転した。ありがちな黒い画面のあと、あんまりありがたくない白い部屋。青白いイケメンがポテチ食べながら言うわけだ。「願いは?」って(そんな軽いテンションで訊く?)。

「穏やかに暮らしたい」。はい、反射で出た。戦わない、目立たない、誰にも使われない。要するに、静かで、勝手で、ちょっと疲れてる人の願い。彼は肩をすくめて、電子ノイズっぽい声で「加護を授与。生体ナノ群体、管理権限付与。君の手は癒やしの光になる」とか言う。いや、それ、穏やか要素どこ。

目を開けたら天井は白くなくて、金属と消毒薬の匂いがした。帝都軌道ハビタットの医療区画。手のひらに意識を寄せると、そこに“ざわめき”がある。見えない粒が、命令待ちの兵隊みたいに。恐る恐る擦り傷に触れると、金の粉塵みたいに光って、熱で皮膚が縫われた。

「……派手すぎ」

安堵より先に、それ。黄金って、とにかく目立つ。目立つって、つまり危険(この帝国では特に)。生体ナノ群体は軍事と政治のど真ん中に置かれる技術だし、俺が誰かの“所有物”になる可能性なんか想像しただけで、前世の偏頭痛が後頭部でうずく。

だから、決めた。——誰も見てないところでしか使わない。小さな傷だけ。血も涙も避ける。黄金は俺のためだけ。以上。

退院して渡されたのは、身分コード、住所モジュール、星港補給デッキの軽作業の紹介。帝国は新参者をいきなり実験台にしない(少なくとも表向きは)。俺は無表情の練習をして、荷役に混じった。

補給デッキは帝都の胃袋だ。肉、穀物、機械部品、誰かの手紙。コンテナはどれも金属の匂いがして、フォークリフトのホイールとマニピュレータの油が静かに歌う。遠心重力のわずかな傾きが足裏を撫で、時々、貴族仕様の白いコートが視界を横切る(襟の紋章で家柄が読めるの、何回見ても慣れない)。

俺は端っこで暮らす方法を覚えた。朝はドックの冷気、昼は肉屋の親父の端肉、夜は薄重力の部屋で旧地球の音楽を小さく。

「兄ちゃん、また端っこでいいのかい」

肉屋の親父は、俺の好み(脂多め)を勝手に覚えるタイプ。太い腕、笑うと目尻が消える。店はプロムナード寄りで、貴族も庶民も肉の前では平等に真剣だ。

「端っこが一番うまいんですよ」

「そういうの、わかる口だ」

冗談を返せるくらいには、暮らしが体に馴染んできた。手のひらの群体は賢くて、命令の粒度を落とせば光は抑えられる。小さな裂傷なら、皮膚の色がほんの少し温むくらい。誰も気づかない。俺は“傷を作らない”歩き方も練習した(これが意外と難しい)。

……でも、目を逸らせない時ってある。夕方、補給デッキの影で小さく泣く声。膝を破いた少年。血が透明フィルムに貼りついて、見てるだけで痛い。

「大丈夫か」

しゃがんで、手のひらをかざす。閾値は最低。発光はゼロ寄り。空気がほんの少し金色に濁って、痛みがほどける。

「……あれ、痛くない」

「気のせい。よくある」

立ち上がると、少年の目が一瞬だけ大きくなって、すぐ普通に戻る。礼を言って走っていく背中を見送りながら、俺は手を見る。光はない。昼夜サイクルは、少しだけ夕方へ傾いた。

目立たない。目立たない。目立たない。これは呪文。前世で生き延びた術が、今世でも通用するかのテスト(合格してほしい)。

ハビタットは巨大な円環都市で、内側に人工の空と木々、外側に星と軍艦。帰り道はいつも同じ。正面エスカレータは使わない。螺旋のメンテ階段、広告が少ない側道。世界から半歩浮いて歩くと、なぜか安心する。

その頃から、星港の“噂”が耳に入ってきた。近衛艦隊司令の一人娘――シルフィード公爵家の令嬢が、長らく神経インターフェース不全で視覚補助が効かない、とか。帝都医療局総出でも原因不明、とか。噂ってのは、たいてい最初の一文で充分。残りは聞かない(関わる未来、想像したくない)。

続きに興味があれば https://notebooklm.google.com/notebook/9508ee51-4a21-42d4-bf6c-856cfc9274aa を見てください。

補足 2025/11/01

AI 作家による大量投稿によって、新着リストが埋まるのでは? という懸念が X に上がっていますが、実際にはそんなことにはならないです。例えば、以下はカクヨムの「異世界ファンタジー」の新着リストになります。
このリストの新着時刻を見ると、

  • 2025年11月1日 11:22
  • 2025年11月1日 11:16
  • 2025年11月1日 11:14
  • 2025年11月1日 11:11
  • 2025年11月1日 11:11

のように、10分間以内にも数件上がってくる様子で、1時間もあれば新着リストが一巡してしまう勢いです。しかも筆者は別々になった状態です。

つまりは、既にカクヨムの新着投稿では1時間で一巡するぐらいの流量があるので、AI 作家がちょっとやそっと入れたところで新着投稿のリストを埋めることはできません。もし、AI 作家が 1時間に1回以上の投稿をすればリストに載る程度のもので、埋めようと思うならば、1時間に40本位は上げないとリストは埋まらないでしょう。つまり、実質としてはひとりの AI 作家がリストを埋めるのは無理です。
もちろん、AI 作家が 10 人位でてきて、同じように 1 時間に 2,3 本ペースで up していったとしたら、新着リストは「複数の AI 作家」によって埋まってしまうかもしれませんが、それは、そのときになったときに判断すれば良いでしょう。少なくとも、運営側が判断する話です。現在のところ、傾向としては 1 人の AI 作家なので問題は少ない。しかも AI 作家だとしても、1 時間に 1 回程度の投稿であれば(24時間であれば 1 日 24 本まで投稿が可能です)、特に新着リストを荒らすことはありません。十分、許容できる範囲と思われます。

もちろん、それは実際に作家になりたい投稿者と☆の数だけが欲しい投稿者との混在になってしまうのですが、現状でも似たような感じなので、そこは AI 作家の問題とは異なるものです。

まあ、個人的に言えば、「あ、これ面白い」と思ったものが AI で書かれていたものだとしたら、ちょっと鼻白みますね。AI を活用して書いたのならばいいけど、全面的に AI に頼っているものを読むのは騙された感じがするので、二度と読まないと思います。

追記 2025/11/14

カクヨムから声明がでました。生成 AI に対してという訳ではないですが、過度な頻度での投稿の禁止です。

過度な頻度で作品やエピソードを投稿する行為はお控えください – カクヨムからのお知らせ https://kakuyomu.jp/info/entry/2025/11/13/170248

AI からの自動生成は禁止しないけど、あまり極端なのはやめてね、という具合ですね。当該のアカウントは BAN されていはないので、OK なようです。毎日更新は続けているので、それはそれで良いのかなぁと。

カテゴリー: 開発 | 生成 AI によるカクヨム小説の自動作成の解説 はコメントを受け付けていません

Windows 11 の OneDrive で “安全に” 同期させないようにする方法

定期的に OneDrive dis が発生する X 界隈ではありますが、まあ、確かに「OneDrive の同期」については最初は切っておく、ってのがベターです。というのも Dropbox のようにバックアップ環境としてファイルを置いておく感覚で OneDrive にファイルを置くと痛い目にあいます。

Dropbox ではファイルのバックアップなのでクラウド環境にファイルを退避すれば、ローカル PC にあるファイルを消しても構いません。ファイルはクラウド上に残ります。これは感覚的にあっています。倉庫に物を置くようなイメージですからね。

しかし、OneDrive の場合は同じことをやるとクラウド上のファイルも消えてしまいます。一般的なバックアップシステムのような振りをしていますが、実は「複数の PC で同期」するのが主目的なので、削除した場合はバックアップ…じゃなくてクラウド上のファイルも消えてしまいます。さらに言えば、同じアカウントで入っている別の PC からも消え去ってしまいます。これは一大事。ってのが、何度も繰り返される OneDrive dis の本質でしょう。

OneDrive はクラウドのバックアップじゃなくて、同期システムなんだ、と何度言っても無理なので、ここは潔く「OneDriveを使用しない」あるいは「部分的にしか使用しない」に留めておきます。ちなみに、私は「部分的にしか使用しない」ことにしています。

OneDrive を使わないようにする。

いったん、OneDrive を使わずに同期をしないようにしてしまいます。おそらく Windows 11 をいれるときに Microsoft アカウントを入れるのが通常なので、ほぼ無条件で OneDrive でリンクされてしまいます。PC が 1台だったらいいのですが、複数台(ノート PC と在宅 PC とか)を使う場合には、いったん OneDrive を1台だけに絞って、他の PC では使わないようにしたほうが間違いが少ないです。

Windows 11 のタスクバーから、クラウドアイコンを右クリック

歯車の設定アイコンをクリック

メニューから「設定」を選択

OneDrive 設定から「アカウント」を選択して、「この PC からリンクを削除する」を選びます。

たとえば、持ち運びをするノート PC とか、一時的に Windows アカウントが必要だったときの業務 PC では「この PC からリンクを削除する」を選択して外しておきます。

ちなみに、バックアップのつもりで OneDrive を使う場合には、

  • デスクトップ PC では、上記のように PC からリンクの解除をしておく。
  • ブラウザで onedrive.com を使う

としておくのが安全です。ちょっと面倒ですが、Word/Excel ファイルを操作するときはブラウザ上で、画像ファイルなどはいちいちアップロード/ダウンロードとしておきます。こうすると、PC とクラウド上がうまく分離されるので、Dropbox と同じ形で使えます。

部分的に OneDrive で同期させる

たまに OneDrive の同期が失敗するのが難点ではありますが、部分的に同期させるのがお勧めです(これは、Documents 配下を同期させても失敗は良く起こるので、部分同期でもドキュメントフォルダ同期でも変わりません)。

さきほどの OneDrive の設定から「フォルダーの選択」ボタンをクリックします。

初期設定は忘れてしまったのですが、おそらくこんな感じで「Desktop」「Pictures」「ドキュメント」にチェックが入っているはずです。

よく、OneDrive に騙されるのは、デスクトップを同期に含んだ状態であって、ノート PC のデスクトップからファイルを削除したら、業務 PC のほうからも削除されてしまった。という例です。他にも、ノート PC とデスクトップ PC の両方で別々で作業していたとか、片方でファイルを別のフォルダーに移動したとか、そのようなところで衝突(コンフリクト)が起こって、OneDrive の同期ができなくなってしまいます。最近は、OneDrive が勝手にファイル名を別のものにする機能が加わったので、だいぶんマシにはなったのですが、それでもファイル名がよくわからなくなってどちらが最新なのか混乱してしまいます。
まあ、同時にファイルを弄るのが不味いといえば不味いのですが、ブラウザ上で編集しようとすると、編集できてしまうのが問題ではありますね。

私の場合では、

  • Desktop は同期させないので、チェックを外す
  • Picture を同期させないので、チェックを外す
  • ドキュメントを同期させないように、いったんチェックを外す

すべてのチェックを外したうえで、同期させておきたいフォルダー(下記では、「仕事」と「Blog」)にチェックを入れます。

仕事フォルダは “c:\Users\masuda\OneDrive\ドキュメント\仕事 にフォルダーを作っています。個人用のドキュメントフォルダーとは異なる位置にあります。他にも OneDrive\ドキュメント配下に「公開」フォルダーを作って、その中に Blog を作って、これを同期する形にします。

これによって同期されるフォルダーが「仕事」と「Blog」のみに限られます。
これは新しい PC に Windows 11 をインストールするたびに、やらないといけないのが面倒ではあるのですが、このように同期するフォルダーを設定してしまうほうが制御が楽です。

当然、このフォルダーはバックアップとしてではなく、同期としてつかうので複数台の PC から同期されること(削除や移動など)を意識してつかいます。バックアップとして使いたい場合はあらためて「OneDrive/ドキュメント/バックアップ」のようなフォルダーを作っておけばよいです。

特に、初期値では OneDrive の容量が 5 GB しかないので、ドキュメント全体を同期させてしまうとパンクしてしまいがちです。そのために OneDrive の増設を考えさせられることになるので、ちょっとこれは無駄でしょう。私の場合、以前 40 GB までの無料アップグレードキャンペーンがあったので、最大容量が 40GB になっているので大丈夫なんですが。Microsoft 365 Personal とかを契約したときには、1 TB になるので、契約している場合はいいのですが、素の Windows 11 の場合は OneDrive は使わない方針にして、ブラウザ経由のみで使うのがお勧めです。

OneDrive のその他の使い方

私の場合、OneDrive の仕事フォルダーは各プロジェクト(執筆など)の作業場所にしてあって、出版社との原稿のやり取りや、お客さんとの課題管理表のやりとりに使っています。ぷプロジェクト用のフォルダー移行を相手と共有するようにしてあるので、ファイルをメール等に添付する必要がありません。

会社の場合 OneDrive にセキュリティリスクの高いファイル(設計書、契約書など)を置くのはどうかと思うのですが、さすがに契約書まわりは置かないけれど設計書まわりは置いてあります。こうするとお客とのやり取りが手早いのです。これは Google Claude でもできるので、それでもいいのですが、私の場合は OneDrive で。

補足

Documents フォルダーを同期したままにしておくと、ファイルの紛失もそうなのですが、Visual Studio などで作成した中間ファイルなどが置きっぱなしになっていて、それを同期させて OneDrive の同期が死ぬことになります。ちらほらと Adoble のテンポラリファイルが溢れている例もあるので注意が必要です。

これ、素の Windows 11 の時は容量が 5 GB 程度なので、中間ファイル(Node.js や Python のライブラリも含む)が多くなると溢れてきて気付くのですが、Microsoft 365 を契約していて 1TB に拡張されていると気づくのが遅くなります。ノート PC で同期が走っていてどうもおかしいな?と思ったら OneDrive のでかい同期か Windows Update がバックグラウンドで走っていることが多いです。

カテゴリー: 開発 | Windows 11 の OneDrive で “安全に” 同期させないようにする方法 はコメントを受け付けていません

ソフトウェア開発/運用に必要なソフトウェア工学の書籍とは?

震源地は忘れてしまったのですが、「(IT)エンジニアならばソフトウェア工学を知っておいて欲しい」という X のポストだったと思います。ソフトウェア開発するならば、工学的なアプローチも知っておかないといけないのは当然で、まあ、当たり前だよね…と思っていたのですが、意外と「これは、ソフトウェア工学の本だろう」というのが出て来なかったので、備忘録的に書いておきます。

最初に「工学」の定義なのですが、属人性が低く再現性があり量産が可能であることとします。これは、ソフトウェアに限らず、建築、造船、車両技術などを見ればわかる通り、

  • 工場で誰もが(一定技術は必要かもしれないが)製品を作れる
  • 設計図などがあり同じ製品を作ることができる(これも技術が必要だが)
  • 単一でなく、複数のものが作れる

ということです。いわゆる「プロダクト」というやつですね。ただし、IT プロジェクトのように一回性の高いものがあり、プロダクトとプロジェクトを区別することもあるのですが、ひとつ視点を高くして「IT プロジェクトを成功に導く手法あるいは確率的に成功させる方法」として、IT プロジェクトを生産するための「プロダクト」手法というメタ的な考え方ができます。

たとえば、ビルを建築する場合には、それなりの手順があります。基礎を作る、鉄骨を入れるための場所を決めるなどの手順を踏まないとビルは建設できません。もちろん、適当にやってもビルの建築はできるかもしれませんが、確率的にそのビルは崩壊してしまうかもしれません。それよりも、確実に建築できる方法をとるわけです。これがサグラダファミリアも同じで、時間は掛かりましたが(途中ちょっと間違っていたらしいので)、最終的に建築できるものを建築しているという手順や基礎固めがあります。

この手順はソフトウェア開発や運用においても存在します。開発手法として、ウォーターフォール開発やアジャイル開発、スパイラル開発などさまざまな開発手法が提案されて、最近では AI によるバイブコーディングも含まれます。しかし、それらを越えたところに、いわゆる基礎固めとして「ソフトウェア開発プロジェクトを成功させる」ための基礎知識なり知識の蓄積があります。これがソフトウェア工学です。基礎固めなのですから、基礎知識がないとプロジェクトの成功は危うくなります。そういうもので、欠かすことができない要素ということになります。

プログラム言語の本が入っていないのは、ソフトウェア工学自体には特定のプログラム言語は必須条件ではないからです。正確には、プログラム言語という概念が必要になるので、「コンパイラ」の本が必要なのですが、残念ながら私は持っていません。これに適当なコンパイラの本が追加されます。

プロジェクト知識体系 PMBOK(第6版以前)

私自身は PMBOK はあまり好きではないのですが、知識体系として網羅性が高いのでソフトウェア開発に有用です。特に、プロジェクト計画、コミュニケーション、文書管理、調達などの分類がわかりやすいです。ただし、第8版以降は、それぞれのプロセスの実施よりも全体のコンセプトに移行してしまっているので、あまり役に立ちません。アジャイル開発スクラムや CCPM と整合性を合わせたために変な感じになっています。どうせならば、がちがちにプロセス重視でやったほうが PMBOK の有用性は高いです。

PMBOK では全体の要素を網羅するのが目的ですから、それぞれのプロセス/知識分野をすべて同じ力で関わる必要はありません。全体として摘まんでいけばいいんです。ですが、PMP 取得のプロジェクトマネージャがでてくると、PMP の通りにやるのでこれが問題だったのです。最近の PMBOK 系の PM はどうなんでしょうね?

先に書いた通り、PMBOK はアジャイル開発を含むようになっているので、PMBOK(かつてはウォーターフォール開発)とアジャイル開発(スクラム、XP、チケット駆動など)を離反させる必要はありません。全体としてソフトウェア開発のプロジェクトマネジメントという視点で捉えることができます。

UML

設計書を細かく文章で書くことも必要ではありますが、手書き UML だけでも十分なことが多いです。アジャイル開発にしても、開発意図などを伝えるときに UML を使う方がスムースでしょう。いわゆる、建築の三面図や、工作物の図面にあたるものです。

UML は多種にわたっていますが、PMBOK と同様に必要なものとしてつまんでおけば ok です。少なくとも UML を全く知らない、まったく使わない、状態でなければ ok ということです。

私が良く使っているのは、

  • クラス図
  • シーケンス図
  • ステートチャート(状態遷移図)
  • オブジェクト図(整合性をあわせるために)
  • ユースケース記述

の5種類です。たしか、アジャイル本にも書いたと思いますが、クラス図、シーケンス図、ステートチャート、オブジェクト図は、時間と具象・抽象の2軸で4象限を網羅できます。ユースケース記述は、システムテストに有効なのと、要件定義や検収に有用なためです。

計算機プログラムの構造と解釈

この本は中身が LISP なので読みにくいので、実際はヘネパタ本を使ってください。ヘネパタ本は kindle 版しか手元になかったので、代わりの登場です。パターソン&ヘネシーの「コンピュータの構造と設計」ですね。

コンピュータの内部構造(CPU、主記憶装置、入力装置、出力装置、補助記憶装置)とレジスタ周りが解説されていれば ok です。論理回路はあってもなくてもいいです。これは論理式で代用ができます。

コンピュータがきっちりと電子と電子回路、バス等で繋がっていること知っておくことは重要です。例えば、CPU と主記憶装置は分離しているので、なんらかのキャッシュが発生します、とかレジスタがありますとかいう話です。補助記憶装置は、HDD、SSD、DVD、データベース などの媒体があり、それぞれスピードが違うのでソフトウェア開発をするときに注意が必要なときがあります、とか。WEB 開発にしても回線のスピードがあるし、データはパケットで送られるから衝突や損失もあるとか。そのあたりが想像できるようになります。

逆に、このあたりのコンピューターの弱点がないものとして「設計」をしてしまうとえらいことになります。当然、要件定義(とくに非機能要件)に関わってくる話です。

ソフトウェア・テストの技法

ソフトウェア開発で、一番ソフトウェア工学らしいのが「テスト技法」の分野です。プログラマ的には TDD(テスト駆動)とかを思い浮かべていますが、いわゆる旧来のテスターや品質管理部門の人達がいる分野です。QA の人たちですね。

このあたり、計測がしやすいので、カバレッジとかコードの複雑度の計測とかいろいろな製品があります。はっきり言って、プログラマから見ると邪魔な存在ですが、必要不可欠な人たちです。テスト駆動の再帰テストはコードが崩れないことを保証するものですが、製品として完成していること=要件定義などを満たすこと、は保証してくれません。単に動くとか、バグがないとかいうのだけでは駄目で、なんらかの「保証」が必要なんですよね。

これは、自動車の品質管理や安全基準を思い浮かべるとわかります。自動車は動くことは大切ですが、何かにぶつかったり事故が起こったときに人が生き残ることが重要です。これが安全性です。なので、人型に衝突させたり、ボンネットに重たい玉を落としたりします(いわゆる、人間の頭や体ですね)。こういう風な極限状態でも車が安全であることを実験で保証するわけですが、果たして、ソフトウェア開発において極限状態の保証はどうやってやるのでしょうか? ということです。

つまりは「テスト技法」には、自動車で言う処の極限状態や頻度は低いが重大な障害が発生するところを、工学的に網羅していくという分野です。見知ったところでは、境界値テストとか、負荷テストとか、極限状態のテストです。

ソフトウェア開発の定量化手法

「ファンクションポイント法」を読むと、今更な感じもあり、現在のプログラム言語やライブラリに沿っていないので、あまり意味がない感じがします。実際そうです。そのまま使うことはできません。ここに書いてあるのは、機能単位、コード量などから、プロジェクト計画時に見積もりをしようという発想があります。これが重要な要素になります。

開発プロジェクトが「いつまで終わるのか?」というのは重要な要素です。当然、人件費がかかるので「いくら掛かるのか?」が出てきます。つまりは、計画と予算がプロジェクトの開始時に必要なわけです。官庁の見積もりでもそうですが、事前にスケジュールと予算が必要になります。でも、実際作ってみないとわからないですよね。でも、走り出す前に計画と予算を出さないといけないのです。実に矛盾しているように見えるのですが、これは建築や土木、車両の分野でも同じです。事前に見積もりを出します。

ビル建築の場合は、部材ごとに見積もりを出して合算していきます。それぞれの工法には施工期間が事前にわかっているのでこれで期間を見積もれます。途中に天候の問題などがありますが、それは余裕を持っているのであまりずれることはありません。まあ、沖縄の普天間基地の移転のように岩盤の調査をミスったりするとずれてしまうわけですが(それが意図的であるかどうかは別として)

ソフトウェア開発は複雑度が高いので、正確な見積もりは出しにくい。というのがソフトウェア開発におけるマネージャ、プログラマの意見ですが、だからといって目途を全く立てないという訳ではありません。実は、そこそこのプログラマはいつごろまでプログラムができるかを、的確に予想してコーディングすることができます。おそらく、経験と勘なのですが、なんらかの形で「定量化」することができます(実際は、PSP(ソフトウェア・パーソナル・プロセス)を使って測定できます。しかし、しんどいので私はあまりやりたくありません)。

つまりは、何かを基準にして(それが経験と勘であったとしても)何らかの法則で計算することによって、プロジェクトが計画可能であることを示すのが、定量化手法のベースです。逆にいえば、何かの基準を持たない人(新人や、コーディングをしないマネージャなど)は計画を立てることができません。このあたりの弊害は「BIG THINGS」に書いてあります。

ソフトウェア開発見積りガイドブック

定量化手法は、規模見積の話(いわゆるスケジュール)になりますが、この本では予算の話になります。ベースは定量化と同じようにファンクションポイント法などを使って計算をしていきます。

いままでは、プロジェクトの期間は、人月を掛けることによって予算に直結していたのですが、最近は異なります。高度なライブラリを使ったり、これからは AI エージェントを利用したりと、期間とは異なった形でプロジェクト予算が変わってきます。つまりは、建築でいうところの部材調達の比率が大きくなるということです。クラウドの利用料や特定の UI システムの利用、SAP や Microsoft 365 などの継続利用料というものが関わってきます。

つまりは、同じ要件定義でもなにかのライブラリを使うとか使わないとか、クラウドを使うとか使わないとかの形で、開発費用や運用費用が異なるということです。これらの状況はガイドブックができた頃にはなかった話なのですが、意味合いとしては昔からありました。

そのように必要な人件費とプロジェクトが活用する設備費用を合算していきます。当然、運用時の費用も計算します。これは PMBOK にあるのですが、定量化や金額見積もりの具体的な方法については、この2冊が非常に詳しいです。内容は古いのですが。

コンパイラ

写真にはでてきませんが、「コンパイラ」について挙げておきます。プログラムコードがそのままコンピュータで実行されるわけではないこと、その前にコンパイル作業が必須であることを理解できるようになります。

プログラムコードの文法、字句解析、文法解析、中間言語、マシン語への変換、などの流れを知っておくと、プログラムのコードがどう動くか?だけではなく、どのように最適化されるのか、なぜそのような文法になっているのかを知ることができます。これは、プログラム言語に関係ありません。中間言語で動く Java や C#、スクリプト言語として動く Python や JavaScript など(正確にはプリコンパイルなどの機能がありますが)の内部の動きを把握することで、単なる抽象概念としてのプログラム言語ではなくて、具体的な制限のあるプログラム言語を知ることができ限界値がどこにあるのかを気にするようになります。

たとえば、いろいろなソートアルゴリズムがありますが、それがなぜ「いろいろ」なのかということです。抽象的なメモリ配置ではなくて、具体的なメモリ(架空ではない)をアクセスしているので「いろいろ」になるのです。その感覚を養うために「コンパイラ」のざっとした知識が必要になります。

大学時代に読んでいた「コンパイラ」はこれですね。著者は aho だったのか。

おまけ。こっちのコンパイラも。

カテゴリー: 開発 | ソフトウェア開発/運用に必要なソフトウェア工学の書籍とは? はコメントを受け付けていません

駆け出しプログラマ向けに。コードを読みながら AI を使って向上する方法

小説を書くならば小説を読んだ方がいいし、絵を描くならば絵を見たほうがいいです。当然、最終的には小説を書いたり絵を描いたりすることが目的なのですが、なにも吸収しなければ何も出て来ない、というのが常ですね。たまに、小説も絵も見ないで書/描ける人もいますが、それは例外的な人なので、一般的な話として制限しておきます。
あと、将棋がうまくなるのも、将棋の棋譜を読むのが重要なので、やたらに将棋を指すだけではいけません。棋譜を読むのもひとつの手です。

自分の経験上でも、良質のコード読むのが手っ取り早いです。私が駆け出し=つまりは会社に入って新人のプログラマだった頃には、インターネット等は無かったので、主に参考にできるのは、少ないコンピュータ書籍とマニュアル、そして既存のコードでした。まだ、コンピュータ書が少なかった時期なので、プログラム言語(VB2.0 や C++ の頃)を学ぶにはマニュアルしかなかった時代があります。もっとも、既に C 言語や Fortran の書籍はいくつかあったので、初心者本というか教科書は手元に置いておきます。当時 VB2.0 はまだ新しかったので、参考にできる書籍はなくマニュアルが頼りでした。

あとは、既存のコードとなるわけですが、果たしてそれが良質なコードであるかどうかはわかりません。今考えれば、とんでもないクソコードだった気もしますし、新人だった当時も私もクソコードを書いて納品していた覚えがあります。まあ、C++ にかぶれていた時期があるので、現場は Unix C なんだけどオブジェクト指向(のつもり)で書いて、実に読みづらかったんですよ。他人が読めるってのは大切です。特に、当時はコンパイルのスピードも遅かったし、テスト駆動以前の時代だったので、紙面でのコードレビューは重要でした。それでも、会社の先輩のコードは「読む」のが普通で、そうしないと仕事にならなかったですよね。

あと、私の場合は “コードを読む” ことに関しては、

  • 大学時代に、炉計算の Fortran のコードを読む必要があった
  • OpenSSL を修正して検証ツールを作る関係上、OpenSSL のコードを読んだ

ってのが大きいです。炉計算は日立の技術者が作ったもので、これを修正するのが自分だったので読まざるを得ませんでした。OpenSSL は、ガラケーの暗号化のテストツールなのですが、データ解析するために OpenSSL を使ってデバッグコードや特殊なスイッチ(証明書の不正など)を入れざるを得ませんでした。

どちらにしても、大量の “良質な” コードを読まねばならず、これが幸いしたと言えます。

ただし、この方法はいまとなっては効率が悪いです。当時としてもどうかと思うけど、読むにしてもいきなり OpenSSL は大変です。GNU ツールのいくかから始めたほうがよいでしょう。

今だったら何のコードを大量に読むか?

いまだったら GitHub にある OSS のコードを読みます。プログラム言語は JavaScript でも Python でもなんでもいいのですが、できることならば IDE でデバッグ実行と変数が見れるようなプログラム言語がいいです。プログラムをステップ実行して、メモリの中身を確認できるものがいいですね。
まあ、そうなると Python と JavaScript はあまり適してはいないので(ステップ実行できるツールをもっていれば、それでもいいです)、Java とか C# のほうがやりやすいですね。コマンドラインツールでも GUI ツールでも途中でプログラムを止めて中身を確認することができます。ただし、仕事の都合上、React での Web 開発や、Python を使った科学計算をすることも多いでしょう。そういう場合は、真っ先に print デバッグの手法(JavaScript ならば Console.log 、Python ならば print)を覚えて、動作をログ出力しながら動きを確かめていきます。

仕事で使うコードが OSS のプログラム言語とは異なっている場合は、AI チャットを使ってコンバートしてもらうのも良いです。プログラム言語は、似たような文法が多いので(英語、フランス語、ドイツ語の関係のように)ひとつのプログラム言語を覚えておけば、他のプログラム言語を覚えやすいという傾向があります。
いままでは、初心者本を一冊買って文法を下読みするのですが(私の場合は今でもそれをやりますが)、いまだと AI のチャットを使って、コードを変換してもらうといいです。
AI のプロンプトで「○○言語に変換して」と頼むと、高確率できれいに変換してくれます。
当然、固有のライブラリまでは変換してくれないので、これは別途探す必要があります。あくまで、プログラム言語の文法やいくつかの構文の使い方を学ぶときに使います。

固有なライブラリを使っているときは、変換先の言語で適当なライブラリを探して貰います。そして、そのライブラリの使い方についてサンプルコードを AI に書いて貰います。
ライブラリ込みで変換することも可能なのです。が、AI エージェントだと結構な確率で変えてくれるのですが、コードが長くなり複雑になりがちで学習には適してはいません。できるだけ、ライブラリはひとつに限定して確かめていったほうが良いです。
プログラム言語の歴史として、手続き型、構造化、関数型あるいはオブジェクト指向、という形で進化してきているので、最初は手続き型の文法(if文やfor文など)を覚えたあとで、構造化(関数の使い方、構造体の使い方)を学ぶとよいです。その後、状態(ステート)について、オブジェクト指向型を使うか関数型を使うか選んでください。Web API の呼び出しは、構造化のレベルで十分可能なので、オブジェクト指向/関数型言語を最初のうちは意識する必要はありません。
効率よりも、確実に動くコードを目指していきます。

自分で書いたコードは、逐一 AI にレビューして貰うといいです。仕事でチーム開発をしている場合はレビューがあると思いますが(いや、無い場合も多いのでしょうが)、少なくともプログラム言語の学習をしている間にレビューを頼むということはほぼ不可能です。プログラミング教室に行って高いお金を払ってレビューして貰うことも可能ではあるのですが(最近 X では聞かなくなってしまったので、プログラミング教室が駆逐されたのか、果たして…)、AI にレビューをして貰ったほうが安価だし手軽です。
ただし、AI を使ったレビューにしても冗長なところが多いので、いまひとつ何を言っているのかわからないと思います。このようなときは、書き出した全体のレビューを AI に頼むのではなく、部分的にコードを選択して AI にレビューを頼むと良いです。この方法は、仕事でもよくやります。Agent モードを使うとコード全体を直しがちになるので、Ask モードを使って部分的な関数やコードをレビューして貰います。
特に、自分にとってあまり詳しくない言語にはこれが効いてきます。仕事でも Kotlin/Swift のコードは部分レビューを多用しています。

昔風に、コードを精読するのもいいのですが、もっと大量に多読する形でもよいです。

ちなみに、小説ですが私の場合は2,3か月程度で、こんな風に多読をします。金銭的には新刊で買うと辛いので BOOK OFF 等で 100 円程度で買ってきます。いわゆる乱読を意識的にやります。1冊読むのに、1,2日間ぐらいで時間で言えば、2時間弱位の流し読みです。これで文章のパターンを覚えた上で、もろもろの短編を書く、というのを今やっています(乱読自体は20歳代のころからやっているのですが、それは書評日記を書くためだったりするので、ちょっと違う)

上記の学習方法については、以下の本に書いてあります。これは Python がターゲットなのですが、他の言語でもいけますね…って形で書いたんですが、意外と売れないので次がありません(汗

まあ、Python 自体を学ぶのではなくて「Python の学び方を学ぶ」という手法を実際に示したものなので、読むと「いままで AI を使って学んできたやりかたと同じじゃん」という感想しになってしまうのも無理からぬことです。既に AI を使った学び方を知っている人じゃなくて、知らない人向けなので、既に知っているひとにとっては not for me なんですよね。

カテゴリー: 開発 | 駆け出しプログラマ向けに。コードを読みながら AI を使って向上する方法 はコメントを受け付けていません

設計と実装をひとつの vscode + copilot で開発するコツ(AI ペアプロ)

spec 駆動のエディタ(Claude xxxx とか Codex とか Kiro とか)流行りなのですが、それ vscode + copilot でやることもできます、って話です。夜間にぐるぐる回すようなヘビーな使い方をする業務型プログラマならば別ですが、それほど AI に任せきりではなく AI ペアプロぐらいな形で廻している場合には、課金的にはこっちのほうで十分です。まあ、開発のスタイルにもよるんでしょうけど、React とか Node.js を使った Web 開発のほうは Codex 系でぶん回したほうがいいのでしょうが、Android 実機で BLE 通信を確かめるとか(ってのを今やっている)のは、どうしても実機まわりのテストを手動でこなさなくてはいけないので、AI でぶん回すことは無理なのです。

あと、当然のことながら、

  • 趣味でプログラミングをやる
  • 在宅プログラマで、いくつかの案件を廻している
  • 新人教育で AI を使ってプログラミング学習も兼ねる

というパターンも、vscode + copilot で十分です。GitHub Copilot のほうは pro で十分で月額は $10 で…という宣伝はどこかに書いたような気がするのでさておき、ここでは「設計」と「実装(コーディング)」を分離させていきましょう、という話です。

Windows Copilot がやたらに実装を勧める

プロトタイプを作って動きから確認したい場合には、要件や設計を煮詰める前に実装を始めてしまうほうが楽です。というのも、具体的に UI が決まっていないのに、長々と要件/設計を煮詰めてしまうと、余計な設計をしてしまいがちです。そのあたりは、スパイラル開発あたりを参考にしてください。

昨今の spec 駆動型エディタは、要件/設計を先に煮詰める形になっていますが、これはいわゆる「ワンパス」方式になります。いわゆる、コンパイラ設計でコードからアセンブラに落とすときの「ワンパス」つまり一回しか読み込まない方式です。要件/設計 → 実装の一手順だけを考えれば、要件/設計をしっかり作る=夜間に AI にコード生成を頼む、ということになるので AI の時間一杯を使うだけの設計の盛り込みが必要になりますが、先のように設計→実装→UI 確認→設計→実装 のサイクルとなると、それほど設計の作り込みは必要ありません。と言いますか、余分なところが多く出てしまいます。

ただし、ここのサイクルが廻る開発/実装環境と、そうではない環境(先の Android 実機でのテストなど)では、プロトタイプサイクルの時間が異なるので、設計と実装の時間比とバッチ(いわゆる実装する機能の大きさ)を調節する必要があります。

で、Windows Copilot などで、コード開発をしようとすると、やたらにコード例を示してきます。どうも、React + Fagma の組み合わせや Python 開発が最初に出てくるので、この開発スタイルに引きずられてしまいます。一般的な AI 驚き屋の対象も Web 開発になるので、確かに UI から考えていったほうが検討上早いというのもあるでしょう。実際 Web サイトの自動開発はとてつもなく早いです。Windows Copilot や、その他の AI エージェントも Web 開発を前提としているものが多いのでしょう。

ですが、非 Web 開発の場合には、機器などをそろえたり環境を揃える必要があるので、そう簡単に実験環境が揃えるわけでもありません。特に AWS や Azure の環境にないものを使う場合は、環境構築も含めて検討をする必要があります。そういう点で、「設計」に力点を置いたほうが、ソフトウェア開発において無駄が少なくなる、というバランスになるのです。

設計と実装をプロンプトで分離する

ちょっと前までは(それも数か月前ですね)、spec 駆動は別の AI エージェントの IDE を使っおいて、コーディングは Claude xxxxx や Codex に任せる、というスタイルが多かったのですが、現状だと vscode + copilot ひとつで済みます。これ、vscode + copilot に agent モードが追加された(それまでは ask モードとして質問だけだった)ことが大きくて、これによって、

  • 要件や設計を煮詰めたいときは ask モードでやる
  • 実装やバグ直しをしたいときは agent モードでやる

という使い分けをします。ask モードの場合は、最初の頃はコードをばらばらと出してくるのですが「コードをの提案をしないで」とか「設計に集中して」というような、プロンプトを入れるとコードの提案をしなくなります。おそらく model の内部的に、コードの部分は codex で、それ以外は chatgpt で、という使い分けがなされているからと思われます。

さらに、再設計時には AI にコードを触れてほしくないので、敢えて ask モードを使います。ask モード自体は、従来のプロンプトで質問して、その解答をテキストだけで表示するモードでコードに反映するのが手間だったりするのですが、敢えてこれを利用します。思考したいだけですので、AI 壁打ち状態とするわけです。

実例

以前、ためしに作ってみた「見積もり依頼作成ツール」 https://omitt-chan.vercel.app/ を変更してみましょう。これも AI エージェントを使ったもので、基本的に次のような readme.md を使って、初期型を作っています。

# omitt-chan

見積もり依頼作成ツール

- 発注者が、みずから希望する機能を入れて見積もり依頼書を作る
- 見積もり依頼書のテンプレートを提供
- 作成した見積依頼書をもとに3パターンの見積もりを作成する(相見積に使う)

# 画面構成

- 左ペインに、発注者が対話的に入力するチャットフォーム
- 中央ペインに、発注者が入力した要件や機能を構造化して表示する
- 右ペインに、見積もり依頼書のテンプレートを表示する

## 要件チャット(左ペイン)

- 発注者は、チャット形式で要件や機能などを入力する。
- 発注者は非IT技術者のため、自然言語で要件を入力する。
- 希望、要件、設計、制約などは混在して入力されるため、入力内容を解析して構造化する必要がある。
- 発注者の入力を解析して、要件や機能を抽出し、中央ペインに表示する。

## 要件整理(中央ペイン)

- 中央ペインでは、発注者が入力した要件や機能を整理して表示する。
- 要件と機能を区別して表示する。
- 機能は、機能要件と非機能要件を区別して表示する。

このときは、readme.md に書いていたのですが、design.md とか設計.md とかでも構いません。ファイル名は、プロンプトから「design.md をもとにして Web サイトを作成して」で指示ができます。

ここでは、機能追加をする上で、どのような設計がよいかを readme.md に手作業で追加していくことを考えます。

こうやって、見積もり依頼書ができた後に、おおまかな予算を顧客側で把握したい、と考えます。

設計に適していると思われる CPT-5 に変更して、Ask モードに切り替えておきます。

追加機能を書きたい場所を、readme.md 等に作っておきます。
ここでは「概算予算の計算」という項目を作りました。

プロンプトで、追加機能を設計していきます。

初期状態だと、コードが大量にでてくるので、これをプロンプトで抑制します。

プロンプトで抑制すると AI の回答にコードが含まれなくなります。安全のために Ask モードのままで会話します。

以降は、コード無しで会話ができます。機能追加の検討でも、やたらにコードを出すことはありません。この分、トークンの消費も少ないし、レスポンスも早くなります。まあ、Agent/Ask の切り替えが面倒というのもありますが、そこまで開発スピードを求めるならば別途 SPEC 用の AI エージェントを使えばよいわけで、私のような使い方だとこれぐらいで十分かな、という感じですね。

あとは、Chat での検討に従って、readme.md に追記していけば ok です。このときに Agent モードに切り替えてもよいし、markdown 形式への補完をつかってもよいでしょう。

その後に、あらためて「概算予算の計算を Web サイトに追加して」というプロンプトを Agent モードで Copilot に頼めばよいのです。

もちろん、一手順ずつうごくので夜間で バイブコーディングとして動かすことはできません。ですが、要件や設計を試行錯誤しながらスパイラル開発っぽいものをやる場合には、このスタイルのほうが良いです。

カテゴリー: 開発 | 設計と実装をひとつの vscode + copilot で開発するコツ(AI ペアプロ) はコメントを受け付けていません

Windows 11 でローカルアカウントを作る方法

巷にいろいろな抜け道があるのですが、

  1. Windows 11 で Microsoft ID のアカウントでインストールする
  2. ローカルアカウントを作って管理者権限を付ける
  3. インストール時の Microsoft ID アカウントを消す

の手順が一番安全なはずです。

※ 抜け道を探す方法は、別のサイトを参照してください。

Announcing Windows 11 Insider Preview Build 26120.6772 (Beta Channel) | Windows Insider Blog https://blogs.windows.com/windows-insider/2025/10/06/announcing-windows-11-insider-preview-build-26120-6772-beta-channel/ によれば、SetDefaultUserFolder.cmd を使ってユーザーのフォルダーを設定します(これ、手軽かどうかは不明です)

以前は、インストール時に Administrator のアカウントが作成されていて、それにプラスする形でローカルアカウントを作っていました。これは Linux での root アカウントと同じで、消すと OS ごと死んでしまいます。なので、root アカウントや Administrator アカウントは外部からログインできないようにする(リモートデスクトップや ssh など)のが定番なのですが、Windows 11 の場合はそのあたりが曖昧になってしまっています。

会社のドメインやポリシーを使っている場合は、管理者権限のアカウントと社員が使うアカウントを区別します。しかし、家庭で使っているようなアカウントの場合は、もう少し緩くてもいいでしょう。さらに言えば、会社のようなポリシーをきつくした環境を作ってしまうと、家庭の PC ではオーバースペックでややこしいことになります。

実際、私の環境では Windows 11 Pro に Microsoft ID で作った PC に対して、リモートログインができません。おそらくドメインサーバーを入れればいいんですが、それはオーバースペックですよね。そういう、もともとのローカルネットワークでの環境に Windows 11 の Microsoft ID アカウントの強要は適していないということです。
(実際の原因はわからないのですが、度々発生するので、リモートデスクトップ用のローカルアカウントを作成しています。多分、Wi-Fi 等のネットワーク関係だとは思うんですが、ちょっとわからなすぎです)

で、先の手順で作る訳ですが、実は 3 の部分を実際にやったことがないのです。消せるはずなのですが、先に書いた通り「インストール時に使ったアカウントを削除すると、えらいことになる」ことが多かったので、最新の Windows 11 ではよくわかりません。

Microsoft アカウントで作成

最初のアカウントは通常の Microsoft アカウントを使います。新規に作ってもいいのですが、実験用メールを使いまわすのは大変なので、業務用のアカウントを用意しておくとよいです。OneDrive の同期や位置情報などをは切っておきます。

スマホの Authenticator で認証を通します。

「新しい PC としてセットアップする」を忘れないように。

Microsoft アカウントでログインできた状態です。

さて、powershell と立ち上げると、ホームディレクトリが「c:\Users\masud」になっていて、激おこなんですよ。後から、ディレクトリを変更することも可能なのですが、やめておいた方がいいです。せめての Microsoft アカウントの @ の前を取ってくればいいのですが、これが暫く放置されています(次のアップデートで、フォルダーが指定できるようです)。

バッチを作るときには環境変数 %USERPROFILE% を使えばいいのですが、wsl とかで指定したい場合にはもっと簡単にしたいですね。他にも自前のツールを使う時は、c:\users\masuda でもいいわけで、これは masud から masuda に変更したいです。

ローカルアカウントを作成

設定 → アカウント → その他のユーザーで、ローカルアカウントを作成します。

「このユーザーのサイン情報はありません」をクリック。

「Microsoft アカウントを持たないユーザーを追加する」で、ローカルアカウントを作ります。

ローカルアカウント「masuda」を作成します。

「アカウントの種類」で「管理者」に変えます。

「標準」なところを「管理者」に変えておきます。

あらためて、管理者 masuda で入り直します。

無事、c:\users\masdua のフォルダーができています。

Microsoft アカウントの方を削除

普段使いをローカルアカウントの masuda を使い、Microsoft アカウントは使いません。ただ、使っていないのに管理者権限のアカウントが残っているのはセキュリティ上、気持ち悪いですよね。OneDrive や Office 関係まわりもあるので、Microsoft アカウントのほうを消してしまいます。

ローカルアカウント masdua に入った状態で「設定」→「アカウント」→「その他のユーザー」で、Microsoft アカウントのほうを「削除」します。

実験用に入れただけなので空っぽにして大丈夫です。

念のために、再起動してローカルアカウントしかないことを確認します。

ローカルアカウントなので OneDrive の同期はありません。Windows Store は見ることはできるのですが、ダウンロードはできません(別途、Microsoft アカウントを入力する必要があります)。

Windows の Copilot は使えませんが、Edge にある無料の Copilot は使えます。

おそらく Micorosft 関係を使わない、GitHub や Node.js とかで開発する分にはこっちで十分だと思います。VS code でも大丈夫かもしれない。

あとは、Chrome 入れて Google アカウントで運用するとか、家庭用 PC であったり実験用に運用する場合はこっちでいいはずです。

カテゴリー: 開発 | Windows 11 でローカルアカウントを作る方法 はコメントを受け付けていません

C# のメモリーリーク現象の紹介(検証コード付き)

一連の C# dis から飛び火?したのか、Huomoto san のポストに、さまざまな「GC だとメモリリークしない」意見が飛び交っていますが、C# でもメモリリークしますよ、ってのを証左しておきます。

参照カウンタで制御しているから、GC(ガベージコレクション)が起こってメモリーリークはない、と思い込んでいると、実は GC のあるプログラム言語(Java も同じ)で「メモリーリーク関係の対策を見落とす」ことになるので危険です。普段使っているときには、あまり気にしないのですが、リアルタイム制御とか増減のある大量データを扱うときに、気にしておいてください。なんか、イイ感じにコードを高速化したと思ったら、その先でメモリーリークを起こすことになります。
当然、リークが発生してしまうこと自体が「設計ミス」というのは同意はしますが、リークが発生する可能性を否定しまうと、設計考慮の範囲外になってしまって、設計ミスにすら気づかないことになります。後知恵的に設計ミスや考慮不足をなじるよりも、境界値に近いパフォーマンスを得るようなときは転ばぬ先の杖、石橋を叩いて渡る気分でいきましょう。もちろん、普通の Web アプリを作る場合にはあまり必要ないのですが(実際には、Web サーバーのときは必要なんだけど、それは別の機会に)

リフレクションでオブジェクト生成時

検証コードを一から作るのは面倒なので、ベースは Copilot に作って貰います。Copilot の出した生コードは、そのままでは駄目なので、多少手を加えていますが、一応合格点は上げられると思います(考えているかも、という意味で)

プロンプトは、こんな感じ。手元の適当な生成AIチャットでも可能でしょう。

C# でメモリーリークをする、サンプルコードを作って。リフレクションを使って create object を大量にすると参照されるポインタがなくても、手動の GC を動かさないとメモリが解放されない状態になる

using System;
using System.Collections.Generic;
using System.Reflection;

namespace MemoryLeakDemo
{
    class LeakyClass 
    {
        public byte[] Data = new byte[1024 * 1024]; // 1MB
        public LeakyClass()
        {
            // ランダムにデータを初期化
            new Random().NextBytes(Data);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            List<object> leakyList = new List<object>();

            for (int i = 0; i < 5000; i++)
            {
#if false
                // リフレクションでオブジェクトを生成
                Type type = typeof(LeakyClass);
                ConstructorInfo ctor = type.GetConstructor(Type.EmptyTypes);
                object instance = ctor.Invoke(null);
#else
                // 通常の方法でオブジェクトを生成
                LeakyClass instance = new LeakyClass();
#endif
                // Finalizer を抑制(GC の対象になりにくくなる)
                // GC.SuppressFinalize(instance);

                // 明示的に参照を保持(GC が回収できない)
                leakyList.Add(instance);

                Console.WriteLine($"Created instance {i}");
            }

            Console.WriteLine("大量のオブジェクトを生成しました。GC を強制しない限りメモリは解放されません。");
            Console.ReadLine();

            // 解放する筈
            leakyList.Clear();
            Console.WriteLine("leakyList の解放");
            Console.ReadLine();

            // 手動で GC を動かすことでメモリを解放可能
            GC.Collect();
            // GC.WaitForPendingFinalizers();

            Console.WriteLine("GC を強制実行しました。");
            Console.ReadLine();
        }
    }
}

type.GetConstructor のように、DI を使うとメモリーリークが発生しやすいです。GC が追跡しにくくなるんですね。実は、このコードだと new LeakyClass() でもリークするので、検証コードとしてはいまいちなんですが、まあ、リークのサンプルコードということで。

  1. leakyList.Add(instance) で、参照を保持しているが、
  2. leakyList.Clear(); でメモリを解放していると思ったが、解放はされない
  3. 明示的に GC.Collect(); が必要

おそらくスコープの関係だと思うのですが、3 の時点で、GC.Collect() を実行しても解放はされません。

これは、.NET のガベージコレクションの解放が3種類あって、世代ごとに解放されるタイミングが違うからです。大量に取得した new LeakyClass のインスタンスは、leakyList.Clear() した時点で解放されるように見えますが、この瞬間では解放されません。メモリの状態や生存期間(lifetime)によっては、GC.Collect の呼び出し後も残ることが多いです。.NET の GC の場合、GC メモリが自動拡張されるために、物理メモリを圧迫してしまうリスクがあります。この場合は、コンソールで1つしか動かしていないのですが、Web サーバーでの内部処理やアプリケーションサーバーのような扱いをしているときは、このような不意なメモリ取得は他のプロセスに悪影響を与えてしまいます。

解決案としては、LeakyClass 専用のアロケーターを作ります。5000件ぐらいだと IDisposable を実装して内部メモリを外出しにするとか、リークの量を減らす方法も活用できます。ゲームサーバーだと 100万件とかが多いでしょうから、もう少し別な対処をする必要があるでしょう(ゲームの方は知らないので、調べてみてください)

相互参照によるメモリリーク

もうひとつ典型的なリークのパターンを紹介しましょう。リスト構造の中で、各オブジェクトが相互参照や循環参照になっている場合です。これは参照しているのだから、参照カウントで GC の対象にならないので合ってはいるのですが、このオブジェクト群を管理しているリストやルートノードを解放しても、その先のオブジェクトが解放されることはありません。
これは、GC の仕様で、解放の深度はそこまで追わないという設計になっているためです。追えないことはないのでしょうが、GC のためにそこまで実行時に時間を掛けるのは馬鹿馬鹿しいので、実装者のほうでメモリを管理してね、という「意図的なメモリーリーク」です。
なので、この意図的な GC の設計を知らないと、相互参照をさせてリークしてしまうんですね。つまりは「仕様です」というやつです。この GC 設計は .NET 特有なのか、JVM の GC にも使われているか私は知りません。

相互参照をしたオブジェクトのリストを作っておいて、おおもとの参照ポインタを消しても相互参照したオブジェクトが残ってしまう例を示して。
using System;
using System.Collections.Generic;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace CyclicReferenceLeak
{
    class Node
    {
        public Node Partner;
        public byte[] Payload = new byte[1024 * 1024]; // 1MB

        public Node()
        {
            // ランダムにデータを初期化
            new Random().NextBytes(Payload);
        }

    }

    class Program
    {
        static void Main(string[] args)
        {
            List<Node> rootList = new List<Node>();

            for (int i = 0; i < 5000; i++)
            {
                Node a = new Node();
                Node b = new Node();

                // 相互参照を構築
                a.Partner = b;
                b.Partner = a;

                // rootList に追加(GC の対象外)
                rootList.Add(a);
            }

            Console.WriteLine("相互参照したオブジェクトを 1000 組作成しました。Enter で rootList をクリアします。");
            Console.ReadLine();

            // rootList をクリア → おおもとの参照が消える
            rootList.Clear();
            Console.WriteLine("rootList をクリアしました。GC を強制しない限り、相互参照のためメモリは解放されません。");
            Console.ReadLine();

            // GC を強制実行
            GC.Collect();
            GC.WaitForPendingFinalizers();

            Console.WriteLine("GC を強制実行しました。");
            Console.ReadLine();
        }
    }
}

これも Copilot に作って貰ったもので(つまりは、Copilot の codex のモデルには GC のメモリリーク関係の情報が入っているということですよ)、Node の a と b が相互に参照しています。保持リストとして rootList.Add を使っているのですが、rootList.Clear() の瞬間にはメモリは解放されません。これも GC の仕様です。そのあとに、GC.Collect() を実行しますが、以下のように、この PC ではメモリは解放されません。
この業務 PC は、先日メモリを豊富にしたばかりなので、10GB 程度ではびくともしないんですよね。もうちょっとチープなメモリ(8GBとか16GBあたり)で試してみると、OS ごとロックされるか、アプリケーションが固まるのが判別できるはずです。Windows 上でやると、Swap ファイルを食い尽くして C ドライブの SSD がいっぱいいっぱいになるので、やめておいたほうが良いです。OS が落ちる現象は、メモリーリークで落ちるのではなく、swap ファイルの食い尽くしで OS が利用するテンポラリファイルが作れなくなったときです。ブルースクリーンになりますね。

正しく検証したい場合は、Hyper-V で 8GB 程度の Windows 11 を作成して、その中で実験するとよいです。メモリを制限させると、swap ファイルを作成する様子がわかります。ただし、上記のようなプロファイルを見るために Visual Studio を入れないとけないのが結構手間ですね。仕事でやると 1,2 日がかりというところでしょうか。

参考書

「Garbage Collection」という洋書があって、これはほぼ唯一の GC の解説書です。他にも 「プログラミング .NET Framework」の本にも GC の章はあるのですが、あまり解説はない(GC.Collect あたりのざっとした解説)ので、まあ、これを買うしかないですよね(と言ってみるテスト)。

ただ、これを買ったのは15年程前なので、いまだといくつか出ていますね。GC の世代とか、マーク&スイープ方式の詳しい解説とか図つきであります。

余談ですが、java の場合は -vm でメモリサイズを制御できるので、.NET 環境のような swap を食い尽くすことがありません。ただし、java の場合は -vm のメモリを喰い付くしてしまってプログラムが不意に止まります。これ、どちらを優先するかにもよるのですが、運用時にアプリが落ちないことを優先=.NETの GC にするか、運用時に OS が落ちないようにするか= Java の GC ということです。今だとメモリが潤沢にあるので、Java の -vm を大き目に取っておくことができますが、サーバー運用のときは -vm を大きく取り過ぎると他のプログラム(他のプログラムも java だったりする)を圧迫してしまうので、.NET 方式が良かった時期もあるのです。これはどちらの方式も取れるといいんですが、今だとできるのかな。10年程前 .NET のほうで調べたときには、-vm 方式が使えないので、先の紹介したような独自アロケート方式で対応することにしたのです。

カテゴリー: 開発 | C# のメモリーリーク現象の紹介(検証コード付き) はコメントを受け付けていません

Linux + SQL Server + dotnet 環境を構築する(但し、Docker 上で)

おそらく、発端は次のポストだと思うのだけど、よくわからん…が、その後に続く「Mac でにインストールするときに~」が気になったので、備忘録として構築手順を残しておこう。

Linux で SQL Server が動くと言われた当初のころから、ちまちまと Linux に入れたみたことがあるのだけど、なかなかうまくいかない。当時は、Linux + dontet の環境が貧弱だったせいもあるし、SQL Server on Linux がまともに動いていなかったというのもある。じゃあ、今はどうなのか?というと、(かなりズルいが)Docker で構築するのがベストである。Docker 上ってのが Linux なのかが不明なんだけど(私としては、Docker 上ってのと Linux 上ってのを分けたい派なんだが、これは後述しよう)、ひとまず Docker ≒ Linux 上という意図?のもと、それだったら今ならなんとかなりますね、程度には何とかなる状態になっている。ちなみに、macOS 上はわからん。そもそも、macOS 上で開発環境ならばまだしも、実運用環境はあり得ませんよね(と暴言を吐いておく)。まあ、mac server を使うのもそれなんだけど、少なくとも現時点ではクラウド上と言えば Linux と一般的には決まっている(これも Azure 上では Windows Server が動いていることは伏せておく)。あくまで、一般的な SE やプログラマの範疇で、開発環境ないし運用環境を考えてみた結果、

  • 開発環境の構築は、いわゆる LAMP 環境の方が便利ではあるが、SQL Server も Docker を利用して手軽に構築できるまではできている。
  • クラウド運用環境としては、Azure, AWS と分かれる。AWS 環境では SQL Sever は自前で構築しないといけないので面倒がだが、Azure 環境では SQL Server が用意されているので、これを使うことができる。なお、Azure では、SQL Server のほうが MySQL を立てるよりも安いので「安価」という点でも有利となる。AWS の場合は、当然のことながら、MySQL や PostgreSQL が選択肢となる。
  • 運用環境において、レコードサイズが少ない(1億件以下)となると、MySQL や PostgreSQL でもよいのだが、10億件となると Oracle や SQL Server を考えざるを得ない。なお、NoSQL として key-value 型の分散データベースを考慮するのも必要ではあるが、ここは一般的なリレーショナルデータベース(生産管理や物流追跡など)を使いたい場合とする。実際のところ、生産分野では key-value 型だとちょっと困る(設計上の制約というのもあるだろうが)

製品の購入やランニングコスト、サポートやセキュリティ条件などがあり、どの構成を使うと良いという訳では必ずしもない。
ちなみに、クラウド上に 10 億件のデータを置く場合、データベース容量のランニングコストが並みではない。常にストレージとして 2TB ぐらいクラウド上に配置されてしまうので、この固定費が馬鹿にならない。また、データをアップロードするにしても 2TB のデータは容易ではない。その場合は、素直にオンプレの PC でデータベースを構築したほうがよい。今後の MCP サーバーとかは、オンプレ PC を使ったほうが安価になるはずだ。社内 DB の検索とかにいいんじゃないですかね?

ただし、端的に言えば

のように、Linux + SQL server + dotnet の環境はお薦めしない。止む無く、既存の SQL Server のデータをそのまま持って行きたい場合に限るだろう。運用を考えれば、

  • Windows Server + SQL Server + dotnet
  • クラウド上の Azure SQL Server + Azure Functions でマイクロサービス
  • テスト用バックエンドとして Azure 上に SQL Server + dotnet 環境で web api サービスあるいは MCP サービス

に限るだろう。

Linux + SQL Server + dotnet 環境を Docker 内に構築する

忘れられているが、Windows Server の Docker コンテナ(ホストではなく)というのがある。忘れ去られているが。それを使ったほうが SQL Server は安定するのではないか、と思うのだが、GUI がない場合 SQL Server の設定は結構面倒なので、素直に Linux Docker を使ったほうが便利です。

実は、構築の仕方は microsoft が出している。
Docker: SQL Server on Linux 用のコンテナーを実行する – SQL Server | Microsoft Learn https://learn.microsoft.com/ja-jp/sql/linux/quickstart-install-connect-docker?view=sql-server-ver17&tabs=cli&pivots=cs1-bash

出してはいるんだけど、なんかうまいかないんですよね。というか、この記事だけだと要件に足りないんですよ。機能しか載っていないので。

要件としては次を考えます。

# 要件定義
- Linux Docker で動作する SQL Server + dotnet 環境を構築する
- SQL Server と dotnet は Dockerfile で動かし、Docker compose を使う
- donet 環境では web api を提供する

という形になるので、SQL Server と dotnet(web api)の2つの Dockerfile が必要になります。
以前は、この環境を構築するのに Microsoft が提供する SQL Server 用の dockerfile と、.NET Core の Dockerfile を組み合わせてあれこれやらないけなかったのですが、いまだと Copilot に作って貰えます。

docker-compose.yaml

services:
sqlserver:
image: mcr.microsoft.com/mssql/server:2022-latest
container_name: sqlserver
environment:
SA_PASSWORD: "Zaq!2wsx"
ACCEPT_EULA: "Y"
ports:
- "11433:1433"
volumes:
- sql_data:/var/opt/mssql
networks:
- backend

dotnetapp:
image: mcr.microsoft.com/dotnet/aspnet:9.0
container_name: dotnetapp
build:
context: ./dotnetapp
dockerfile: Dockerfile
ports:
- "5000:80"
depends_on:
- sqlserver
networks:
- backend

volumes:
sql_data:

networks:
backend:

ディレクトリ構成

project-root/
├── docker-compose.yml
└── dotnetapp/
   ├── Dockerfile
   └── [your ASP.NET project files]

dotnetapp/Dockerfile

FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /app
COPY . .
RUN dotnet publish -c Release -o out

FROM mcr.microsoft.com/dotnet/aspnet:9.0
WORKDIR /app
COPY --from=build /app/out .
ENTRYPOINT ["dotnet", "webapi.dll"]

おそらく cli codex とか claude code でも作れる筈です。

都合上、SQL Server のポート番号、.NET のバージョンを変えています。確か、以前やったときは .NET9 がうまく動かなくて .NET8 にしたのですが、現在 .NET8 がディスコンになったので .NET9 で動かないと不味いんですよね。果たして。

docker compose up -d

できあがったら、SQL Server Managemnet Stuido で接続してみます。

Docker 内のポートにつなげるので「localhsoat,11433」を使います。

無事接続できているので、SQL Server on Linux in Docker は大丈夫そうですね。このあとは、dotnetapp ディレクトリ内に dotnet new webapi とかして、Web API 用のプログラムを作ればいいわけです。

  • dotnet new webapi でプロジェクト構築
  • ddl.sql で各種のテーブル作成
  • ddl.sql に従って CRUD できる openapi.yaml を作成
  • openapi.yaml に従って、model クラス群を作成
  • oepnapi.yaml に従って、controller クラス群を作成

という手順になります。ddl.sql は create table の羅列でよいので、適当に copilot に作って貰います。その後は、好きな AI エージェントを使って、先の手順を動かせば ok です。これえひな形となる web api の .NET プロジェクトが作成できます。

Linux 上で SQL Server を使うメリットは?

先にも書きましたが、Linux 上で SQL Server を動かすメリットはほとんどありません。あるとすれば、

  • 10億件程度レコードがあるが、Oracle では高い(SQL Server もそこそこ高いが)
  • LINQ が使いたい(Laravel の Eloquent ではなく、Ruby の Acitve Reacord でなく、Node.js の comporess ではなく…)
  • SQL Server が手慣れていて、MySQL とか PostgreSQL だとよくわからない。
  • 既存の SQL Server のデータを移行しないといけない。カラム名が日本語の場合とか。これが一番多いと思われ。

って、ところですね。Docker で構築するのだったら、同じような手順で Linux + Laravel + MySQL という組み合わせも手軽にできるので、実は大差がありません。これも、自分にとって手慣れているか否かの違いです。開発環境として試験的に使いたいときは、MySQL や PostgresSQL よりも SQL Server + LINQ の組み合わせの方が早いです、という .NET 開発者向けです。

じゃあ、運用上どうなんだ?という話と、運用時に Docker 上でよいのか?という疑問があります。Docker イメージとしては microsoft 社が提供するる”mcr.microsoft.com/mssql/server:2022-latest” を使えば、インストールが簡単です。が、当然のことながらオンプレの PC などに直接入れる場合はここがハードルになります。ほかにも、10億件のレコードの場合 Oracle という選択肢があります。Oracle の場合も SQL Server と同じように Docker イメージが用意されています。

oracle/docker-images: Official source of container configurations, images, and examples for Oracle products and projects https://github.com/oracle/docker-images

実は Oracle の場合は古いバージョンの Docker イメージとか設定が用意されていて、移行とかに楽なんですよね。経験則ではありますが、Oracle の場合は設定ファイルが別口になっているので、データベースファイルが潰れたときにでも設定ファイルが残っているので、これを使ってデータの救出が可能なのです。このために昔は Oracle を使っていたものなのですが(Unix 上で SQL Server が動かないというのも理由のひとつですが)、いまはどうなんでしょう?

あと、SQL Server はクライアントからの接続にパイプを使っているときが一番高速で TCP/IP 経由だとちょっと遅いんですよ。それに、SQL Server のファイルアクセスは特殊で、このあたりは Windows Server に最適化されているのですが、Linux 版の場合はどうしても posix 経由になってしまうのでパフォーマンスが落ちがちです。が、そこまで気にするのもどうかと思うし、そこまでチューニングしないといけない環境の場合は、Windows Server + SQL Server を選びますよね。なので、Linux + SQL Server の組み合わせははどうしても中途半端な気がするのです。
そうでもあっても、.NET (特に LINQ)が使いたい場合には、dotnet + SQL Server の組みわせがよいので、運用パフォーマンスよりも、開発パフォーマンス(不具合修正なども含めた保守・改修のパフォーマンス)を優先する場合には、Docker 上でもアリかなと思うのですが、果たしてどうでしょうか。

カテゴリー: 開発 | Linux + SQL Server + dotnet 環境を構築する(但し、Docker 上で) はコメントを受け付けていません

キーエンス社の営業システムを再考察してその先へ

定期的にキーエンスの営業力の高さが流れてくるのだが、実際のところどういう情報は巷には流れているのかを、拾い集めてみる。いわば、「30台で、家か墓が立つ」といわれている K 社の噂は本当なのか?それを支えているものは何なのか?とか、以下は Copilot などを駆使して探してみる。

ビジネス視点で考えると、K社の方法はファブレスという工場を持たない営業特化に絞っているところが大きい。もちろん、顧客ニーズの取り込みとか、いろいろあるわけだが、外部からの分析としては、これがわかりやすい。

キーエンスの強さの源泉。最強の営業の型「PSS」とは | SFA JOURNAL
https://next-sfa.jp/journal/sales/pss/

既に名前をついている。おそらく、営業方式のカンファレンスとかで使われているんじゃないだろうか。PSS(Professional Selling Skills)で検索すればいくつも出てくる。

  • オープニング
  • プロービング
  • サポーティング
  • クロージング

他にも四段階をステップとして、営業活動を合理的に示して、横展開できる状況を作っているのが K 社の営業方法である。なので、上記のステップを営業している個人のみが使っていても K 社には追い付けないし、合理化の恩恵が受けられない。これが、K 社の営業として同じ形で横展開される形で浸透しているからこそ、同じスタイルを貫けるし、それが客先に対しても同じ品質(営業としての)が得られるという安心感(継続であろうが新規であろうが)があると思われる。

営業マンには服装ルールがあって「白シャツでジャケットを脱がない」が徹底されている。白シャツなので、赤シャツだったり柄物だったりしない。普通の会社の営業では個性を演出するためにネクタイやシャツなどを工夫するところだが、K社では「営業」という型を徹底するために、白シャツと決まっている。

キーエンスでは「シャツは絶対白」と決まっている – 日本唯一の経営者専門スーツ仕立て屋 イルサルト
https://ilsarto.net/blog/archives/21559

そのあたり、Java の方(型)ですね、と言いたくなってしまうプログラマでもあるが、まあ型なんです。実は、これは内勤の派遣や開発者にも適用されていて、白シャツとネクタイの色が制限されている。内勤の場合、外部から見えないからどうでもいいような気がするが、私服なんて持っての他。つまりは、アジャイル開発とかには適さない体制が内規として組まれている。

[246] 営業所に赴任してから教えられるキーエンスのルール⑪【当番とお昼休み】:元キーエンス(→アンリツ)社員の回想[246] | アンリツ | 東京・四ツ谷の経営コンサルタント 立石シゲオ中小企業診断士事務所
https://www.tateishi-smemc.com/2019/05/30/%ef%bc%bb246%ef%bc%bd-keyence-_-sales-office-rules%E2%91%AAresponse-for-lunch-time/

さらに言うと、K社では昼休みがは短い。たまに、着替えは勤務時間に入るのか否か、という話が X に流れることがあるが、K 社では昼休みは、午後1時に着席していないといけない状態になる。昼に外出禁止のところもあるようだが、外出は自由である。しかし、時間内に戻ってこないといけないので本社ビルのエレベーターは激混みである。時間通りに戻ってきては間に合わないので、少し前に戻らないといけない。当然、出社もそのようなエレベーターラッシュがあるわけだが、社員や長めの契約社員の方は普通である。ちなみに、遅刻をするとビル下の警備員ににらまれるのである。まるで、高校生のようだw

キーエンスの厳しい社内ルール4選を元社員に聞いてみた|キャリアスイート(ハイキャリア転職プラットフォーム)
https://note.com/career_suite/n/nedef4ac29cd9

あと、基本的に就業時間中は私語禁止である。どうも営業活動であっても内勤の会社であっても私語禁止なので、気が休まる時間がない。休憩所はあるにはあるのだが、ゆったりとした気分にはならない。休憩室に椅子とかはない。当然のことながら皆さん白シャツである。

一般的な IT 会社に比べると、K 社は厳しい社内ルールが敷かれていて、到底あたらしい社員が入らないんじゃないかと思われるが、なにせ2000万という年収は堅い(きちんと馴染めばの話だろうけど。営業のほうは、営業ノルマがあるので大変そうだが、技術者採用の場合は「作れ」ばいいので、比較的達成しやすい。ただし、技術者は 1/10 ぐらいなので狭き門である。もちろん、白シャツと私語厳禁には耐えないいけない。あと、技術者のほうは徹夜は当たり前なので、就業時間はあって、無きがごとしだ…と聞く)。このめに、年収につられてほいほいと新入社員がやってくる。まあ、年収と福利厚生ぐらいしか外側から見えないので、それもまた良いだろう。

で、営業力に戻ると、先の PSS(Professional Selling Skills)による合理化が徹底している。K社内で PSS と言っているかどうかわからないが(実は聞いたことがない…と聞いた)、営業システムなどを含めて数億円をかけてシステムを組み、営業への合理化をすすめている。合理化というとコストダウンのように見えるが違う。営業活動をするために、目標達成のための無駄を省き、達成のためには資金をつぎ込むという体制が K 社にはある。これは、営業ノウハウ自体を全社に横展開することで成り立っている。ゆえに、社員が白シャツであったりネクタイの色が揃っていたり、営業スタイルが皆同じであったりするのに通底しているのだ。

だから、それが悪いとは言わないし、実際に粗利は50%を越える営業成績を残しているし、実績がある。ただし、そこに再現性があると言えばどうだろうか?と悩むところでもある。

ちなみに、同じような営業スタイルは、他業種としてはパーソルやリコー(のリコピーの時代)やトヨタ(のトヨペットの時代)がある。徹底的に顧客の要望を分析してい、顧客の求めるものを掘り起こし、顧客の要求を素早く解決する、という方法を取っている。K 社がリコーとトヨタと異なるのは、いわゆるファブレスであり工場を持たないことだ。パーソルは工場を持たない(派遣社員だけを持つ)ので似たスタイルと言える。

余談だが、一方でラピダスがある。先日、NHK 特集で半導体復活の特集を組んでいた。

1兆円を託された男 〜ニッポン半導体 復活のシナリオ〜 – NHKスペシャル – NHK https://www.nhk.jp/p/special/ts/2NY2QQLPM3/episode/te/NWQKL47GY6/

ラピダスの場合は工場そのものである。しかし、80年代の半導体産業とは異なり、設計と生産ラインを一体化しない。ラピダスは生産ラインのみ持つという形式で、半導体設計はやらない。他社が設計したものを作るというスタイルを持つ。実は、きょうび、半導体の設計と量産を同時にやることはない。これは TSMC でも同じだ。ソフトウェアを駆使しての設計(ハードウェアの設計)と、ソフトウェアを駆使しての量産ラインの保持(ハードの製造)とは異なるという形になる。あえて、ソフトウェアを絡めるのは、ここにソフトウェア開発者としての余地があるためだ。もちろん、それぞれの専門知識(ドメイン知識)が必要なのであるが、ハード特化とは異なる形があるだろう。

と、ラピダスと K 社のアピール面は異なる。K 社の場合は、徹底的に合理化された営業スタイルとバックグラウンドにある営業システムに強みがある、今後もそうだろう。一方で、ラピダスの場合は(まだ成功しているわけではないが、あのロードマップを見ると、成功はしそうだ。少なくとも試作はできている)、専門知識を活用した上で、一点突破のスタイルで突き進む。まさに技術力と品質が営業力となっている。

もちろん、K 社が対象となる顧客は数万社であり、ラピダスの対象とする顧客は 10 数社というところだろうから、営業スタイルが変わっていても問題はない。逆に言えば、対象となる顧客の象が異なれば、K 社の営業スタイルを適用する必要はないということだ。まあ、パーソルのように逆も真ではあるのだけれど。

では、非 K社スタイルでの営業活動を Copilot と一緒に考えてみると、雑談や創造性を活用した形での「共感型営業」という単語が出てくる。K 社が顧客との「目的共有」というスタイルで進むのであれば、対抗する営業スタイルとして「共感共有」からはじめたらどうか、という提案だ。端的に言えば、アジャイル型で雑談を大切に、スタイルに引っ張ろうという私の意図的なものではあるのだけれど、合理化スタイルが苦手な場合は、別の方法を取ればよいんじゃないですか?ということです。別にK社と対抗したいわけではなく、K社ができない場所を取って行けばいいということですね。

おまけ

moonmile/omitt-chan: 見積もり依頼作成ツール
https://github.com/moonmile/omitt-chan

共感というか、見込み客自身が IT 屋に発注するために、自ら見積もりができるツールの試作です。非 IT 業者向けです。OpenAI API を使っているので、ローカルで動かしてみてください。参考サイトは https://omitt-chan.vercel.app/ にあります。そもそも、どう見込み客にリーチするかどうかは問題があるのでが(苦笑)、これ、AI エージェントを使って高速プロトタイプ作成をしたらどうなるのかの一環なので、そういう意味でのお試しです。ちなみに、この React コードは内部にあるプロンプトも含めて1日程度で出来ています。

カテゴリー: 開発 | キーエンス社の営業システムを再考察してその先へ はコメントを受け付けていません