Inside of LOVOT

GROOVE X 技術ブログ

Jetsonを使うときの細かい話

この記事は、GROOVE Xアドベントカレンダー2025 の8日目の記事です。

こんにちはfmyです。皆さんはJetsonを使っていますか?

LOVOTではJetson Orin NXシリーズを採用しています。 Jetsonは公式のライブラリやリファレンスが充実しており扱いやすいのですが、 開発キットそのままを動かすことはできても、カメラをつないだり開発キット以外のキャリアボードを使うと未知の挙動に悩まされることがあります。 ここではJetsonを使うアプリケーション開発者が知っておくと役に立つかもしれない話をします。

Jetson LinuxのBoot Flow

アプリケーション開発者にとっては起動後に何するかが重要ですが、Jetson Linuxは起動前に色々しており、アプリケーション側にも大きく関係します。

The following diagram shows the flow of control in the boot software
Jetson AGX Orin, Orin NX and Orin Nano Boot Flow

上はJetson Linuxのソフトウェアリファレンスから引用したブートソフトウェアの制御フローの図です。 大まかに3ステージに分かれており、BPMPではJetsonのデバイスを利用可能にし、PSCはLinuxのセキュリティを担当し、最後にCPUが起動してLinuxカーネルを起動します。 起動しなかったりデバイスが認識されないときには正しくflashできているかを確認しましょう。

BPMP設定例: Super Mode

2024/11/17にOrin Nano 開発キットの"Super" Boostが発表され、JetPack 6.1.1で有効化されました。 この機能はどのように実現されているのでしょうか?

JetsonはnvpmodelでCPUやGPUなどのクロックの設定をできるようになっています。 特定の電力制限モードではこのファイルに上限値を設定してますが、MAX_Nモードの場合は-1で別のところで定義された設定可能な最大値を指定するようになっています。 この最大値がBPMPのデバイスツリーによって設定されています。 Jetson Linux 36.4で追加されているtegra234-bpmp-3767-0000-3768-super-maxn.dtbがまさにこのSuperモード向けの設定値が書かれたデバイスツリーなのです。

ということは、SuperMode対応以前のL4T 35.6.2でも、開発キットflash時に*super-maxn.dtbを使うことでDLAを1.2GHzで動作させることができます。 以下の例はL4T 35.6.2でSuperModeと同じ周波数で動作させている例です。DLAは本来614.4MHzですが1.2GHzとなっています。

SuperMode jtop (ただし、古いバージョンでのSuper boostはサポート外と思われるのでご注意ください)

キャリアボードのEEPROM

BPMPではSoCだけではなくキャリアボードもみます。 Jetson EEPROM Layoutに書かれている情報です。 MACアドレスの指定を行うことを想定されており、CRC-8検証が通らなければJetsonは起動しないようになっています。

もしも何らかの理由でキャリアボードのEEPROMにアクセスできない場合はEEPROM ModificationsにあるようにEEPROMを無視させることで起動できるようになります。

# Linux_for_Tegra/bootloader/t186ref/BCT/tegra234-mb2-bct-misc-p3767-0000.dts
- cvb_eeprom_read_size = <0x100>
+ cvb_eeprom_read_size = <0x0>

Timerの話

Jetsonを使いたい人の多くは何らかのセンサー、特に画像のようなデータを処理したいケースが多いでしょう。 そしてセンサー値を扱うにはデータの時刻が重要ですね。 Jetsonはそのような用途のためにTimerの実装がされています。

次の図はOrin SoCのマニュアルにあるTimerの階層です。

Timer Hierarchy
DP-10508-002_v1.2 | Page 5785

Jetson SoCではTSCというタイマーを元にしてCPUやカメラ関係のブロックにSecondary TSCの名前で38.4 MHz(26.04ns解像度)の信号を、NV関係はNV Timerの名前で1 MHz(1us解像度)でクロックが供給されています。 カメラ関係に付与されている各タイムスタンプはSecondary TSCで付与された値になります。 また、L4T 36.xではLIC IRQやGPIOの変化についてもTSCのタイムスタンプを得る方法をHTE Driverとして提供されています。

TSCというのは Timer's System Counterの略称で、より一般的にはTimeStamp Counterと呼ばれる機能と同じものになります。 一定周期でカウントアップするもので、これ自身は何らかのリファレンス時計と同期をしているものではありません。 このカウンタ値をUnix Timeなどに変換するには、現在のTSCとセンサー値の差分を現在時刻から引くことで求めます。

またSecondary TSCはArmのGlobal Timerとしても供給されているため、LinuxからもアクセスできてMONOTONIC_RAWに対しては固定のオフセットがある値になります。 TSCの取得はArmのCNTVCT_EL0命令を使います。

L4T 35.xまではTSC - MONOTONIC_RAWの値であるoffset_nsという値がsysに出力されていましたが、L4T 36.xからはCPU命令での取得を推奨されています。

何らかの時刻に変換するなら、TSCと同時に時刻を取りセンサー値との差分を時刻から引けばよいです。 可能な限り同時に時刻を取るならforumと同様の実装で実現できます。 以下はRustでの実装例です。

pub fn get_ts_with_clock(clock_id: nix::time::ClockId) -> nix::Result<(u64, TimeSpec)> {
    // Conversion constants for cycles to nanoseconds
    const CYCLES_MULTIPLIER: u64 = 100;
    const FRQ_DIVISOR: u64 = 10000; // Jetson Orin TSC frequency is Fixed at 31,250,000 Hz
    const NS_MULTIPLIER: u64 = 1000;
    // Conversion formula:
    unsafe {
        let mut cycles: u64;
        let mut frq: u64;
        std::arch::asm!("mrs {0}, cntfrq_el0", out(reg) frq);
        std::arch::asm!("mrs {0}, cntvct_el0", out(reg) cycles);
        let r = clock_id.now()?;
        let tsc_ns = (cycles * CYCLES_MULTIPLIER / (frq / FRQ_DIVISOR)) * NS_MULTIPLIER;
        Ok((tsc_ns, r))
    }
}

