koboriakira.com

五つの並行世界

2026/02/24

久々の更新となった。これには少しだけ理由がある。シンプルに開発にハマっていたらからだ。通常の仕事をしながらも、隣のプライベートPCで生成AIがいろいろと実装を進めている。その記録もあるので、要約してみよう。

繰り返し言うが、これが今日1日の仕事ではない 今日1日の仕事を回している最中にやったことである。すでに私の中ではこれぐらいのパフォーマンスは当たり前というか、やろうと思えばできるレベルになってきた。これがエンジニアにおける一般的なものなのかどうかはわからないが、少なくとも2,3年後には最低限のスキルやアウトプット量になるだろう。


もじずかん

子ども向けのひらがな学習iOSアプリ。この日だけで12セッション回した。

まず文字認識エンジンをApple純正のVision FrameworkからGoogle ML Kit Digital Ink Recognitionに移行した。Vision Frameworkは印刷テキスト向けのOCRで、手書きのストロークを認識するにはML Kitのほうが適している。CocoaPodsでの導入にあたってXcode 16固有の問題をいくつか解決し、arm64シミュレータ非対応のためデバイスターゲットでビルドを確認した。

次にひらがなフィルタリング。OCR結果から数字や記号を除外し、ひらがなだけを抽出するfirstHiragana(in:)メソッドを実装。TDDで4テスト追加。

プリセット辞書を追加した。どうぶつ、たべもの、のりもの、しぜんの4カテゴリ、約22語。完成時に絵文字と説明文を表示し、未登録時にはガイダンスを出す。

図鑑画面をグリッド表示と詳細画面の2階層で実装した。ZukanDataStoreを@Observableで作り、登録済みの単語は絵文字とwordを表示、未登録は「?」でロック表示。SwiftDataでデータ永続化し、ZukanEntryモデルにword、category、registeredAtを持たせた。

音声読み上げ機能。AVSpeechSynthesizerで日本語(ja-JP)、速度0.4。説明文タップで読み上げ、再タップで停止。SpeechManagerを@Observableで状態管理。途中でModelContainer周りのクラッシュが発生し、アプリプロパティ化して修正。

サジェスト機能のトグルを追加。デフォルトOFF。AppSettingsを@Observable + UserDefaultsで新規作成し、DebugViewにトグルを配置。

演出とポリッシュでMVP完成。AppThemeを定義して暖色系クリーム、ダークブラウンテキスト、オレンジアクセントの配色を統一。カテゴリアイコン追加、図鑑登録時のSpring/フェードアニメーション、タイトル画面の改善。

Phase 2として「はっけん!」機能を実装した。プリセットにない自由な単語を登録できる仕組み。WordValidator、ImageGenerator、DescriptionGeneratorの3つのProtocolを設計し、OpenAI APIで2段階バリデーション(プリセット辞書照合 → 生成AI判定)を入れた。ZukanViewに「はっけん!⭐」セクションを追加。

効果音とBGMも入れた。SE 7種、BGMはGood_morning.mp3を音量0.15でループ再生、音声読み上げ中はダッキング。

そのほか、説明文の動的生成(Chat Completions API)、画像生成API連携、入力サジェスト(前方一致)、未登録シルエット表示、コンプリート演出、カタカナ対応(Unicode 0x60差分変換)まで。SwiftDataのスキーマ変更でクラッシュが出たため、try-catchで既存ストアを削除・再作成するフォールバックも入れた。

TestFlightへのデプロイはビルド12から始まり、最終的にビルド22まで上がった。

なぞり書きモードも追加。既存のWordInputViewに「おてほん」ボタンを配置し、50音から文字を選ぶとキャンバス上にシステムフォントのガイドが薄く表示される。なぞり完了の精度判定はせず、おてほんモードでは選択文字をそのまま確定とした。

マイルストーン肩書き表示も実装。ZukanDataStoreにcurrentTitleプロパティを追加し、登録数に応じた肩書き(10件/20件/50件/100件の4段階)をZukanView最上部に黄色バナーで表示。

図鑑の登録日表示と登録履歴。ZukanDetailViewに「YYYY/M/d に かいたよ」形式で登録日を表示。AppSettingsに子どもの生年月を追加し、ChildAge構造体で年齢計算。保護者メニューに登録履歴画面を新設し、「3歳8ヶ月」のような年齢表示に対応。

シェア機能。保護者メニューからエントリを複数選択し、タイトルを入力するとカード風レイアウトのシェア画像を生成。ViewRendererでSwiftUI ViewをUIImageにレンダリングし、UIActivityViewControllerでiOSのシェアシートを呼ぶ。

Issue整理として、#23(書き順ガイド)、#26(図鑑登録日)、#27(肩書き)、#30(シェア)をクローズ。フィードバック機能の調査を行い、Google Forms + SFSafariViewControllerを推奨案としてIssue #33を起票した。


cloud-sourcing

ココナラ案件の自動スキャン・提案パッケージ生成の仕組み。

