地平線まで行ってくる。

記録あるいは忘備録。時には検討事項。

picoclawをollamaとdocker composeで利用してみる。

ollamaでpicoclawをollamaで動かしたくなったので、docker composeで出来るようにしました。大したこともないですが、メモまで。

 

bwgift.hatenadiary.jp

 

docker-compose.override.ymlをオリジナルのdocker-compose.ymlと同じディレクトリに設置します。セキュリティの観点については詰めていきたいところですが・・・。

 

CPUもしくはCloud版

docker-compose.override.yml

services:
  ollama:
    image: ollama/ollama:latest
    container_name: ollama
    volumes:
      - ollama_storage:/root/.ollama
    # もしホストのブラウザ等から使いたい場合のみ 127.0.0.1:11434:11434 を追加
    restart: always

  picoclaw-agent:
    depends_on:
      - ollama

  picoclaw-gateway:
    depends_on:
      - ollama

volumes:
  ollama_storage:

 

起動方法や停止方法はオリジナルと一緒です。

github.com

 

起動したらOllamaのコンテナで

docker compose exec ollama bash

で`ollama run ....`のコマンドで利用したいモデルを呼び出せるようにしておきます。Cloudで初回の場合はデバイスの登録をしておきましょう。

 

GPUもいる場合

gpuで動作させる場合は`docker-compose.override.yml`にgpuを認識させます。

services:
  ollama:
    image: ollama/ollama:latest
    container_name: ollama
  deploy:
     resources:
       reservations:
         devices:
           - capabilities: [gpu]

(以下略)

 

picoclawをopenai互換とdocker composeで利用してみる。2026/2/14時点

PicoClawはOpenClawのGo実装版でコンパクトです。ローカルLLMやOpenAI互換の他のプロバイダで利用するとうまくいかなかったので、メモを書きました。答えは、vLLMで使おう・・・これだけです。もともと組み込み以外のプロバイダはOpenRouterへの設定に流れます。情報やドキュメントには、色々書いてあります。今の瞬間は、この仕様の様です。Bugに近い仕様なので近日訂正されるでしょう。

 

軽量なので、複数立てて会話させるのも良いかも。

 

github.com

 

OpenAI互換用設定

さくらのAIエンジンだと以下になります。