カメラのタイムスタンプ

カメラ画像には2つのタイムスタンプ、SoFとEoFが付与されています。 ArgusAPIからはSoF, EoFが取得でき、V4L2ではSoFがタイムスタンプとして用いられます。

vb->vb2_buf.timestamp = descr->status.sof_timestamp;

SoFやEoFの時刻は以下のようなイメージで、露光後転送したデータを受信した時点のTSCとなっています。 ローリングシャッターなら最初のラインの露光が終わって露光と転送をしている途中の時刻となります。

SoFとEoF

V4Lのストライドの話

V4Lの場合はArgusAPIと比較してアクセスできる情報も少なく、画像についてもArgusAPI経由とは異なる制約があります。 V4LバッファーはVIのATOMP(Atomメモリパッカー)が書き込みを行っており、このブロックは1atom=64Bのアライメントで動作しています。 画像の1ラインの長さがこのアライメントと合わない場合、受信した画像データは欠損したりずれることがあります。 この問題を回避するにはV4Lのコントロールにあるpreferred_strideを32の倍数(1pixel=2Bytesの場合)に拡張することでパディングを含んだ形で正常なデータが受信でき、後で範囲外のデータを削除する必要があります。(forum)

おわりに

Jetsonと周辺機器を使うときに躓きやすい要素を紹介しました。

最後になりますが、GROOVE X ではロボット開発したい人材を募集しています。ぜひ以下のリンクからご応募ください!

採用情報 | GROOVE X株式会社

入社して2ヶ月で感じたGROOVE Xの面白さ

この記事はGROOVE X Advent Calendar 2025の7日目の記事です。

はじめまして。今年(2025年) 10月に入社したばかりのPeacock (id:peacock0803sz)です。Kiban ワーキンググループのクラウドチームに所属しています。
よく聞かれる「LOVOTのように高性能なCPUを積んだロボットとクラウド環境がどう繋がっているのか」という疑問に、入社から2ヶ月経ちましたが全く説明できる気がしない今日この頃です。

入社時にエントランスで撮った一枚

入社してからは、機体のバックアップやOS更新を支えるTerraformコードを含めクラウドインフラのメンテナンスや最適化などを担当しています。

チームに上司がいない

スクラムについての話は、入社時期が近いsugamoさんのエントリを参照いただくとして、個人的に入社して一番驚いたのはこれです。

tech.groove-x.com

実は私自身スクラムは経験したことがなく、初めて完全にフラットな組織で仕事をしています。
そんな経験でも入社後に(元々クラウドでも活躍されていた!)スクラムマスターのniwano (id:kosuke_n)さんが研修会を開いてくれたので、不安は払拭されました。

加えて現在GROOVE Xのエンジニア組織は100名に近い規模で、もちろんソフトウェアだけでなくハードウェアを扱うエンジニアも所属しています。
特にKibanワーキンググループは(自分と比較的近い)Web開発者のようなバックグラウンドでない方も多いと聞いていたのですが、私のバックグラウンドも受け入れられて感激しています。

何でも屋が歓迎される・多種多様なメンバー

これはスクラムを採用しているエンジニア組織であることの大きなメリットなのではと感じていることです。 前述の通り100名近いエンジニア・全社員で約250名にもなる規模の会社ですが、とても気軽に部署・チームを越境して相談や仕事ができる環境です。

ソフトウェアエンジニアとして入社しましたが、先月行なわれた10周年記念イベントでは映像・音声スイッチャーを操作する機材オペレーターをやっていました(笑)

イベントでの機材卓の様子

GROOVE XではLOVOTの服も自社で設計・販売している関係もあり、実は直近ではアパレルの関係者と仕事をしたりもしています。

エンジニア間で決められることが(比較的)多い

(店舗に勤務されている方も増えましたが)エンジニア・デザイナーといった技術職が多くを占める会社ということもあり、自分達で会社のルールを決める文化が強いです。
実際に毎週火曜日の朝には「自分たちの会社は自分たちで良くしていく会」という名の予定があります。この会に議題が上がり、会社のルールが変わることが入社してからも数件ありました。
私の観測範囲でも聞いたことがないレベルで、ここまで裁量が大きいのは素晴しいと思っています。

おわりに

これからもクラウド技術を軸にLOVOTと一緒に成長できたらと思っています。

最後にGROOVE Xでは、一緒に働く仲間を募集しています。
興味のある方は、ぜひ下記から募集中のポジションを確認してみてください。
recruit.jobcan.jp

もちろん私(Peacock)に直接「カジュアル面談してくれませんか」のDMも歓迎です!

LOVOTを部品レベルから高品質に作り上げる!

こんにちは!GROOVE X(株)、生産チームの小川です。

この記事はGROOVE X Advent Calendar 2025の6日目の記事です。

今回は、生産チームの役割の1つ「部品メーカー様の工程を監査する」 について、 お話ししようかと思います。

生産チームでは、

「良い品質のものをお客様に提供する」

を合言葉に日々LOVOTを製造・出荷しております。 LOVOTの生産工程での作り込み、検査の精度アップはもちろんですが、 LOVOTを構成する個々の部品品質も重要なものと考えています。

なぜなら、

品質の良いLOVOT=品質の良い部品の積み重ね

と考えているからです。

ですので、

部品メーカー様に品質維持・向上してもらう事が我々のタスクの1つになります。

もちろん、適正価格で、納期遅れが無いことが前提条件です。

では、

「部品メーカー様の品質を維持・向上をしてもらう事」と

「部品メーカー様の工程監査を弊社が実施する事」が

どう関係するのでしょうか? それを説明していきます。

この品質維持・向上を常に目指して、部品を生産して頂いているか、実際の工場にお邪魔して、 現場の方と話をし、現場を見て、確認する、これが工程監査です。

「3ない(さんない)ポリシー」

こういう言葉を聞いたことありますか?