日次調査パイプラインを実行。80件スキャン → 7件フィルタ → 1件選別通過。通過した案件4857652(Googleスプレッドシート集計・可視化、予算5-10K)に対して、5フェーズ自動実行(スキャン → 選別 → テック査定 → 提案チーム → 最終報告)で提案パッケージを生成した。テック査定はGO(条件付き)。提案チーム5人分の出力を生成し、評価スコアは信頼感8 / 専門性8 / 共感度7。

提案テンプレートも改善した。見積り内訳の設計ルール(価格帯別の粒度調整)を追加し、質問設計を「信頼感表示」から「作業開始スムーズ化」へ目的転換。

GAS試合分析アプリの案件4840415に対しては、ストラテジーの再分析とブループリント作成を行った。応募者15名で契約0名が1週間続いている理由を4仮説で深掘りし、price_breakdownを新設。strategy.jsonに3カテゴリの見積り内訳と4件のオプションを定義。ブループリントではコード例を改善し、二重送信防止やローディングインジケータを追加。

同案件の提案パッケージを再生成。5チーム体制のAgent Teamsで、前回(2/23)のスコア7.7から8.3に向上。改善点は5項目:能動的姿勢(期限付きコミット)、信頼感(技術アーキテクチャの具体性)、価格の明確化(幅提示から一点提示へ)、デバイス確認の追加、質問の効率化(3問から2問へ)。

ココナラの入力欄がプレーンテキストのみ対応であることがわかったため、proposal.mdに「ココナラ投稿用(プレーンテキスト)」セクションを追加。

提案テンプレートに「準備シグナル」の設計を組み込んだ。依頼者に「準備の深さ」を伝えるための5つのシグナル(S1: 課題の再定義、S2: 完成後の体験描写、S3: 初手のコミット、S4: 制約の開示と対策、S5: ドメイン語彙)を定義し、依頼者タイプに応じて優先シグナルを変える。

cron実行のPATH問題も修正。daily-scanがexit=127で失敗していた原因は、cron環境で$HOME/.local/binがPATHに含まれないこと。スクリプト冒頭にexport文を追加して解決。


personal-agent

Slackの活動を自動分析してObsidianに書き出すエージェントサーバー。この日に新規立ち上げ。

まずプロジェクト初期化。pyproject.toml、ディレクトリ構成、Protocol定義を作成。SlackMessageとActivitySummaryのdataclass、5つのProtocol(collector、repository 3種、analyzer)を定義した。

CLAUDE.mdを仕様書から最小化して作成。将来のClaudeインスタンスがスムーズに開発に入れるよう、技術スタック、コマンド、アーキテクチャの要点をまとめた。

GitHub Issueを13件起票。Wave 0(Protocol定義)→ Wave 1(最大9並列)→ Wave 2(実DB)→ Wave 3(統合)の構成で、依存関係グラフ付きで並行開発を最大化する設計。5つのカスタムラベルも作成。

CLI main.pyを実装。argparseベースのサブコマンド(serve / collect / summary / status / mcp)、FastAPI + CollectorScheduler起動、SIGINT/SIGTERM対応。テスト7件追加。

Issue #2から#12までを6ステップで全実装。Database接続・マイグレーション → SlackMessageRepo/SummaryRepo → SlackCollector/REST API/ActivityAnalyzer(3エージェント並列) → CollectorScheduler(APScheduler) → CLI/Summaries API/MCPサーバー(3エージェント並列) → launchd + README。

実装の中で、Claude CLIバックエンド対応(CLAUDE_BACKEND=cli|api切り替え)、Slack search.messages API移行(API呼び出し数をN → 2に削減)、タイムゾーン不一致修正(UTC → JST、既存3993件を一括変換)、dailyサマリー自動生成(毎日22:00)、Obsidian dailynote連携(自動書き出し、既存ノート検出・置換対応)を行った。

最終結果は128テスト全パス、lint/format/mypy全クリア、17コミット。


sandpiper

MCPサーバー(タスク管理)のツール名リネーム。CRUDベースから目的ベースの命名に変更した。

  • create_todoschedule_task
  • create_next_todointerrupt_with_task
  • start_todobegin_task
  • complete_todofinish_task
  • create_project_taskadd_task_to_project
  • create_someday_itemdefer_to_someday

読み取り系7ツールはツール名を維持し、docstringを強化。全docstringに使い分け判断基準と相互参照を追加した。テスト22件全パス。

差し込みタスクツールcreate_next_todo(後にinterrupt_with_taskにリネーム)も新設。ToDoKind.INTERRUPTIONを設定し、現在時刻からセクションと並び順を自動決定。テスト2件追加。


そのほか

Claude Codeとの対話効率を改善した。選択肢を番号付きの箇条書きで提示し、数字だけで回答できるルールを全プロジェクト共通のCLAUDE.mdに追加した。

Obsidian

K

Kobori Akira

IT業界の社会人。最近はプロレスと音楽の話題が多め。
読む価値のある記事は Qiitanote に投稿します。
過去人気だったブログ記事はこちらから。