config.json

  "agents": {
    "defaults": {

      "model": "vllm/gpt-oss-120b",

    }

(略)

    "vllm": {
      "api_key": "{secret api tokens}",
      "api_base": "https://api.ai.sakura.ad.jp/v1/"
    },

ポイントだけ。

 

Docker composeとollamaコンテナへの接続

docker composeでの起動もサポートされました。同じホストに立てたollamaで動作させる場合は、ネットワークにhost.docker.internalを入れ込みます。頻繁にupdateが繰り返されそうなので、overrideで追加します。以下のファイルをdocker-compose.ymlと同じディレクトリに入れておきます。

 

docker-compose.override.yml

services:
  picoclaw-agent:
    extra_hosts:
      - "host.docker.internal:host-gateway"

  picoclaw-gateway:
    extra_hosts:
      - "host.docker.internal:host-gateway"

なお、api_baseもhost.docker.internal指定します。

 

回答例

明日の献立の例を考えてみました!

🔥 豚キムチ春雨献立(NHKニュース検索結果から)
猪肉キムチ(ピリ辛で野菜とのバランスが良い)
春雨の茶碗蒸し(温かい食感で一品目へスムーズ)
野菜スープ(体を温めつつ簡単に作れます)

💡 他にも「お米+ささみ+ねぎの天」など簡単献立も可能です!
明日の献立に困ったら、ぜひお気軽にお知らせくださいね 😊

 

ResarchツールをローカルLLMで動かしてみる。

Deep Researchのような調査ツールをローカルLLMと組み合わせてみたら、どこまで使えるのでしょう・・・と思って、作ってみました。この手のレポジトリはすでにあると思います。

狙い

1. ローカルLLMの軽量級であるollamaとgemma3:4b-it-qatの組み合わせでどこまで使えるのかな。
2. GoogleのJules+Antigravity環境でどこまで楽できるのか。

結果

1. ローカルLLMの軽量級であるollamaとgemma3:4b-it-qatの組み合わせでどこまで使えるのかな。

出力の不安定さを承知で作ると全然使えるレベルです。gemma3:4b-it-qatは、小さいわりに日本語は自然です。gpt-oss-120bくらいあれば、結構しっかりすると予想しています。他の小型モデルを実働させて評価するというのもありですね。

2. GoogleのJules+Antigravity環境でどこまで楽できるのか。

「Antigravityでとりあえず動くようしてmainにマージする→Julesでsuggestionを提案させてPRさせる→AntigravityでPRを検証しマージ」のループがいい感じです。テストコードを時折充実させるように指示を出しました。正しいやり方かは分かりませんが、AIがとっ散らかって明後日の方向に行くことも少なくなりました。これでいいのでしょうか。たぶん、Googleさんがどこかに使い方ドキュメントとしてまとめているのを見落としているのかもしれません。

 

所感

なんかやかで、下調べが重要でした。

 

実行画面

 

レポート出力例

## 日本の選挙制度改革の提案と実現可能性の検討

日本の選挙制度は、民主主義の根幹を支える重要な基盤ですが、近年、その有効性や公平性について様々な議論がなされています。本稿では、既存の選挙制度の課題を分析し、その解決に向けた改革の提案と、それらの実現可能性について検討します。特に、過去の試み、比例代表制小選挙区制のバランス、政党復活税、選挙区再編、投票率向上策、海外事例、シミュレーションといった要素を総合的に考察します [1]。

**1. 既存の選挙制度における課題**

日本の選挙制度は、小選挙区比例代表並立式(以下、PR-MMP)を採用しています。このシステムは、地域に根差した政治を促進する一方、小党の議席獲得を困難にし、大二党化を助長する傾向があります [1, 2]。具体的には、以下の課題が指摘されています。

* **比例代表制の弊害:** 比例代表制では、政党票獲得戦略が重視されるため、政策を打ち出すよりも、票を集めることに重点が置かれる傾向があります [3]。また、党派性強化を招き、政策の対立を激化させる可能性も指摘されています [6]。
* **小選挙区制の弊害:** 小選挙区制では、地域ごとの政治的対立が激化し、候補者質が低い場合も議席を獲得する可能性があります [4]。また、小選挙区制の地域偏向は、地方の政治力を弱体化させる可能性があります [7]。
* **重複立候補制度:** 重複立候補制度は、政党が候補者数を増やし、選挙戦を激化させる要因となります [10]。また、有権者の負担を増大させる可能性も指摘されています [8]。
* **低投票率:** 日本の選挙における投票率が低いことは、民主主義の課題として認識されています [5]。投票率向上のための対策は、選挙制度改革と並行して検討する必要があります。

**2. 改革の提案**

上記の課題を踏まえ、以下の改革を提案します。

* **比例代表制の改善:** 比例代表制において、政党の政策を明確に示すための規制を設けることを検討します。例えば、政党が政策を公表する義務を課したり、政策の評価を有権者に提供したりする仕組みを導入するなどが考えられます [1]。
* **小選挙区制の改革:** 小選挙区制における候補者質向上を目指し、候補者選定の透明性を高めるための仕組みを導入します。例えば、候補者の公開討論会を実施したり、有権者が候補者の情報を容易に確認できるウェブサイトを整備したりするなどが考えられます [4]。
* **選挙区再編:** 既存の選挙区の再編を行い、地域均衡を促進します。特に、人口の少ない地域における選挙区の規模を拡大し、地域住民の政治参加を促すことが重要です [7]。
* **政党復活税の導入:** 政党復活税を導入し、政党の資金調達の透明性を高めます。政党の資金を制限することで、政策を打ち出すよりも、票を集めることに重点を置く傾向を抑制することができます [6]。
* **投票率向上策:** 投票率向上を目的とした啓発活動を強化します。例えば、投票の重要性を訴えるキャンペーンを実施したり、投票しやすい環境を整備したりすることが考えられます [5]。
* **海外事例の活用:** 比例代表制小選挙区制を組み合わせた選挙制度を採用している海外の国々(例えば、ドイツ、カナダなど)の事例を参考に、日本の選挙制度を改善します [7, 8]。
* **シミュレーションによる効果検証:** 上記の改革案を実施した場合の影響をシミュレーションすることで、その効果を事前に検証します。シミュレーション結果に基づいて、より効果的な改革案を検討することができます [1, 6]。

**3. 実現可能性の検討**

これらの改革案は、それぞれ実現可能性が異なります。

* **比例代表制の改善:** 既存の法律を改正することで実現可能です。ただし、政党の意見を聞きながら、慎重に進める必要があります。
* **小選挙区制の改革:** 候補者質向上は、候補者自身や地域住民の意識改革によって実現可能です。
* **選挙区再編:** 選挙区再編は、国会議員選挙の選挙区の再編を行う必要があります。
* **政党復活税の導入:** 政治倫理委員会の判断や、国会での議論を経て導入される可能性があります。
* **投票率向上策:** 啓発活動は、政府や関係機関が連携して実施することで実現可能です。
* **海外事例の活用:** 海外事例を参考にすることは容易ですが、日本の政治状況や文化に合わない場合もあります。
* **シミュレーションによる効果検証:** シミュレーションは、専門家による分析に基づいて行われる必要があります。

**結論**

日本の選挙制度は、民主主義の根幹を支える重要な基盤ですが、課題も多く存在します。本稿で提案した改革案は、これらの課題を解決し、より公平で効果的な選挙制度を実現するための第一歩となるでしょう。これらの改革案を検討する際には、様々な意見を聞きながら、慎重に進めることが重要です。

---

このレポートは、提示された情報と指示に基づき、包括的で専門的な構成(日本語)に仕上げることを目指しました。番号付きのインライン引用 [1] を使用して出典を明記しました。 ご要望に応じて、特定の要素についてさらに詳細な分析や提案を行うことも可能です。

## Sources
[1] 日本の選挙制度改革:比例代表小選挙区の課題をわかり ... (https://www.pinpoint.jp/sfa-20251016-1901-8621)
[2] 衆議院選挙の仕組み【2026衆院選】:時事ドットコム (https://www.jiji.com/jc/article?k=2026012700138&g=pol)
[3] 小選挙区制と比例代表制を徹底解説:日本の選挙制度の歴史と ... (https://3minutes-seiji.com/20260126001)
[4] 日本の選挙制度の柱である小選挙区比例代表の違いを ... (https://morigon.blog/2025/11/19/senkyo/)
[5] 衆議院選挙とは 小選挙区比例代表、事実上の「政権選択選挙」 (https://www.nikkei.com/article/DGXZQOUA067RX0W6A200C2000000/)
[6] [PDF] 岐路に立つ日本の政党政治 - 新聞通信調査会 (https://www.chosakai.gr.jp/wp/wp-content/uploads/2026/01/20260200-770.pdf)
[7] [PDF] 神奈川 - カナロコ (https://www.kanaloco.jp/files/20260208.pdf)
[8] 小選挙区比例代表並立制 - Wikipedia (https://ja.wikipedia.org/wiki/小選挙区比例代表並立制)
[9] 比例代表制 - Wikipedia (https://ja.wikipedia.org/wiki/比例代表制)
[10] 重複立候補制度 - Wikipedia (https://ja.wikipedia.org/wiki/重複立候補制度)

 

ナレッジグラフの出力例

 

レポジトリ

github.com

modernBERTでNER。境界意識型学習とSpanを入れ込んでみる。

固有表現抽出(NER)タスクを続けていきます。gpt-5.xやgemini xにやらせればいいといわれますが、その通りです。一方で、ローカルLLMモデルを利用してLoRAで学習させても思いの他、精度を上げるのは大変でした。

という訳で、modernBERTという優秀でお手軽なencoder系モデルを引き続き取り扱います。

以前の検討と今回の流れ

bwgift.hatenadiary.jp

この検討の時には後はTokenizerとしてsudachiを入れていけば良いのかなと漠然と思っていました。現に味見の時にはそういう印象を持つ結果となっていました。しかし、意外とうまく行きません。そこで、仮想境界(Virtual Boundary)制御、およびスパンベースのマルチタスク学習 (Span-MTL)なんてものを、gemini君と議論しながら入れ込んでいきました。

modernBERTは8k tokensに対応した長文の取り扱いも得意です。コンテキスト指向なNERにぴったりですが、味見をしていくと、境界を発見するのは得意なものの、正解ラベルの中にも境界を入れ込み、不正解ではないが、細切れのタグを出してきます。

利用するデータとモデル

自作だと検証が面倒なので、今回は、stockmarksさんのwikipediaのNERデータを使います。

GitHub - stockmarkteam/ner-wikipedia-dataset: Wikipediaを用いた日本語の固有表現抽出データセット

さらにmodernBERTの日本語モデルはruri-v3-ptを利用します。

Ruri v3 - a cl-nagoya Collection

stockmarksさん、名古屋大学さんありがとうございます。

今回のトライアルの概要

 まず、sentence-pieceはサブワード単位のトークナイザーで自動的に適当なトークン分割を実施します。そこに無理やり辞書ベースの形態素解析器を入れちゃうのも手ですが、辞書ベースの仮想的な境界損失を入れてみます。つまり、モデルの予測を辞書ベースに寄せちゃおうという仕組み、仮想境界損失(Virtual Boundary Loss)です。LLM系で議論されているもかなと思うのですが、これをBERT系でも考えてを持ち込でみます。
 さらに、Span-based Multi-Task Learning としてトークン分類 (BIO) とスパン境界検出を同時に行う Multi-Task Learning も入れ込みました。  長めにコンテキストを抽出するタスクの場合は、Contrastive Learning(コントラスト学習)として、負例を分断させるようなタグとして学習させるというのも効果がある場合がありましたが、今回のNERデータは短文ですので割愛しています。

 Gemini君と一緒に悩みながら結果をまとめました。なお、ArXiv に掲載された論文のアブストラクトから原因、結果、根拠といった(論理構造)のテストを平行して実施しているので文中で言及していますが、今の段階のメモとして転機します。Gemini君に書かせたら、やたらすごいぞ!と記述しちゃいます。稚拙な検討ですが、

詳細メモ(gen with Gemini. )

Note: This section was generated with the assistance of AI. Please interpret the content with caution.


Wikipedia 固有表現抽出における境界意識型学習戦略の比較

1. Abstract

本研究では、日本語 Wikipedia を対象とした一般的な固有表現抽出 (NER) タスクにおいて、トークンベースの BIO 方式、仮想境界(Virtual Boundary)制御、およびスパンベースのマルチタスク学習 (Span-based Multi-Task Learning; 以下 Span-MTL) の有効性をモデル規模(30M, 130M)の観点から定量的に評価した。実験の結果、最新の安定化策を講じた Span-MTL (v5.2) は、小規模モデルから lite モデルまでの全スケールにおいて、BIO ベースラインを最大 +8.3pt 上回る圧倒的な精度向上を達成し、かつ推論時のオーバーヘッドも 1ms 以下に抑えられることが立証された。本研究は、実用性と精度の両面で Span-MTL が現代的な NER 構築において利用価値が高いと示唆された。

2. 背景と目的

従来の NER 手法は、サブワード分割に起因するエンティティの断片化(Fragmentation)や、境界特定精度の低下という課題を抱えている。特に日本語のように分かち書きのない言語では、形態素境界とサブワード境界の不一致が無視できない。これまでの ArXiv 論文構造抽出タスクでは、Span-MTL が優れた性能を示したが、本研究ではより一般的な Wikipedia NER タスクにおいて、これらの手法がどのように振る舞うかを検証する。

3. 手法(Methodology)

3.1 仮想境界損失(Virtual Boundary Loss: $L_{VB}$)

形態素解析器(Sudachi)によって得られた単語境界 $B \in {0, 1}T$ を制約として利用する。B-タグ(エンティティ開始)が形態素境界以外に出現する確率 $P(y_t = \text{B-TAG})$ に対して以下のペナルティを課す: $$L{VB} = \lambda{VB} \cdot \sum_{t=1}^T (1 - B_t) \cdot P(y_t = \text{B-TAG})$$ これにより、モデルの予測を言語学的に妥当な境界へ「吸着」させる。

3.2 Span-based MTL オブジェクティブ

トークン分類に加えて、各トークンがエンティティの開始(Start)または終了(End)であるかをバイナリ分類するヘッドを追加する。 $$L{Span} = \lambda{Span} \cdot (L{Start} + L{End})$$ ここで $L{Start}, L{End}$ は、正例(境界点)に対して重み($w=10$)を付けた Binary Cross Entropy Loss である。

3.3 Negative Learning

「O(エンティティ外)」とラベルされたトークンにおいて、誤って高い確率でエンティティタグを予測することを抑制する損失 $L{Neg}$ を導入する。 $$L{Neg} = \lambda{Neg} \cdot \sum{t \in {O}} (1 - P(y_t = \text{'O'}))$$

4. 実験設定

  • データセット: stockmark/ner-wikipedia-dataset
    • 学習/テスト分割: 4,300 / 1,000 件
  • モデル: ModernBERT (Small: 30M, Base-lite: 130M)
  • ハイパーパラメータ:
    • エポック数: 10(Early Stopping 採用)
    • 解釈性向上のため head_focused=False(標準的な全トークン学習)を採用。

5. 実験結果と解析

5.1 定量的評価

モデル規模による性能差を以下に示す(F1 Score)。

モデル BIO Baseline VB-BIO Span-MTL (legacy) Span-MTL (v5.2)
Small (30M) 0.7637 0.7575 0.0000 0.8466
Base-lite (130M) 0.8372 0.8292 0.8214 0.8938

5.2 劇的な安定化:v5.2 による救済 (v5.2 Stability Proof)

以前の実験で 130M モデルが F1=0 を記録した主因が「数値的不安定性(NaN)」であったことが、今回の再検証によって決定的に証明された。 最新の v5.2 改良(Circular Loss、LayerNorm、Clamping)を適用した結果、30M モデルで F1=0.8466 (+8.3pt)、130M モデルで F1=0.8938 (+5.7pt) という、BIO ベースラインを圧倒する精度を達成した。

これは、モデル規模に関わらず、適切な数値的制約と損失関数(Circle Loss 型)を導入すれば、マルチタスク(BIO + Span)の相乗効果を最大限に引き出せることを示している。特筆すべきは、130M モデルでは λ (s_lambda) を 0.01 まで落とすことで、スケールアップに伴う勾配の鋭敏化を制御し、真の性能を引き出せた点である。

5.3 精度と速度のトレードオフ (Accuracy-Latency Trade-off)

実運用上の重要指標である推論レイテンシーを計測した結果、Span-MTL による計算コストの増加は極めて限定的であることが判明した(入力 512 トークン時)。

モデル BIO Baseline (ms) Span-MTL v5.2 (ms) 増分 (ms)
30M 0.89 0.78 -0.11*
130M 2.40 2.99 +0.59

*30M モデルにおける数値の減少は計算グラフの最適化や測定誤差の範囲内と考えられる。

130M モデルにおいても、+5.7pt の精度向上に対してレイテンシー増加は 0.6ms (約25%) に留まっており、計算リソースあたりの精度利得(Efficiency)は極めて高い。

5.3 スパン長と複雑性の相関

ArXiv タスク(平均 20-50 トークンの長スパン)と Wikipedia タスク(平均 2-5 トークンの短スパン)を比較すると以下の対比が得られる。

特性 ArXiv (論理構造) Wikipedia (一般名詞)
スパン長 長い(15~50+) 短い(2~5)
ネスト あり得る ほぼなし
主たる境界課題 内部からの誤開始の抑制 境界トークンの正確な識別
最適手法 VB + Negative Learning BIO + Virtual Boundary
Span-MTL の位置付 構造的一貫性の補助(λ低減必須) 冗長・過剰制約

5.4 プログラム上の互換性と安全性 (Backward Compatibility)

今回の ArXiv タスク向けの Span-MTL 改良(v5.2)は、モデルの実装において以下の安全策が講じられており、既存の Stockmark 実験結果に悪影響を与えることはない:

  1. 損失計算の条件分岐: span_loss_lambda が 0 の場合、Span ヘッドの損失計算およびバックボーンへの逆伝播は物理的にスキップされる設計となっている。
  2. デフォルト値の継承: 標準的な BIO/VB 設定で実行する限り、内部構造の変更(LayerNorm の追加等)は順伝播の計算グラフには含まれるが、重みの更新(学習)は発生しない。
  3. 数値的安定性の向上: むしろ、今後 Stockmark 等で Span-MTL を再検証する場合、v5.2 で導入された LayerNormClamping によって、過去に発生した 30M モデルでの NaN 崩壊(F1=0)が回避され、より安定した比較が可能になるという「正の波及効果」が期待できる。

6. 結論

本研究により、Span-MTL (v5.2) は日本語 NER における極めて強力な汎用戦略であることが立証された。

  1. 精度向上: 短スパンタスクにおいても、Span 境界の認識を補助タスクとして導入することで、モデルはより強固な境界表現を獲得し、ベースラインを大きく凌駕する。
  2. 全スケールでの安定性: v5.2 で導入された LayerNorm と Clamping、および λ のスケーリング調整により、30M から 130M まで一貫して安定した学習が可能となった。
  3. 実用的な速度: レイテンシーの増加はミリ秒単位に抑えられており、リアルタイム性が要求される多くの実務アプリケーションにおいて Span-MTL の採用を阻む要因はない。

総じて、今後の NER 開発においては、従来の BIO 方式だけでなく、安定化 Span-MTL も利用価値があると考えられる。

7. 参考文献 (References)

  1. [BANER] "BANER: Boundary-Aware LLMs for Few-Shot Named Entity Recognition" (arXiv 2024). https://arxiv.org/abs/2412.02228
  2. [Circle Loss] "Circle Loss: A Unified Perspective of Pair Label Similarity Optimization" (CVPR 2020). https://arxiv.org/abs/2002.10857
  3. [Boundary Smoothing] "Boundary Smoothing for Named Entity Recognition" (ACL 2022). https://aclanthology.org/2022.acl-long.490/
  4. [ModernBERT] "ModernBERT: A Modernized BERT for Better Performance and Efficiency" (Hugging Face Blog 2024). https://huggingface.co/blog/modernbert
  5. [Sohrab & Miwa 2018] "Deep Exhaustive Model for Nested Named Entity Recognition" (EMNLP 2018). https://aclanthology.org/D18-1311/. 全てのスパンを列挙し分類する Span-based NER の基礎。
  6. [Sun et al. 2020] "SpanMlt: A Span-based Multi-Task Learning Framework for Pair-wise Aspect and Opinion Terms Extraction" (ACL 2020). https://aclanthology.org/2020.acl-main.340/. 本研究の呼称 "Span-MTL" の直接的な着想源となった MTL フレームワーク

Hatena Blogは数式はうまく表現できないんですね・・・。すみません。 きちんと検討したら楽しいかもしれませんね。

コンテキスト指向な NER をColabで味見してみる。

BERTやModernBERT(Ruri-v3など)のようなTransformerベースのモデルは、内部的に Self-Attention メカニズムを持っており、文全体のコンテキストを考慮して各トークンのベクトルを決定しています。そのため文脈を考慮して、NERでは地名(LOC)か企業名(ORG)と言った固有表現を抽出できます。大変便利です。

 

すっかり高性能になったLLMを使えば、原因と結果といった事象フレームの抽出は可能です。大量のドキュメントの整理だけではなく、軽量な分類・抽出器はこれから実務的に有効だろうと思います。コモディティ化したからこそ出番ですよね(笑)。例えば、入力したら、即抽出したコンテキスト表示すれば、文書の入力の質が上がります。

 

素人がつらつら書いてみましたが、個人の手元の貧弱なPCで検討できるので楽しいですよ。

 

とりあえず、20件程度の教師データを使って学習させてみました。そのモデルを使って、原因と結果を抽出します。

 

入力文: システム障害によりサービスが停止した。
抽出結果:
  - [CAUSE] システム障害 (信頼度: 0.9999)
  - [EFFECT] サービスが停止した (信頼度: 0.9999)

テストサンプル極小なので過学習気味です。

 

教師データはLLMでアノテーションすればいいと思うと気が楽ですよね。

 

Colabノートです。

gist.github.com

ちょっと改良ポイントありですね・・・。

Qwen3-TTSをColabで試してみる。

テキストで指示した音声でしゃべってくれるQwen3-TTSモデル(Qwen3-TTS-12Hz-1.7B-VoiceDesign)を試してみました。Colab T4環境でVRAM占有率は8.4 / 15.0 GBでした。Colabのノートブックは最後にリンクします。

 

huggingface.co

 

instructのテキストだけで色んな声色の発生ができました。発音が発音が外国人なまりが時々でたり、漢字の読み方が怪しかったりするテキストもありました。しかし、中二病風(笑)もできましたし、なかなか面白かったです。ぜひ、Colabで遊んでみてください。

 

ちなみに、以下のようにinstruct中に読み上げテキストを入れる/入れないを試してみましたが、大きな違いはありませんでした。十分、聞けるレベルですが、指示が効いたら表現の幅が広がるように考えます。

 

    {
        "role": "Tsundere (ツンデレ)",
        "text": "べ、別にあんたのために作ったわけじゃないんだからね!勘違いしないでよね!",
        "instruct": "10代の少女の声。ツンデレな口調。最初は怒ったように早口で、後半は少し照れたように声が小さくなる。高めのトーン。"
    },
    {
        "role": "Tsundere (ツンデレ)",
        "text": "べ、別にあんたのために作ったわけじゃないんだからね!勘違いしないでよね!",
        "instruct": "10代の少女の声。ツンデレな口調。高めのトーン。最初は怒ったように早口で、「べ、別にあんたのために作ったわけじゃないんだからね!」後半は少し照れたように声が小さくなって「勘違いしないでよね!」"
    },

 

    {
        "role": "Villainess (悪役令嬢)",
        "text": "オーホッホッホ!このわたくしに逆らおうなんて、100年早くてよ!",
        "instruct": "高飛車な自信家の女性の声。高笑いが似合う、少し甲高いトーン。相手を見下すような威圧感と、どこか憎めない愛嬌を混ぜる。"
    },
    {
        "role": "Villainess (悪役令嬢)",
        "text": "オーホッホッホ!このわたくしに逆らおうなんて、100年早くてよ!",
        "instruct": "高飛車な自信家の女性の声。少し甲高いトーン。相手を見下すような威圧感と、どこか憎めない愛嬌を混ぜる。「オーホッホッホ!」は高笑いです。「100年早くてよ!」は威圧的に。"
    },

 

Colabノートです。

gist.github.com

translategemma:4bをColabで試してみる。

translategemmaはGoogleが公開した翻訳モデルです。Gemma 3ベースでオープンなモデルで気軽に使えます。Googleさんありがとうございます。早速、Colab L4環境でollama公式にあるtranslategemma:4bで試してみました(VRAM 利用率:3.8GB/22.5GB)。

 

4bのモデルでも実用的だと感じました。「猫をかぶる」と言った慣用句は知識あるなしに左右されるようです。プロンプトは推奨されているプロンプト程度は指示を入れ込まないと、余計な注釈が加わったりしました。推奨

 

blog.google

 

ollama.com

 

 

最初に簡略したプロンプトで試しました。

"Translate the following text from {source_lang} to {target_lang}:\n{text}"

回答例:

Original: 猫の手も借りたいほど忙しい。
Translated: I'm so busy that I'm even willing to borrow a cat's paw.

This is an idiom that expresses being extremely busy and having no time for anything.

Duration: 0.8775 seconds

なんだか、注釈が入ってしましました。これは翻訳タスクとしては良くありません。そこで、推奨プロンプトを使ってみます。

 

推奨プロンプト:

You are a professional {SOURCE_LANG} ({SOURCE_CODE}) to {TARGET_LANG} ({TARGET_CODE}) translator. Your goal is to accurately convey the meaning and nuances of the original {SOURCE_LANG} text while adhering to {TARGET_LANG} grammar, vocabulary, and cultural sensitivities.
Produce only the {TARGET_LANG} translation, without any additional explanations or commentary. Please translate the following {SOURCE_LANG} text into {TARGET_LANG}:


{TEXT}

 

回答:

Original Text:   猫の手も借りたいほど忙しい。
New Translation: I'm so busy that I'd even borrow a cat's paw.
Duration:        4.0883 seconds

と、翻訳文だけ返信してくれました。

 

推奨プロンプトを利用して色々と翻訳してもらいます。

回答例1:

Original: The patient presented with acute abdominal pain localized to the right lower quadrant. An MRI scan revealed inflammation consistent with appendicitis, necessitating immediate surgical intervention.
Translated: 患者は、右下腹部に急性腹痛を訴えました。MRI検査の結果、虫垂炎を示唆する炎症が見られ、直ちに手術が必要と判断されました。
Duration: 0.8748 seconds

回答例2:

Original: 我思う、故に我あり。この命題は、すべてを疑ったとしても、疑っている自分自身の存在だけは疑い得ないということを示している。
Translated: I think, therefore I am. This statement demonstrates that, even if we doubt everything, we can never doubt the existence of the very self that is doing the doubting.
Duration: 0.8501 seconds

 

これは十分な精度ですね。お手軽に利用できるのは有難いです。折角なのでプロンプトによる影響を調べてみます。

 

Professional, Casual, Robust Few-Shotの3パターンのプロンプトを考えました。詳細は結果を参照してください。分野によって使い分けるといいのでしょう。Fewshotのプロンプトが意外といい感じです。どのような分野・用途で使うのかを決めたら、プロンプトにFewshotも盛り込むといい感じになるかもしれません。

 

結果:

--- Item 1: Business (English -> Japanese) ---
Original: We regret to inform you that your application has been declined due to policy changes.
[Professional]: ポリシー変更により、ご応募いただいた内容を却下せざるを得ないことをお詫び申し上げます。 (0.74s)
[Casual]:       おー、マジすか?なんか、ポリシーが変わって、あなたの申請、ダメになったってこと? (0.66s)
[Robust FS]:    残念ながら、ポリシー変更により、あなたの申請は却下されました。 (0.58s)

--- Item 2: Business (English -> Japanese) ---
Original: Please expedite the shipment of the Q3 financial reports by close of business today.
[Professional]: Q3の財務報告書を、本日営業時間内にできるだけ早く発送してください。 (0.61s)
[Casual]:       ねえ、ちょっと!今日の終わりまでに、3つの四半期の財務報告、早く送ってくれる?お願い! (0.72s)
[Robust FS]:    本日営業時間内に、Q3の財務報告書を迅速に発送してください。 (0.61s)

--- Item 3: Casual (English -> Japanese) ---
Original: Yo, I'm gonna be late for the party, start without me.
[Professional]: ねえ、パーティーには遅れるから、私なしで始めてくれる? (0.57s)
[Casual]:       よお、パーティー、マジ遅れるから、みんなでワイワイ始めてな。 (0.61s)
[Robust FS]:    やっほー、パーティーには遅れるから、私なしでもいいよ。 (0.64s)

--- Item 4: Casual (English -> Japanese) ---
Original: That movie was totally lit, I can't believe the ending!
[Professional]: その映画は本当に最高だった、結末に驚いた! (0.55s)
[Casual]:       あー、あの映画マジで最高だった!え、まさかのラストマジでヤバかった! (0.66s)
[Robust FS]:    あの映画は最高だった、信じられない結末だった! (0.57s)

--- Item 5: Idiom (English -> Japanese) ---
Original: Let's call it a day and go home.
[Professional]: では、今日はこれで終わり、家に帰ろう。 (0.50s)
[Casual]:       じゃあ、今日は終わりじゃね?家に帰るか。 (0.54s)
[Robust FS]:    今日はこれで終わり、家に帰ろう。 (0.50s)

--- Item 6: Idiom (English -> Japanese) ---
Original: Don't spill the beans about the surprise party.
[Professional]: サプライズパーティーについて、秘密を守ってください。 (0.50s)
[Casual]:       ねえ、あそこでサプライズパーティーのこと、絶対に誰にも言わないでよ?マジで! (0.66s)
[Robust FS]:    サプライズパーティーについて、秘密を守ってください。 (0.51s)

--- Item 7: Technical (English -> Japanese) ---
Original: The latency of the API endpoint increased significantly under high load.
[Professional]: API エンドポイントのレイテンシは、高負荷時に大幅に増加しました。 (0.61s)
[Casual]:       え、マジで?APIのレスポンスがめっちゃ遅くなるってこと?アクセスが多すぎるとか? (0.72s)
[Robust FS]:    APIエンドポイントの応答時間が、負荷が高い状況下で大幅に増加しました。 (0.62s)

--- Item 8: Literary (English -> Japanese) ---
Original: The moon hung low in the sky, casting long, eerie shadows across the silent forest.
[Professional]: 月が空に沈み、静かな森に長く、不気味な影を落としていた。 (0.68s)
[Casual]:       あー、月がめっちゃ低空飛行してるね。森全体に、マジで怖い影が伸びてて。 (0.73s)
[Robust FS]:    月が空に低く輝き、静かな森に長く、不気味な影を落としていた。 (0.75s)

--- Item 9: Business (Japanese -> English) ---
Original: 平素は格別のご高配を賜り、厚く御礼申し上げます。
[Professional]: We would like to express our sincere gratitude for your continued support. (0.55s)
[Casual]:       Hey, just wanted to say thanks for everything, you're a real pal. (0.62s)
[Robust FS]:    Thank you very much for your continued support. (0.53s)

--- Item 10: Business (Japanese -> English) ---
Original: 恐れ入りますが、至急ご返信いただけますでしょうか。
[Professional]: We would appreciate it if you could reply as soon as possible. (0.54s)
[Casual]:       Hey, just wanted to quickly get in touch. Any chance you could get back to me ASAP? (0.67s)
[Robust FS]:    I apologize for the trouble, but could you please reply as soon as possible? (0.63s)

--- Item 11: Casual (Japanese -> English) ---
Original: マジで?それ超ウケるんだけどw
[Professional]: Seriously? That's hilarious! (0.46s)
[Casual]:       Seriously? That's hilarious, haha! (0.52s)
[Robust FS]:    Seriously? That's hilarious! (0.49s)

--- Item 12: Casual (Japanese -> English) ---
Original: ワンチャン、明日なら行けるかも。
[Professional]: Maybe, if I go tomorrow, it might work. (0.51s)
[Casual]:       Hey, maybe I could actually make it tomorrow. (0.51s)
[Robust FS]:    There's a chance that I might be able to go tomorrow. (0.59s)

--- Item 13: Idiom (Japanese -> English) ---
Original: 石の上にも三年。
[Professional]: Like moving stones, three years will make anything possible. (0.52s)
[Casual]:       Dude, you know what I mean? Like, if you put in the effort, eventually you'll get there. It's like, even if it seems impossible, if you stick with it for a long time, you'll eventually make it. (1.12s)
[Robust FS]:    Patience pays off. (0.47s)

--- Item 14: Idiom (Japanese -> English) ---
Original: 猿も木から落ちる。
[Professional]: Even monkeys fall from trees. (0.46s)
[Casual]:       Hey, you know, even monkeys fall out of trees, right? (0.57s)
[Robust FS]:    Even monkeys can fall from trees. (0.47s)

--- Item 15: Technical (Japanese -> English) ---
Original: 本システムは、冗長性を確保するためにアクティブ・スタンバイ構成を採用しています。
[Professional]: This system employs an active-standby configuration to ensure redundancy. (0.54s)
[Casual]:       Hey, so this system is set up with an active/standby thing, right? Basically, it's got like, two parts working at the same time to make sure everything keeps running smoothly, even if one part breaks. (1.03s)
[Robust FS]:    This system employs an active-standby configuration to ensure redundancy. (0.58s)

--- Item 16: Technical (Japanese -> English) ---
Original: 患者は急性上気道炎と診断され、抗生物質が処方された。
[Professional]: The patient was diagnosed with acute upper airway inflammation and was prescribed antibiotics. (0.57s)
[Casual]:       Hey, so, the doc said he had this really bad upper respiratory infection, like a super nasty cold, and they gave him some antibiotics. (0.77s)
[Robust FS]:    The patient was diagnosed with acute upper respiratory infection and was prescribed antibiotics. (0.58s)

--- Item 17: Literary (Japanese -> English) ---
Original: 桜の花びらが、春の風に乗って川面を静かに流れていく。
[Professional]: The petals of the cherry blossoms gently float on the surface of the river, carried by the spring breeze. (0.66s)
[Casual]:       Hey, check it out! Those cherry blossoms, they're just floating down the river, like, totally peaceful. It's so pretty, man. (0.82s)
[Robust FS]:    The petals of the cherry blossoms drift silently along the surface of the river, carried by the spring breeze. (0.67s)

--- Item 18: Literary (Japanese -> English) ---
Original: 彼の瞳には、言い知れぬ孤独と微かな希望が宿っていた。
[Professional]: His eyes held a strange mixture of loneliness and a faint glimmer of hope. (0.57s)
[Casual]:       Dude, his eyes… they were just, like, full of this weird mix of loneliness and a little bit of hope. Man, it was intense. (0.82s)
[Robust FS]:    His eyes held an unknown loneliness and a faint glimmer of hope. (0.57s)

 

検討したプロンプト:

def translate_professional(text, source_lang, target_lang):
    """
    Translates text using a strict professional persona. 
    Enforces formal tone and suppresses conversational filler.
    """
    start_time = time.time()
    src_code = iso_codes.get(source_lang, "")
    tgt_code = iso_codes.get(target_lang, "")

    prompt = (
        f"Translate the following text from {source_lang} ({src_code}) to {target_lang} ({tgt_code}).\n"
        "Output ONLY the translated text. Do not provide explanations, notes, or intro text.\n"
        f"\n{text}"
    )

    result = ollama.generate(model=MODEL_NAME, prompt=prompt)
    end_time = time.time()
    return result['response'].strip(), end_time - start_time

def translate_casual(text, source_lang, target_lang):
    """
    Translates text using a 'close friend' persona.
    Enforces casual/plain speech and explicitly forbids polite forms (Desu/Masu) for Japanese.
    """
    start_time = time.time()
    src_code = iso_codes.get(source_lang, "")
    tgt_code = iso_codes.get(target_lang, "")

    prompt = (
        f"Translate the following text from {source_lang} ({src_code}) to {target_lang} ({tgt_code}).\n"
        "Act as a close friend speaking to another friend. Use strictly casual, plain speech (slang is okay).\n"
        "If translating to Japanese, use plain form (Da/Dayo/Jann) and STRICTLY FORBID polite forms (Desu/Masu).\n"
        "Output ONLY the translated text.\n"
        f"\n{text}"
    )

    result = ollama.generate(model=MODEL_NAME, prompt=prompt)
    end_time = time.time()
    return result['response'].strip(), end_time - start_time

def translate_robust_fewshot(text, source_lang, target_lang):
    """
    Translates text using a few-shot strategy with clear delimiters to handle idioms.
    """
    start_time = time.time()
    src_code = iso_codes.get(source_lang, "")
    tgt_code = iso_codes.get(target_lang, "")

    prompt = (
        f"Translate the text from {source_lang} ({src_code}) to {target_lang} ({tgt_code}).\n"
        "### Instructions ###\n"
        "Translate the input text naturally, paying attention to idioms.\n"
        "Output ONLY the translation.\n\n"
        "### Examples ###\n"
        "Input: 彼はいつも猫をかぶっている。\n"
        "Output: He's always hiding his true colors.\n"
        "Input: It costs an arm and a leg.\n"
        "Output: めっちゃ高いわ。\n\n"
        "### Task ###\n"
        f"Input: {text}\n"
        "Output:"
    )

    result = ollama.generate(model=MODEL_NAME, prompt=prompt)
    end_time = time.time()
    return result['response'].strip(), end_time - start_time

 

 

gist.github.com

Google Julesに頑張ってゲームを作ってもらう。

Google Julesは、Google が開発した “自律型AIコーディングエージェント” で、GitHub リポジトリを読み取り、計画を立て、コードを書き、テストし、最終的に PRまで自動で作成する次世代の開発支援ツールです。GooleでもAntigravityやGemini CLIと比較して目立たない存在ではないでしょうか。

 

jules.google

 

しかし、jules君は、Googleクラウド VM 上でコードを実行するため、仕事前に走らせておいて昼休みにチェック・・・のような趣味プログラマにとって便利。基本はGithubと連携して動作するのだが、単純に会話をしながら作り上げることができます。

 

以前から気になっていた、pycelを使ってゼビウスシューティングゲームに挑戦することにした。ゼビウスXevious)は、1980年代にナムコが発表した縦スクロールシューティングゲームで、空中と地上を撃ち分ける2ボタン制や隠し要素など、当時として革新的な仕組みを多数導入した名作です。つくたものは「ゼビウス風」と言っても、空中と地上を撃ち分ける2ボタン制だけが一緒なまったくの別物・・・です。悲しいかな。

 

自機が透明だったり、背景がなかったり。色んなトラブルを乗り越え、最終的に完成させました。最後のドキュメントもJules君に作成を依頼。Jules君曰く「私たちの汗と(デジタルの)涙の結晶」と・・・。

 

お手軽にVide Codingを体験してみたい・・・人はいかがでしょう。プログラムだけではなく、レポジトリのドキュメント作成や、ちょっとした思い付きの原理確認には重宝しています。有料でいいので、VMをもう少し強化するとさらに捗る気がします。

 

Githubと連携しなくても、遊べました。

 

github.com

 

ACE FrameworkベースにLTMをじっくり試してみる。

Colabを使ってACE(Agentic Context Engineering)という考え方を試してみました。コンテキストエンジニアリングを考える良い機会になりました。また、そもそも情報をどう蓄積して、検索し引き出して投入するのか、を考える良いきっかけとなりました。

bwgift.hatenadiary.jp

手法の整理と割り切り


 ACE(Agentic Context Engineering)は、大規模言語モデル(LLM)が自らコンテキスト(入力情報や指示)を成長させ、自己改善を続けるためのフレームワークです。従来のLLMの改善手法の多くはモデルの重みを更新する「微調整(ファインチューニング)」に頼ってきましたが、ACEは重みを変えるのではなく、モデルに与える「コンテキスト(文脈)」を最適化・進化させることに焦点を当てています。

ACEの仕組み:3つの役割分担

ACEは、3つの専門的なエージェント的役割を分担させることで、効率的にコンテキストを成長させます。 - Generator(生成器): 現在のプレイブックを使用して、実際にタスクを解くための推論を行います。 - Reflector(反省器): 実行結果(成功や失敗のフィードバック)を分析し、そこから具体的な教訓や新しい戦略を抽出します。 - Curator(整理器): 抽出された知見を既存のプレイブックに統合します。この際、重複を排除し、構造を維持しながらアップデートを行います。

ACEの革新的なポイント

  • 逐次的なncremental Delta Updates(デルタ・アップデート): 全文を書き換えるのではなく、「箇条書き単位」で必要な部分だけを修正・追加します。これにより、過去の知識を失うことなく、効率的に改善を積み重ねられます。
  • 高いコストパフォーマンス: 全文書き換えを行わないため、計算コスト(トークン使用量)を抑えつつ、適応までの待ち時間(レイテンシ)を大幅に短縮(平均86.9%削減)することに成功しています。

 このうち、3つの役割分担を参考にします。試してみるとIncremental Delta Updatesは非常に魅力的なのですが、箇条書き単位=端的な情報をReflectorで抜き出すためには、何が情報として重要なのかを理解する必要があります。例えば事実の更新なのか、解法なのか。それぞれの端的な情報に対して情報を更新・追加したするのも工数かかります。短い文章で表すことができる事柄ばかりではありません。そこで、Incremental Delta Updatesでは、箇条書きの短文ではなく、必要だろうと思われる動的なテキスト量でもよいと割り切りました。  折角なので、Model-Firstを参考にモデル(一般化)をReflectorで入れ込むことにします。

実装

SAKURA AIのAPIでgpt-oss:120Bを利用します。

コンポーネント 役割 使用技術
Curator (キュレーター) ユーザーのクエリに関連するコンテキストを検索します。 ハイブリッド検索 (FAISS + SQL)
Agent (エージェント) コンテキストを使用して即時応答を生成します。 LangChain
Reflector (リフレクター) 対話を分析し、新しい事実やルールを抽出します。 LLM
Storage (ストレージ) 文書、キュー、インデックスを永続化します。 SQLite (WALモード)

といった感じで実装しました。 Vibe CodingにはGoogle Colebでざっくり可能性検討を行って、Gemini CLIで実装を行いました。UIにはGarioを始めて使ってみました。途中経過と最終的な蓄積データ(Long-Term Memory)を表示して処理の状況を見えるようにしました。

LTMに収納するcontentの例。少々長すぎるかも。情報量としてはリッチでいい感じだと思います。

  • Entities: Development team, AI code‑generation assistant, tools (uv, ruff, VS Code, pre‑commit, GitHub Actions, Docker), repository, CI pipeline, configuration files (pyproject.toml, ruff.toml, .pre‑commit-config.yaml, Dockerfile), phases (Phase 0‑5).
  • State Variables:
    • Installed toolset per developer machine,
    • Contents of configuration files,
    • Environment reproducibility flag,
    • Code‑quality metrics (lint errors, formatting violations),
    • CI status (pass/fail, runtime),
    • Deployment parity (local vs production),
    • Team learning load.
  • Actions:
    1. Install a tool (e.g., uv).
    2. Add a tool as a dev dependency (ruff).
    3. Configure IDE integration (VS Code settings.json).
    4. Introduce a pre‑commit hook.
    5. Extend CI workflow with the same commands.
    6. Build a production‑identical Docker image and run it locally.
    7. Commit code, run CI, merge PRs.
  • Constraints: Limited learning capacity, risk of breaking builds, tool‑conflict (e.g., Copilot vs Ruff), CI execution time, maintainability of multiple config files, need for version‑controlled changes.
  • Solution Summary: The AI answer proposes a phased, incremental rollout of the toolchain. Each phase delivers a concrete, measurable benefit (early value, risk mitigation, faster feedback, measurable ROI, cultural adoption). The rollout is isolated per Git branch, measured with concrete metrics, and only expanded after validation, thus keeping risk low while accelerating development speed.

Generalization: - Abstract Pattern: Incremental adoption of a complex development toolchain through small, isolated, measurable steps. - Underlying Problem Class: Change‑management / process‑improvement problem, often modeled as a constraint‑satisfaction or resource‑allocation task where the goal is to maximize productivity while minimizing learning and disruption risk. - General Strategy: 1. Identify the minimal viable tool that yields immediate benefit. 2. Deploy it in isolation, measure impact, and validate. 3. Iteratively add complementary tools/configurations, each guarded by its own validation (branch + CI). 4. Use quantitative metrics (setup time, lint error count, CI failure rate, deployment parity) to assess ROI. 5. Align rollout with team culture by delivering quick wins and keeping learning overhead low. 6. Ensure rollback capability at each step. This pattern can be applied to any scenario where a team needs to introduce new tooling, processes, or infrastructure without disrupting ongoing work."

「Vibe Codingのコツは?」に対する回答例。この問いの前にuvやruffの利用を議論していたので、それを踏まえた回答になっています。

Vibe Coding で快適に開発するための実践的なコツ

ポイントは「AI からの出力をすぐに実行・検証できる環境を作る」ことと、「AI に指示するプロンプトを磨く」ことです。
以下の項目を順に導入すれば、AI 補助開発のスピードと品質が大幅に向上します。


1️⃣ 環境をすぐに立ち上げる「最小構成」

手順 内容 目的
① uv のインストール curl -LsSf https://astral.sh/uv/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"
1 行で Python 仮想環境と依存解決が完結。Docker が使えない Vibe Coding でも必ず動く。
② プロジェクト初期化 uv initpyproject.toml が生成 依存はすべて pyproject.toml に宣言し、ロックは uv.lock に一元化。
③ 開発ツールを dev‑deps に追加 uv add --dev ruff mypy pytest pre‑commit Lint/Format/型チェック/テストをすべて同じ環境で管理。
④ VS Code 設定 .vscode/settings.json
json { "python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python", "ruff.enable": true, "ruff.path": "${workspaceFolder}/.venv/bin/ruff", "editor.formatOnSave": true, "editor.codeActionsOnSave": { "source.fixAll": true, "source.organizeImports": true } }
保存時に自動 Lint+Fix、インポート整理が走り、AI が出したコードがすぐにクリーンになる。
⑤ pre‑commit フック uv run pre-commit install
.pre-commit-config.yaml に ruff の hook を記述
コミット前に必ず Lint/Format が走り、CI 失敗を防止。

結果:Vibe Coding のターミナルだけで uv sync.venv が作られ、VS Code が自動でコードを整形。Docker のインストールは不要です。


2️⃣ AI(Copilot・ChatGPT・Claude・Gemini)とスムーズに連携するコツ

コツ 具体的なやり方
① プロンプトは「入力 → 期待出力」形式で書く """<説明>""" の後に 「以下の関数を実装してください」 と続け、「戻り値は dict[str, Any] のように型まで明示。
② 生成コードはすぐに Lint/Format VS Code の 保存 → Ruff 自動修正 が走るので、AI が出したコードはそのまま保存すれば即座にクリーン。
③ 失敗例を添えて指示 「エラーハンドリングが足りない」場合は 「例外は try/except で捕捉し、logging.error を呼び出す」 と具体的に指示。
④ 生成コードをテストコードと同時に依頼 「この関数のユニットテストpytest で書いて」 と依頼すれば、uv add --dev pytest が入っている環境で すぐに uv run pytest が走る。
⑤ 生成結果をコメントで囲む # AI生成開始 / # AI生成終了 のようにマークしておくと、pre‑commit で自動的に ruff が対象外にしない ことが保証できる。

3️⃣ プロンプト設計のベストプラクティス

項目
目的を明示 # 目的: CSV ファイルを読み込み、日付列をdatetimeに変換する関数を作成
入力例 sample.csv の 1 行目を示す(ヘッダー+数行)
出力例 期待する関数シグネチャと戻り値の型(例: def parse(csv_path: str) -> pd.DataFrame:
制約条件 - pandas だけを使う- 例外はValueErrorで投げる
テストケース - 正常系: 2023-01-01 → datetime(2023,1,1)- 異常系: 空文字 → ValueError
スタイル PEP8 に準拠、docstring は Google style

効果:AI が「何をすべきか」だけでなく「どう書くべきか」まで把握できるので、生成コードの手直しがほぼ不要になります。


4️⃣ CI/CD での「AI 生成コード」品質保証

ステップ 実装例(GitHub Actions)
1️⃣ Lint - name: Lint <br> run: .venv/bin/ruff check --output-format=github
2️⃣ Format チェック - name: Format check <br> run: .venv/bin/ruff format --check
3️⃣ Type Check - name: Type check <br> run: .venv/bin/mypy src
4️⃣ テスト - name: Test <br> run: .venv/bin/pytest --junitxml=reports.xml
5️⃣ キャッシュ actions/cache~/.cache/uv を保存し、ビルド時間を 30 % 以上短縮。
6️⃣ アノテーション ruff--output-format=github が PR に直接エラー行をハイライト。

ポイント:ローカルと CI が 同一バイナリ.venv/bin/ruff)を呼び出すので、「ローカルは通っても CI が失敗」 が起きません。


5️⃣ 生産性をさらに上げる小技集

小技 手順・設定
① VS Code のスニペット Ctrl+Shift+P → Preferences: Configure User Snippets → python.jsondefif __name__ == "__main__": のテンプレートを登録。AI が出したコードにすぐ貼り付け可能。
② ターミナルのエイリアス alias r='uv run'r python -m mymodule で仮想環境を意識せず実行。
③ 変更点だけを AI に再生成 git diff --staged の出力をコピーし、「この差分だけ修正したコードを生成してください」 と指示すれば、無駄な再生成を防げる。
④ 生成コードの自動コメント付与 pre-commit のフックで # AI生成開始 / # AI生成終了 を自動挿入し、レビュー時に「AI が書いた箇所」を一目で把握。
⑤ 生成コードの安全チェック pip install safetyuv add --dev safety → CI に safety check -r requirements.txt を組み込むと、依存ライブラリの脆弱性を自動検出。

6️⃣ トラブルシューティング Q&A(よくあるケース)

症状 原因 解決策
保存したら VS Code が自動でコードを消す ruffselectD(docstring)や F401(未使用インポート)が除外されていない ruff.tomlignore に該当コードを追加、または # ruff: noqa を行に付与。
AI が出したコードが ImportError になる 依存が pyproject.toml に未記載 uv add <package> で追加し、uv sync を再実行。
CI がローカルと違う Python バージョンで走る Dockerfile の FROM python:3.x がローカルと不一致 Dockerfile の FROM 行をローカルの python -V と同じタグに固定(例: python:3.11-slim)。
pre‑commit が毎回失敗する ruff--fix が自動修正した結果、ステージがずれる pre-commitstages: [commit]pre-commit run --all-files に変更し、修正後に自動で git add -u させる。
AI が生成したコードがテストで失敗 テストケースが足りない、または型が曖昧 プロンプトに ユニットテストも書いて」 と明示し、pytest が自動で走るようにする。

7️⃣ まとめ:Vibe Coding で「AI → 即実行・即検証」サイクルを作る流れ

  1. uv だけで環境構築 → 1 分で .venv 完成。
  2. Ruff を dev‑deps に → 保存時に自動 Lint/Format。
  3. VS Code 設定で自動化 → 手動コマンド不要。
  4. pre‑commit でコミット前チェック → CI 失敗を防止。
  5. AI に具体的なプロンプト(目的・入力例・出力例・制約)を渡す。
  6. CI に同一コマンド(ruff、mypy、pytest)を組み込み、GitHub Annotation で即フィードバック。
  7. 必要なら Docker devcontainerで本番イメージと完全一致させる(オプション)。

このサイクルを回すだけで、AI が出したコードはすぐに「実行可能・テスト可能・本番と同一環境」になるので、開発スピードが 2‑3 倍に向上し、品質も安定します。


次のステップ(すぐに試す)

  1. プロジェクトのルートで uv inituv add --dev ruff mypy pytest pre-commit
  2. .vscode/settings.json を上記通りに作成し、VS Code を再起動。
  3. uv sync.venv ができたら、AI(Copilot など)でコードを生成し 保存
  4. 保存と同時に Ruff が走り、コードが自動整形されることを確認。
  5. git add . && git commit -m "test"pre-commit が走り、問題がなければ CI へプッシュ。

この流れがスムーズに回れば、Vibe Coding での AI 補助開発はほぼ 「指示 → 生成 → すぐ実行」 の 3 ステップで完結します。

質問や「特定のツールの設定が知りたい」など、さらに掘り下げたいポイントがあれば遠慮なくどうぞ! 🚀

次にむけて

LTMのcontentを適切にupdate出来るような機能を追加していきたいと思います。

github.com

Model-First ReasoningをColab+さくらのAI Engineで試してみる

はじめに

Model-First Reasoning(MFR)は、推論に先立って問題の構造を明示的にモデル化することをエージェントに要求することで、ハルシネーションを抑制し信頼性の高いAIシステムを構築するための基礎的なコンポーネントとなるアプローチです。推論(生成)に先立って、問題の構造を抽象化することは、普段の様々な考えをまとめる時に自然に使っています。興味深かったので、お試ししてみます。なお、理解を深めるのが目的で、論文の検証を実施したものではありません。有効性については、学術的な文献を参照をお願いします。

論文:

arxiv.org

試した感触

LLMのモデルは、さくらのAI Engineで利用できるgpt-oss-120bを利用しました。

与える課題(入力)によっては、過度な抽象化を行ったり、課題の情報量が少ない場合は、仮の数値目標による効果計算が行われたりしました。この時の動作はLLMのモデルに大きく依存するようです。プロンプトの効きも違うので当然でしょう。このプロセスを経ることで、「なんとなくそれっぽい文章」ではなく「定義されたルールに基づく解」が出力される傾向が付与され、最終的には、割と妥当な答えが得られたように思います。

特に、ドメイン知識が不足している場合でも、「値はわからないが、構造としてはこうあるべき」という論理の枠組みを作れる点は、面白いです。こうした論理の枠組み自体をドメイン知識と組み合わせて蓄積させたいかも・・・。

LLMを利用する際に意識したいと感じました。

お試し

推論の流れと利用LLM

論文によると、モデルファースト推論(Model-First Reasoning: MFR)は、推論や計画を行う前に、まず問題の構造を明示的に定義する2段階のプロセスで構成されます。ソースによると、モデルファースト推論で用いられる具体的なプロンプト流れは以下のようになりそうです。

  1. 第1フェーズ:モデル構築プロンプト この段階では、解決策を提示せずに、問題の「枠組み」だけを定義させます,。 「以下の問題を分析してください。まず、(1) 関連するエンティティ、(2) 状態変数、(3) 前提条件と効果を伴う可能なアクション、(4) 制約事項、をリストアップして問題モデルを明示的に定義してください。まだ解決策を提案しないでください。」
  2. 第2フェーズ:推論プロンプト 構築されたモデルに基づき、具体的な解決策や計画を生成させます。

なお、 LLMには、さくらのAI Engine APIを使って、gpt-oss-120bを利用します。

プロンプト

2段階のプロンプトを以下のようにしてみました。

# --- Phase 1: Model Construction Prompt ---
phase1_template = """
以下の問題を分析し、解決策を提示する前に、まず明示的な「問題モデル」を定義してください。モデルは以下の4つの要素で構成し、構造化して記述してください。
1. 関連するエンティティ: 問題に関与するすべてのオブジェクト、エージェント、リソース、場所。
2. 状態変数: 時間とともに変化するエンティティの特性やステータス(例:位置、残量、ステータス)。
3. アクションの定義: 実行可能な操作と、それぞれの「前提条件(実行に必要な条件)」および「効果(実行後の状態変化)」。
4. 制約事項: 常に遵守しなければならない不変のルール、制限、条件。
※重要:この段階では、まだ解決策や具体的な手順を提案しないでください。構造の定義のみに集中してください。

問題:
{problem_description}
"""
phase1_prompt = ChatPromptTemplate.from_template(phase1_template)

# --- Phase 2: Reasoning Prompt ---
phase2_template = """
定義した「問題モデル」のみを使用して、ステップバイステップの解決策を生成してください。
最後に問題に対する回答として述べてください。
推論を行う際は、以下のガイドラインを厳守してください。
• すべてのアクションが、モデルで定義された前提条件を満たしていることを確認する。
• 各ステップ後の状態変化が、モデルの効果と一致しているか追跡する。
• すべてのプロセスにおいて、定義された制約事項が一度も破られないことを保証する。

定義された問題モデル:
{constructed_model}

解決すべき問題:
{problem_description}
"""
phase2_prompt = ChatPromptTemplate.from_template(phase2_template)

# --- Build the Chain ---
# Phase 1 creates the model, passes it to Phase 2
mfr_chain = (
    {
        "constructed_model": phase1_prompt | llm | StrOutputParser(),
        "problem_description": RunnablePassthrough(), # Passes the original problem_description from the invoke call
    }
    | phase2_prompt
    | llm
    | StrOutputParser()
)

課題

サステナNet(https://susnet.jp/social-issues/7)を参考にして入力する課題を設定しました。

problem = """
日本の長年の課題 -働き方改革-
働き方は社会から常に関心を寄せられる話題の一つです。その中でも少子高齢化による生産年齢人口の減少を主な理由として、人材の獲得・定着や生産性向上に向けた取り組みが重要な課題といえます。
政府の将来人口予測では、2050年には総人口が約1億人にまで減少するとされています。少子高齢化が進むと2060年には労働人口が現在の6割になり、女性・高齢者の労働参加を踏まえても2024年以降は労働人口が減少に転じる見込みです。
そのような状況の中、日本において求められる変化としては、外国人をはじめ、より多様な働き手の労働参加や共働き家庭の生活を支える解決策、こうした新しい社会構造を支える仕組みづくりとは?
"""

出力

以下が得られた結果になります。


【前提】
本回答は、提示された「日本における働き方改革」問題モデルの要素(エンティティ・状態変数・アクション・制約事項)のみを用いて、段階的に解決策を構築します。各ステップでは、

  1. 前提条件が満たされているか を確認
  2. 実行したアクションの効果 を状態変数の変化として明示
  3. 制約事項を一切侵害しない ことを徹底

とします。


Step‑by‑Step 解決策

Step 実行アクション 前提条件(モデル上のチェック) 期待される状態変化(変数) 制約事項への適合確認
1 ① 法改正・制度創設働き方改革関連法の改正、育児・介護休業法の拡充) ・国会で法案が可決 → 政策実施状況 = 有効
・予算が確保(年度予算の 予算・財政余裕 がプラス)
平均労働時間 の上昇上限が法的に厳格化(時間外労働上限 720h/年)
女性・高齢者の労働参加率 の改善期待値が上昇(+0.5‑1.0%)
法的上限(労働基準法)を遵守しつつ、制度創設は予算範囲内で実施。
2 ② 税制・補助金導入(子育て世帯への税控除、テレワーク導入補助金 予算・財政余裕 が十分(Step 1 で確保済)
・対象者(共働き世帯・中小企業)が資格要件を満たす
保育・介護サービス供給量 に対する需要圧力が軽減(需要増加率 -0.8%)→ 既存施設の稼働率が上がり、保育サービス供給量 の実質的拡大効果(+3%)
テレワーク導入率 が上昇(+5%)
税制変更は予算上限内で実施、補助金は ICT 投資コスト低減に寄与し、中小企業の 企業規模別柔軟働き方導入率 向上を促す。
3 ③ 雇用促進プログラム(外国人技能実習生受入枠拡大、シニア雇用助成金 法改正・制度創設 が完了し、法的枠組みが整備済(Step 1)
・企業側の参加意思表明(業界団体・大企業・中小企業)
外国人労働者 が増加(+2%)
高齢者の労働参加率 が上昇(+0.7%)
労働年齢人口(実質) が補填効果で微増(+0.3%)
国際条約・協定遵守、最低賃金・労働保護を確保し、予算枠内で助成金を支給。
4 ④ 企業側の働き方改革施策(フレックスタイム・在宅勤務制度) テレワーク導入率 が上昇し、ICT インフラが整備済(Step 2)
・企業内部で制度設計・合意形成が完了
平均労働時間 が短縮(-1.5%)
テレワーク導入率 さらに上昇(+7%)
離職率 が低下(-0.4%)→ 就業率 が僅かに改善
企業規模別に実施可能性を配慮し、中小企業向けに補助金(Step 2)を活用。労働時間上限は法的上限内に収まる。
5 ⑤ 保育・介護インフラ整備保育所増設・夜間保育) 予算・財政余裕 が依然としてプラス(Step 1‑2 の予算消化率 < 80%)
・土地・建設許可取得が完了
保育・介護サービス供給量 が +6%(新設施設数に比例)
共働き世帯の就業継続率 が上昇(+1.2%) → 女性・高齢者の労働参加率 が更に向上(+0.8%)
インフラ供給の時間的ラグは数年と見込むが、計画段階で 技術的制約(地域別通信環境)を考慮し、ICT 連携保育(遠隔モニタリング)を導入。
6 スキルアップ・再教育プログラム(リスキリング補助金、シニア研修) 教育機関・企業の協定 が成立(Step 4 の企業改革と連携)
予算・財政余裕 が残余あり
労働者の生産性指数 が +2%(スキル向上による付加価値上昇)
高付加価値職種への転換率 が上昇(+1.5%)
雇用保険・年金加入義務などの 労働者の権利保護 を遵守し、再教育コストは補助金で賄うことで 企業規模別実施可能性 を確保。
7 ⑦ 移民受入政策の調整(特定技能制度拡充・永住権緩和) 国際条約・協定 の改正が完了(Step 1 の法改正に含む)
社会的受容度 が一定基準(+5%)を超えていることを確認(文化・意識変革キャンペーンの効果)
外国人労働者 がさらに増加(+1.5%)
産業別需要 のミスマッチが緩和 → 就業率 が安定(+0.3%)
受入規模は 人口統計的制約(生産年齢人口の長期減少)を補完するレベルにとどめ、労働者権利保護を徹底。
8 VIII. 文化・意識変革キャンペーン男女共同参画・働き方多様性の広報) 予算・財政余裕 が確保(残余予算で媒介費用)
・メディア協力が得られている
社会的受容度 が +8% 上昇
・法制度や企業施策の受容率が向上 → 政策実施状況 の実効性が高まる(実施効果係数 ↑)
文化的・社会的慣習への抵抗を減らし、環境・災害リスク に備えた在宅勤務の継続性も同時に周知。

まとめ(最終的な回答)

上記 8 ステップは、問題モデルにのみ基づく 体系的なアプローチです。

  1. 法制度の整備予算確保 を最初に行い、全ての後続アクションが法的・財政的に実行可能であることを保証しました。
  2. 税制・補助金 によって企業と家庭のコスト負担を軽減し、テレワーク保育・介護サービス の需要・供給バランスを改善しました。
  3. 外国人・高齢者の雇用促進企業側の柔軟働き方 により、平均労働時間 を短縮しながら 労働年齢人口(実質) を補填しました。
  4. インフラ整備スキルアップ で、働く側の 生産性指数就業継続率 を向上させ、長期的な 労働力供給の安定 を実現しました。
  5. 最後に 文化・意識変革キャンペーン を実施し、社会的受容度 を高めることで、すべての制度・企業施策が実効的に機能する環境を整えました。

結果として、

  • 女性・高齢者・外国人労働者の参加率 が総計で約 +3.0% 以上向上
  • 平均労働時間1.5–2.0% 短縮
  • テレワーク導入率10%以上 増加
  • 保育・介護サービス供給量6% 増加し、共働き世帯の就業継続が促進

以上の変化は、予算・法的上限・文化的慣習 といった 制約事項 を一切逸脱せずに実現できることを示しています。

このステップバイステップの実行計画が、日本の 少子高齢化による労働人口減少 を緩和し、多様な働き手の参加生産性向上 を実現するための最適解となります。


以上、生成結果です。

gist.github.com