ものづくりの工場において、 一般的に品質管理(品質保証)における「3つの基本原則」のことを指します。

これは「不良品(欠陥品)を徹底的に排除し、顧客に完璧な製品を届けるための鉄則」なのです。

具体的には、以下の3つの「〜ないで構成されています。

  • 不良持ち込まない、又は、もらわない

 ➡いかに不良を外から持ち込まないようにしているか?

  • 不良を作らない。        

 ➡いかに不良を作らないようにしているか?

  • 不良を流出させない

 ➡万が一不良を作ってしまったとしても、いかに流出を予防しているか?

なぜ、監査が必要なのか? それは、この「3ない(さんない)ポリシー」を持って常にもの作りをしているかを現場で確認し、品質を維持・向上をしているかを確認したいからなのです。

さて、それでは実際の監査の流れを見てみましょう。

1.あいさつ

2.会社説明(相互に)

3.その日のおおまかなスケジュール確認

4.工程で確認したいポイントの概略説明

5.現場の工程確認

6.まとめの会議

5の現場の工程確認に大半の時間を割く事になります。 現場確認以外の項目は、会議室で行います。

5.現場の工程確認【詳細】

基本的に、製品が出来るまでの工程を順番に確認していきます。 想像しやすいように、プラスティック部品1つを例に取ってみます。 確認させて頂く工程は、大まかに以下のようになります。

原材料保管倉庫➡製造準備室➡製造工程➡検査工程➡梱包工程➡出荷待ち倉庫

工程監査用のチェックシートが有るので、それをベースに細かな点を工程ごとに確認していきます。

多数ある確認項目の中から、原材料保管倉庫での確認項目の一例を紹介します。

プラスティック部品の品質は原材料に大きく左右されるため、保管倉庫での品質管理は非常に重要です。今回は、監査者と現場メンバーによる原材料の品質確保に関する具体的なやり取りを例に、その確認項目を見ていきましょう。

原材料の品質確保をする為に、以下のようなやり取りを現場で行います。監査者の質問(Q)に、現場の方が回答(A)するようなやり取りになります。

原材料保管倉庫でのやり取り例

Q1. この倉庫の温度、湿度の管理をしていますか?

A1. はい、温度は20℃~28℃で管理しています。

湿度は40%~60%で管理しています。

Q2. 書面化されたルールは有りますか?

A2. はい、こちらです。(書面を見せてもらう。)

Q3. そのルールは正しく運用できていますか?

A3. はい、書面のルールで記されているように、

毎日、9時、13時、17時に温度計、湿度計の数値を確認し、チェックシートに記載しております。
現場作業員がチェックシートに記載し、
現場リーダーが記載内容を確認します。
もし、異常が有れば、即座にリーダーを中心に
異常の原因を確認します。

監査者は、実際に使用されている、温度計、湿度計、及びチェックシートを確認させて頂きます。

確認したい項目は温湿度だけではなく多々有り、それぞれの工程で確認したい項目が有りますので、 都度確認し、出来る限り疑問点を解消して次の工程へ向かいます。

原材料倉庫で温度・湿度の確認をしている様子(イラストはイメージです)

監査後は、会議室に戻り、良かった点、不安を覚えた点、疑問点についてまとめを一緒に行います。 疑問点は、出来るだけその場で解消します。

良かった点は継続してもらいたいとお伝えし、 改善を要す点が有れば率直にお伝えし、改善をお願いします。

もちろん、先方の考え方や、状況の詳細をお聞きしますが、その場では改善できるかどうか結論が出ない場合もあるので、そのような点は持ち帰って検討して頂くことになります。

まとめの会議の様子(イラストはイメージです)

監査内容をまとめた後は、意見交換をしたり、 先に行った会社説明に対しての質疑応答、 その他、本日の監査全体に対しての質疑応答の時間を持ちます。 最後は、疑問を解消し、お互いの親交を深め、今後も両社の絆を強めWin-Winの関係を継続していけるよう握手をし、監査は終了します。

以上が監査の流れとなります。

ところで、LOVOTの構成部品は、 樹脂、センサー、サーボモーター、カメラ、有機ELパネル、電子基板、アンテナ、服、ケーブル、バッテリー・・・等々、作って頂いている部品メーカー様の数は、多数になります。(ちなみに、部品点数は5,000個以上になります!)

そして、日本の工場だけではなく、海外工場にも出向き、 監査を実施することもあります。 1日に多くても2社くらいしか回れませんから、長期の出張になることも あります。

そんな生産チームの役割の1つ「部品メーカー様の工程を監査する」 に興味が湧いてきたあなた!

そして「LOVOTを部品レベルから高品質に作り上げる!」事にチャレンジしてみたい方!

お客様に高品質のLOVOTを提供し、喜んでもらいたいと感じた方!

こちらにアクセスしてみてください!

↓     ↓     ↓     ↓

recruit.jobcan.jp

生産チームは、タスクが多岐にわたるので、監査業務はほんの1例ですが、まだまだ進めて行きたいタスクはあります。 「自分には、これしかできない」と自身で仕事の幅を限定せず、製造・生産に関わるタスクは何でもこなす!と構えられる方、 是非一緒に働いてみませんか?

LOVOTの開発現場で学んだスクラムについて

この記事はGROOVE X Advent Calendar 2025の5日目の記事です。  
 
はじめまして。2025年9月に入社したばかりの新入りsugamoです!GROOVE XのAPPチームに所属しています。
LOVOTのアプリは、LOVOTの各種設定を行ったり、LOVOTの状態を通知したりするLOVOTとオーナーさんをつなぐ架け橋のような存在です。
今年は、アプリ内でLOVOTをお着替えできる「フィッティングルーム」機能や、看板LOVOTがホーム画面に遊びに来てくれる「LOVOTの日」をより楽しめる演出など、さまざまなアップデートを行いました。LOVOT本体に負けないよう、アプリも日々進化を続けています!

さて、GROOVE Xでは『スクラム』というフレームワークを用いてソフトウェア開発を行っています。スクラムのフレームワークを通じて、最大限の価値提供を重視した開発体制となっています。 本記事では、入社して実際にスクラム開発を経験して感じたことをアウトプットしていきたいと思います。

ソフトウェアチームにおけるスクラム開発

スクラムとは、定義された枠組みに沿って、短いサイクルで開発と振り返りを繰り返す開発フレームワークです。 *1

ソフトウェアチームでは、2週間を1スプリントとして開発を進めています。
すべてのチームがプランニング、デイリースクラム、スプリントレビュー、振り返り(レトロスペクティブ)といったスクラムイベントを実施しながら、それぞれの目標に向かって開発を行っています。

私が最初にスクラムを学ぼうとした際は、横文字の用語や聞き慣れない概念が多く、理解するのが難しかったです。前職ではスクラムの存在自体は知っていたものの、最終的に導入を断念してしまった苦い経験があります。
しかし、GROOVE Xではすでにスクラムが開発プロセスとして定着しており、毎スプリントのスクラムイベントに参加していく中で、自然と理解が深まっていきました。
さらにGROOVE Xにはスクラムマスターがいます。入社後すぐにスクラムに関する資料を共有していただいたほか、スクラムワークショップを開催し初学者同士で学び合える場を用意いただき、よりスムーズに理解を深めることができました。

スクラムでの開発で感じたこと

開発の自由度

プランニングでは、APO(エリアプロダクトオーナー)と次スプリントの開発内容を相談して決定します。
どのプロダクトバックログアイテム(PBI) が必要・不要など優先度の調整はあるものの、基本的にチームで必要だと判断しピックアップしたPBIを次スプリントで開発していくことが多いです。 コンセンサスを取りながら自分たちの判断で開発を進められるため、私にとってはとても自由度の高い開発現場だと感じています。

チームそれぞれで最適な形に

同じソフトウェアチームの中でも、チームごとにスクラムイベントの進め方は大きく異なっています。APPチームでは朝一でデイリースクラムを実施していますが、昼に行うチームもあります。PBIをホワイトボードで書き出して管理するチームもあれば、Webのツール上で完結しているチームもあります。 組織の偉い人がチームの仕事の進め方を細かく規定するのではなく、示された大きな方針を各チームで解釈し実践していくのは、自律的なチームの在り方だと感じました。

とはいえ課題はある

長年スクラムを実践しているソフトウェアチームですが、今でもスクラムの開発の進め方について頻繁に議論が行われています。
スクラムのフレームワークに従い、仕事の進め方を決めたからといって理想的な開発チームとなるわけではなく、常に理想的な形を議論し、実践し、振り返ることを継続することの重要性を学びました。 スクラムは「完成形が存在する仕組み」ではなく、「より良くするために改善し続ける仕組み」なのだと実感しました。

おわりに

入社してから、特に印象に残ったスクラムでの開発について感想を述べさせていただきました。

LOVOTは最先端技術の結晶のようなロボットですが、実際に開発に関わってみるとまだまだ大きな伸びしろがあることを知りました。ここからさらに進化していく姿を想像して、毎日ワクワクしています。
LOVOTの成長に負けないよう、アプリもより快適に、そしてオーナーさんに楽しんでいただける機能を提供しながら、進化を続けていきたいと思います!

   
GROOVE Xでは、一緒に働く仲間を募集しています。
興味のある方は、ぜひ下記募集にアクセスをお願いします。 recruit.jobcan.jp

*1:アジャイル開発手法の一つ。プロダクトオーナー・スクラムマスター・開発者という3つの役割や、スプリントと呼ばれる1週間〜1ヶ月程度の固定された期間、その中で行うスクラムイベントなどが定義されている。計画・実行・学習のサイクルを高速に回すことで、変化の激しい状況でも価値の高いプロダクトを効率よく届けることを目的としている。

仮説思考:隠れた仮説を暴き、新しい仮説をぶち上げよう!

この記事は、GROOVE Xアドベントカレンダー2025 の4日目の記事です。

はじめに

こんにちは、技術組織デザインチームの junya です。
最近、社内での提案資料や企画書を書くことが多いのですが、 自分の提案の背景にある仮説に思いを馳せることによって、課題に対する解像度が上がる ことを実感したので、それをご紹介します。

お題

ここでは以下の2つの行動指針について、考えてみます。

  • 依頼には質の高い成果物で応えよう
  • 情報は自分で取りに行こう

皆さんの会社にも、このような行動指針があったりしませんか?
この行動指針の裏にある、隠れた前提条件(仮説)について考えてみます。

行動指針の裏にある仮説

これらの行動指針は、基本的には有用であるものの、極端に言えば、以下のような状態を仮定していないでしょうか。

依頼には質の高い成果物で応えよう

  • 依頼者は、自分が欲しいものを完全に言語化してくれている
  • 質は高ければ高いほうが良い

情報は自分で取りに行こう

  • 全員が情報に対するアクセス権を持ち、何がどこにあるか分かっている
  • 人は自分の欲しいものがわかる

この前提条件(仮説)が成り立たないとどうなるか?

多くの場合は、このような前提条件を仮定しても問題ありませんが、常に当てはまるとは限りません。 これらの前提条件が整っていない(仮説が通用しない)ケースで、何が起きるか考えてみましょう。

依頼には質の高い成果物で応えよう

  • 一生懸命1週間かけて作ったものを「全然違う」と言われて、手戻りが発生する。

情報は自分で取りに行こう

  • アクセス権があって各所にコネクションがある古参は無双できるが、アクセス権がなくて「何が分からないかも分からない」新人は右往左往する。

心当たりあるのではないでしょうか。

こういうことが発生すると、その問題を解消するために、逆方向の価値観への力学が働きます。課題を解決するための新しい行動指針を考えてみましょう。

新しい行動指針(アンチテーゼ)

課題を解決するために、新しい行動指針を立ててみました。

  • (新)早く成果物を共有して、早い段階でフィードバックをもらおう
  • (新)できるかぎりの情報をドキュメント化しよう

この新しい行動指針の裏にも、当然、仮説が隠れています。

早く成果物を共有して、早い段階でフィードバックをもらおう

  • 成果物を共有したら、フィードバックがもらえる。
  • 早い段階で成果物を共有すれば、認識のズレを減らせる。

できるかぎりの情報をドキュメント化しよう

  • ドキュメント化されていれば、その情報を活かせる
  • みんなが少しずつ努力すれば、隠れた知見をドキュメント化できる

行動指針は良くなったのか?

これで、人々はより動きやすくなったのでしょうか?

はじめの行動指針同様、多くの場面では期待通りに機能するかもしれませんが、以下のような問題も発生しそうです。

早く成果物を共有して、早い段階でフィードバックをもらおう

  • 品質を重視していたときと比べて、品質が低いまま成果物がリリースされる。
  • 成果物の作り込みが甘く、レビューが繰り返され、かえって時間がかかる。

できるかぎりの情報をドキュメント化しよう

  • ドキュメントのメンテナンスコストが増大する。
  • 新しい情報と古い情報が入り乱れて、どれが正しいかわからなくなる。

もちろん、良い効果もあります。
しかし、このような課題が顕在化したら、改善したくなります。

あるいはもしかすると、元の行動指針を策定した人は、ここにあげたような苦い思い出があり、それがきっかけで「品質重視」と「情報を取りに行く姿勢」を大切にしたのかもしれません。

古い仮説 vs 新しい仮説

これら新旧の行動指針を俯瞰してみると、相反する2つの価値観の対立関係にあることが分かります。

品質とスピード

  • 一生懸命1週間かけて質の高いものを作っても、「全然違う」と言われて、手戻りが発生してしまうことがある。
  • スピードを重視するあまり品質を軽視すると、やり直しが増えてかえって時間がかかったり、最終成果物の質が落ちることがある。

ドキュメントと主体性

  • 「情報は取りに行け」と言っても、アクセス権がなく、「何がわからないかも分からない」人は、右往左往してしまう。
  • 膨大なドキュメントを管理しようとすると、ドキュメントの管理に追われて、本来の仕事ができなくなる。

あちらを立てればこちらが立たず。私たちはどうすれば良いのでしょうか?

発展的解消という考え方

一見対立する二つの価値観を両立することは、哲学の分野において「発展的解消」「昇華」「アウフヘーベン(止揚)」「対立した矛盾の実現」などと言われます。

これはとても難しいのですが、現実世界にはこの「止揚」を実現したもので溢れています。
たとえば、Netflix に代表されるサブスクモデルでは、

  • 購入: 自分のものになるが、高い
  • レンタル 安いが、自分のものにならない

の「所有欲 vs コスト」の矛盾を、 「固定の月額で、膨大なライブラリにいつでもアクセスできる権利」 というモデルで、両立させています。

世の中は「止揚」で溢れているという事実に気づけば、どこかしらに解決策が隠れていることを信じて、思考を続けることができます。

相反する2つの仮説を踏まえた施策

では最後に、なんとか対立2つの価値観を両立してみましょう。
私なりの提案をしますが、正解は1つではないので、ぜひ皆さんも考えてみてください。

ペアワークしよう

  • 早い段階で、依頼者とのペアワークの時間を持ち、求められる成果物の認識合わせをすることで、スピードと品質を両立できる。

成果物を作成するプロセスを共有することで、依頼者が言語化できていない要望もすり合わせることができます。 これにより、「質(完璧を目指す)」と「スピード(とりあえず出す)」という対立を乗り越え、認識のズレを早期に解消しつつ、効率的に品質を高めることができます 。

質問に答えてもらったら、文書にまとめよう

  • 気軽に聞ける環境を作りながら、質問をした人は新しく獲得した知見を文書にまとめるようにすれば、主体性を引き出しながら質の高い文書を増やすことができる。

「気軽に聞ける環境(フロー)」を前提とすることで、誰もが情報にアクセスできる状態を作ります。 その上で、得られた知見を「文書化(ストック)」することで、「主体性(自分で取りに行く)」と「管理(ドキュメント整備)」という対立を統合し、個人の知見を組織の資産へと昇華させます 。

補足:学問的な視点から見る「仮説」

私の学問の師匠(南郷継正)は、

一般論(はじめの仮説)から出立し、すべての物事をその一般論で説明することを試み、事実と抽象の間を上り下りしながら、構造論(対象の論理的な構造はどうなっているか?)・現象論(現実の現象はどのように説明されるか?)を確立し、本質論(新しい仮説:対象の本質とは何か)に至る道が、学問の王道である。

というような事を述べています。

またドイツの哲学者ヘーゲルは、「プラトンの対話篇」の中に「滅ぼしあうような激しい闘論」の価値を見出しました。

自己否定をどれだけ繰り返し、それを乗り越えられるかが、本質を追求する道であり、仮説思考の真骨頂ですが、他者との激しい議論は、自己バイアスを排して自己否定する格好の場であり、他者からの反論に応えることは、自己否定を乗り越えて新しい仮説を見出すことに役立ちます。

​私たちが仕事の中で行っている「隠れた仮説を疑い、新しい仮説を作る」という営みは、実はこうした学問的な真理探究のプロセスと同じ構造を持っているのかもしれません。そう考えると、日々の業務も少しアカデミックで面白いものに見えてきませんか?

まとめ

以上、具体例を用いて、仮説思考の有用性を紹介しました。この記事で私が見出した施策・仮説も正しいとは限りませんが、仮説を疑うことによって新しい視点を獲得し、真理へと一歩ずつ近づくことができるのではないかと思います。

最近だと、AIでこのあたりの壁打ちができるようになったので、便利です。人との議論と比べると、バイアスがかかりやすいというリスクがありますが、 「これまでの議論を、批判的立場・中立的立場で検証してください」 というようなプロンプトを使えば、自己否定をして新しい仮説を見出すのに役立ちます。良かったら試してみてください。

追記

... というような記事を書いたら、ビヘイビアチームの市川さんが「Devin を用いて、対立する要求の発展的解消を実現した」記事を書いてくれてました。 よかったら読んでみてください〜!

tech.groove-x.com


GROOVE Xでは、一緒に働く仲間を募集しています!
少しでも興味を持ってくださいましたら、下記のリンクをご覧ください。

recruit.jobcan.jp

2.8万件のエラーを潰して大規模 Python プロジェクトを mypy strict 化した話

この記事は、GROOVE Xアドベントカレンダー2025 の3日目の記事です。

はじめに

こんにちは!ふるまいチームの橋本です。
普段は LOVOT の意思決定エンジンである NeoDM の開発を行っています。
今回は、Pythonで書かれたこの大規模な意思決定エンジンに対し、型安全性を高めるために mypy の strict モード を導入した取り組みについて紹介します。

NeoDM vs 型エラー

なぜ今、型安全性に取り組むのか

きっかけは「ぬるぽ」

あるリリースにおいて、NeoDMの一部機能で実行時エラーが発生してしまいました。
原因はいわゆる「ぬるぽ」(Pythonでは None に対するアクセスによる AttributeError)です。
変数が None かどうかのチェックを漏らした状態で参照してしまったためでした。
このバグは特殊な条件下でのみ発生するためQAでの検出が難しく、本番環境で顕在化してしまいました。
しかし、静的解析(Type Checker)が機能していれば事前に気づけた可能性が高いものでした。

既存の mypy 運用の限界

NeoDM は Python で実装されていますが、Python は動的型付け言語であり、一般的に静的型付け言語と比較すると型安全性が低いとされています。
ただし Python も型ヒント (Type Hint) をサポートしており、mypy などの型チェッカーを利用することで型安全性を高めることができます。

NeoDMでは以前から mypy を導入していました。
しかし、当時の運用は型ヒントの記述が必須ではなく、チェックの厳格さも緩い設定でした。

特に問題だったのが Any 型の黙認 です。
mypy 変数の型が推定できない場合、それを Any として扱います。
「何でもあり」な Any 型になってしまうと、その変数を扱う以降の処理では型チェックが事実上無効化されます。
その結果、今回のような None チェック漏れも見逃されてしまっていました。

また、型ヒントが不十分なコードは、新規参入した開発者や、最近導入が進んでいる Coding Agent (AI) にとって可読性が低いという問題も抱えていました。

28,631件のエラー

これらの問題を解決するため、コードベース全体で mypy --strict(厳しいチェックモード)をパスさせることを目標にしました。

試しに、当時のコードベースに対して strict モードでチェックを実行してみたところ...

> mypy --strict .
Found 28631 errors in 808 files

28,631件。
普通なら「そっ閉じ」する数字だと思います。
しかし、同じような事故を再発させないためには CI で型検査すべきなのは明らかです。
「以後気をつけます」は当てになりません。

再発防止と可読性のため、この大量のエラーを解消するトライを始めました。
加えて、最近は Coding Agent の性能が上がっているので案外簡単に対応できるのでは?とやや楽観的に考えていた節もありました。

移行戦略:モジュール単位で「後戻りさせない」

800以上のファイルをまとめて修正するのは現実的ではありません。
修正中にも他の開発者がコードを変更し、差分が衝突し続けるからです。

そこで、モジュール単位で段階的に strict 化する という戦略を取りました。

  1. 特定のモジュール(ディレクトリ)の型ヒントを修正する。
  2. 修正が完了したモジュールを「strict チェック対象リスト」に加える。
  3. CI でそのリストに含まれるモジュールに対して strict チェックを強制する。

これにより、一度修正したモジュールは二度と型安全性が低下しない、いわば「後戻りさせない」仕組みを作りました。

部分的に strict チェックを行う工夫

ここで技術的な課題がありました。
mypy はインポート先のモジュールも追跡してチェックを行います。
そのため、まだ strict 化していないモジュールに依存しているファイルをチェックすると、修正対象外のファイルの型エラーまで報告されてしまい、CIをパスさせることができません。

これを回避するため、エラー出力を grep でフィルタリングし、「対象モジュールのエラーだけを検出する」スクリプトを作成しました。

# check_strict_modules.sh

# チェック対象のモジュール一覧をスペース区切りで指定  
STRICT_MODULES="module_a module_b"

# 対象モジュールを正規表現のOR条件(moduleA|moduleB|...)に変換  
PATTERN_BODY=$(echo "$STRICT_MODULES" | sed 's/ /|/g')  
REGEX="^($PATTERN_BODY)"

# mypyを実行し、エラー出力をキャプチャ  
# 終了コードは無視するために || true をつける  
ERRORS=$(mypy --show-traceback --show-error-codes --strict $STRICT_MODULES 2>&1 || true)

# 対象モジュールに関するエラーのみを抽出  
FILTERED_ERRORS=$(echo "$ERRORS" | grep -E "$REGEX" || true)

if [ -n "$FILTERED_ERRORS" ]; then  
    echo "$FILTERED_ERRORS"  
    echo "Found strict type errors in target modules."  
    exit 1  
else  
    echo "Success: No strict type errors found in target modules."  
fi

AI は銀の弾丸になったか?

2.8万件の修正をすべて手動で行うのは苦行です。
そこで、2025年らしく Coding Agent の活用を試みました。

プロンプトエンジニアリングの試行錯誤

mypy の実行と修正を自律的に繰り返してもらうため、プロンプトを継ぎ足していった結果、以下のようなプロンプト*1になりました。

mypy --strict . head -n 40 を実行し、エラーを修正して。  
変更は必要最低限に抑えて。  
原則として Any や 'TypeName' のような文字列での型付けは使わないで。  
ただし **kwargs は基本的に Any で良い。  
ignore は絶対に使わず、必要と思うなら許可を取って。  
型ヒントが必要ない箇所にはつけないで。  
@contextmanager, @asynccontextmanager がついているメソッドの返り値にはそれぞれ Iterator, AsyncIterator を使うと良い。  
np.ndarray は使わず、npt.NDArray[np.float64] などを使って。
(npt は import numpy.typing as npt)

(以下、NeoDM特有の型に関する説明が続く...)

結果と学び

結論から言うと、AI だけでの全自動修正は難しく、人手による修正が不可欠 でした。

  • 見直しの必要性: 深いドメイン知識がないと正しい型付けが難しい箇所もあり、AI が間違えることもある*2ため、結局すべて見直す必要がありました。それなら初めから人手 + Copilot などの自動補完で十分でした。
  • リファクタリングの判断: 適切に型をつけるにはコード構造の見直しが必要な場面もあり、その判断はケースバイケースになるため、AI に任せるのは難しかったです。
  • コーディング以外の対応: 場合によっては、対象のコードに詳しい開発者に仕様を確認する必要があり、コーディングだけでは済まない部分もありました。

初めのうちは Coding Agent に頼ってみたのですが、途中から人手で修正する割合が増えていきました。 ただ、AI 未だに猛スピードで進化しているので、半年後には100%任せられるようになっているかもしれません...

AI によるレビュー支援

修正作業と並んで大変だったのがレビューです。
ほとんどの変更は型ヒントの追加や簡単な修正であり、その正しさは mypy によってチェックできますが、リファクタした箇所はバグを埋め込んでしまうリスクがあります。
そのためレビューは必須ですが、内容を一つ一つ確認するのはなかなか骨が折れます。

初めのうちは人手でレビューしていたのですが、途中からレビューにも AI を導入しました。
具体的には Pull Request の差分を AI に渡し *3、問題がありそうな箇所を指摘してもらうようにしました。

工夫した点: 複数回レビューさせる
LLM は確率的に回答するため、同じ内容でも何度かレビューさせることで、1回目では見逃されたバグを検出できることがありました。

実際に AI の指摘によりバグを発見できたケースもあり、レビューの品質向上と効率化に大きく貢献しました。

成果とまとめ

数ヶ月にわたってスキマ時間にコツコツ修正を重ね、ついに NeoDM 全体で strict モードが通るようになりました。 気持ち良いですね!

> mypy --strict .
Success: no issues found in 974 source files

取り組みの成果:

  1. 安全性の向上: None チェック漏れなどの単純なバグは CI で確実に弾けるようになりました。
  2. 潜在バグの発見: 修正プロセスの中で、今まで顕在化していなかったバグをいくつか修正できました。
  3. コード品質の指標: 「型が書きにくいコードは設計が悪い」という指標になり、リファクタリングのきっかけが生まれやすくなりました。
  4. AIフレンドリーなコードへ: 型情報が充実したことで、今後の開発で Coding Agent がより正確にコードを理解・修正できるようになると期待しています。

型ヒントを厳密に書くことは一見手間にも思えますが、バグ調査の時間削減や、将来的な開発効率を考えれば、十分にお釣りがくる投資だと感じています。

さいごに

今回は、Python プロジェクト NeoDM の型安全性を高めるための取り組みについて紹介しました。

GROOVE Xでは、一緒に働く仲間を募集しています!
少しでも興味を持ってくださいましたら、下記のリンクをご覧ください。

recruit.jobcan.jp

*1:残念ながら、特に有用なプロンプトではないと思います。これくらい練ってみたがさほど上手くいかなかった、という記録です。

*2:既存のコードに誤った型が付いており、それに引きずられて AI が間違えるというケースもありました。

*3:細かい話ですが、レビューには主に Claude Code 等の Coding Agent ではなく、Gemini の Web App を使いました。 変更量が膨大な PR を従量課金の AI に見てもらうのが怖かったからです。

レビュアーとAIの間に「伝書鳩」が生まれたので、PRレビューをやめた

(GROOVE X Advent Calendar 2025 2日目の記事です)

こんにちは!ふるまいチームのエンジニア、市川です!

今回はふるまいチームにおける『レビュアーとAIの間に「伝書鳩」が生まれたので、プルリクエスト(PR)のレビューをやめた』というお話です。

『レビューをやめた』と言っても、もちろん品質チェックを放棄したわけではありません。 従来のような「指摘して直してもらうのを待つ」という"待ちのレビュー"を見直したのです。

Coding Agentが産んだ悲しき「伝書鳩」問題

私たちのチームでは、家族型ロボット『LOVOT』の「ふるまい(意思決定や動き)」を作っています。 ここには、大きく分けて2つの役割を持つメンバーがいます。

エンジニアとビヘイビアデザイナー

かつては、エンジニアがふるまいの骨組みを作り、ビヘイビアデザイナーがその中の「アニメーション」の部分を実装する、といった分業が主流でした。 しかし、GitHub CopilotやCursor、Claude Code、DevinといったCoding Agentの登場・進化により、状況は一変しました。

今や、ビヘイビアデザイナーがガッツリとアニメーション以外の実装までも行うようになっています。 AIがコーディングをサポートしてくれるおかげで、彼らのエンジニアリング能力が底上げされたからです。これは素晴らしいことです。

とは言え、「クオリティの壁」があります。

AIが書いたコードは動きますが、プロダクトとしてリリースできる品質(保守性や堅牢性)には達していないことが多い。 そこでエンジニアがレビューをするのですが、これまでのフローはこんな感じでした。

  1. ビヘイビアデザイナーがCoding Agentとコードを書き、プルリクエスト(PR)を出す
  2. エンジニアがPR上で「ここはこう直して」とレビュー
  3. ビヘイビアデザイナーがそのコメントを読み解き、Coding Agentにプロンプトとして入力
  4. Coding Agentが修正し、ビヘイビアデザイナーがpush
  5. エンジニアが再確認...(以下ループ)

気づいてしまったんです。

「これ、ビヘイビアデザイナーがエンジニアとAIの間の『伝書鳩』になってないか?」と。

ビヘイビアデザイナー伝書鳩問題

エンジニアは、ビヘイビアデザイナーに伝わるように噛み砕いて説明しないといけない。 ビヘイビアデザイナーは、それを正しく解釈してAIに指示しないといけない。 もどかしい。なんだこれ。

そんな時、私たちはDevinを本格導入することにしました。

GitHubのPRが「3人の共同開発会場」に変わった日

当時のDevinが他のAgentと決定的に違っていた点。それは、「GitHubのPR上のコメントを直接読んで、勝手に直してくれる」ことです1

これを使えば、エンジニアのレビューコメントをDevinが直接読み取り、修正コミットを積んでくれるはず。 実際にやってみました。

結果は、革命的でした。

エンジニアがPRに「Devin、もっとシンプルな実装にしたい。xxxでどうですか?」と書く。 するとDevinが「了解しました、修正します」と動き出し、コードを直す。 ビヘイビアデザイナーも「ここに○○を追加してください」とコメントする。 Devinが「承知しました」と対応する。

伝書鳩が消えました

今まで「ビヘイビアデザイナー vs AI」の1対1だった関係が、「ビヘイビアデザイナー + エンジニア vs AI」の多対1になれたのです。

GitHubのPRという場所が、単なるコード置き場から、職種の違う人間とAIが膝を突き合わせて議論しながら作る「共同開発会場」に進化した瞬間でした。 それぞれが自分の得意な領域(ビヘイビアデザイナーは体験、エンジニアはコード品質)から指示を出し、AIが手を動かす。しかも指示は非同期!

「これこそが未来の開発だ!」と興奮しました。

...ただ、失敗もありました。 私達がまだDevinに慣れてなかったり、Devinがふるまい開発に慣れてなかった(知識ベースが不足している)こともあり、PR上のコメント数が100件を超えてしまいました。 「エンジニアとビヘイビアデザイナーのコメントがPRに残るから、お互いどう考えてるかが分かる」なんて事も期待していたのですが、こうなると、もう追いきれません。 しかもDevinは従量課金のため、GitHub Copilotなどの月額固定にできるツールに比べると比較的コストがかかってしまいました。

それでも、この経験から私たちは「ある真実」にたどり着きました。

大切だったのは「仕様書」

Devinでの成功と失敗を経て、私たちは開発マニュアルを作成しました。 「Devinをどう使うか」をまとめようとしたのですが、整理する内に「効率を上げるための鍵」はそこではない事に気づきました。

「ビヘイビアデザイナーの承認なしに、エンジニアがガシガシ修正を入れる」

これこそが、開発効率を爆上げする鍵だったのです。

なぜ今まで、エンジニアはビヘイビアデザイナーのコードを勝手に直さず、レビューコメントで指示出し(ビヘイビアデザイナーを伝書鳩化)していたのか? それは、「勝手に直して、ビヘイビアデザイナーが意図した動きを壊したら申し訳ない」と遠慮していたからです。

しかし、Devinを使った時はそれが気にならなかった。 なぜか? Devinに作業させる際、ビヘイビアデザイナーが最初に「仕様書(あるいは要件定義書)」をきっちり書いて渡していたからです。

これがあるおかげで、エンジニアは「この仕様書通りなら、コードはこうあるべきだよね」と確信を持って指摘・修正ができました2

結果論ですが、「仕様書という正解」が真ん中にあるなら、エンジニアが直接手を下してもトラブルにならない。 むしろ、ビヘイビアデザイナーからすれば「期待した通りに動くなら、中身のコードはエンジニアが勝手に高品質にしてくれた方が嬉しい」のです。

つまり、Devinのような自律型AIがいなくても3、以下のフローさえ組めれば「伝書鳩」は消えます。

  1. ビヘイビアデザイナーがCoding Agentに読ませるための「仕様書」を書く
  2. ビヘイビアデザイナーが任意のCoding Agentを活用して実装し、動作確認してからPRを作成する(PRには仕様書も含める)
  3. エンジニアがCoding Agentを活用して、仕様書を軸にリファクタリングする
  4. ビヘイビアデザイナーが動作を最終確認する(問題があれば修正して3.に戻る)

仕様書を軸にした共同開発

結果、エンジニアはビヘイビアデザイナーを通さずに、仕様から外れない範囲で直接コードを修正・リファクタリングできる。

Devinは「PR上でコメントを拾う」という機能でこの体験をさせてくれましたが、本質はその機能ではなく、「共通の仕様書を軸に、エンジニアが遠慮なく介入するルール」にありました。 このような開発スタイルは業界によっては当たり前かもしれないですが、僕らには新鮮でした。

「仕様書を軸にリファクタリングする」は、以前だとエンジニアが仕様を把握するのが大変で、言うほど簡単ではなかったと思います。 Coding Agentがある今は「仕様書を要約させること」も「仕様書を軸にコード修正させること」も容易にでき、今の時代だからこそやりやすい共同開発スタイルなのかもしれないです。

まとめ

ビヘイビアデザイナーの「伝書鳩問題」を「仕様書を軸に直接介入で解決した」というお話でした。これはビヘイビアデザイナーに限った話ではないかもしれないです。 今の時代、「レビュワーとAIの間の伝書鳩になる」という問題はエンジニアにも起こりそうです。

もしレビュワーに「仕様書を軸にした直接のリファクタリング」を委託できるのであれば、そうすることで効率が上がるかもしれないです。


そんなAIでの開発スタイルを模索している僕らと、一緒にお仕事してみませんか? 是非、下記募集をご確認ください。

recruit.jobcan.jp


  1. 現在はDevin以外のCoding Agentでも可能です。
  2. より正確に言うと、「仕様書を軸にDevinが修正してくれるから心理的安全性が高い」という点が大きかったです。
  3. しかし、DevinのようなPR上のコメントを拾ってくれるAgentの方が、ビヘイビアデザイナーとエンジニアが非同期で指示し、コードを同期しやすいというメリットはあります。