BLOG.HIRO UENO.ART
← index
2026.01.06

Typewriter — 代筆屋をつくる

このプロジェクトで、コーディングしてくれているClaude Code(以降Code)と最初に作ったアプリは、Typewriterという名前の、代筆AIエージェントアプリ。 名前の通り、僕の代わりにX(旧Twitter)投稿などの文章を書く役割。

ただ、ここで言う「文章を書く」はXの投稿だけの話じゃない。Slack、メール、Discord。仕事の返信もブログの投稿も、全部ひっくるめて僕の代わりに書くイメージ。相手のメッセージを読んで、文脈を理解して、僕の文体で返す。さらに「この件はタスクとして登録した方がいい」と判断したら、別のタスク管理アプリ(Handler)に情報を渡す。そこまでやって初めて「代筆屋」と呼べる。いきなり全部は作れないから、まずはXの投稿から。

なんでそんな大げさなものを最初に作ったのか。理由は単純で、すぐに効果が見えるから。メモリシステムとかタスク管理は重要だけど、作っても地味。Typewriterなら、Xを開けば結果が目に見える。5年放置してたアカウントに投稿が並ぶ。それだけでモチベーションが全然違うかなと。作る順番は、正しさより続けられるかで決めた。


で、ここが大事なんだけど、単にX投稿だけだったら実はエージェントなんか要らない。

テンプレート作って、テキスト入力して、APIで投稿。普通のWebアプリで十分。決まった入力から決まった出力を作るだけなら、途中に判断が無い。判断が無いなら、わざわざAIをアプリの中に入れる理由も無い。

でも僕が作りたいのは、複数のデータソースから情報を拾ってきて、文脈を判断して、適切な文章を生成して、場合によっては他のアプリと連携する、そういう複合的なことをやるアプリ。Slackに来たメッセージを見て「これは急ぎだからHandlerにタスク登録して、返信は丁寧めに」みたいな判断を自律的にやってほしい。

**そういう判断を自分でやるためには、中にエージェントがいないと成立しない。**だから Claude Agent SDK(以降Agent SDK)を使うことにした。Anthropic公式のエージェント構築フレームワークで、「考えて→実行して→結果を見て→また考える」のループを自動で回してくれる。ここに行き着くまでに、素のAnthropic APIとSDKの間で構成を何度も行ったり来たりしたんだけど。


システムの全体構成はこうなってる。

中央にClaude(Anthropic API)がMONET(オーケストレーター=中心に立って他のエージェントの指揮をする役)として座ってる。僕との全会話を担当する「頭脳」。1時間のキャッシュが効くから、長い会話でも文脈を保持できる。

その下にTypewriterがぶら下がる。間を繋ぐのはMCP(Model Context Protocol)という、AIと外部のツールやアプリを繋ぐための標準プロトコル。MONETが「Typewriter、下書き作って」と指示を出すと、MCPを通じてTypewriterに届く。Typewriterの中にもClaudeがいて(こっちはAgent SDK)、指示を解釈して自分で考えて実行する。

僕 ←→ MONET(Anthropic API / 頭脳)
              ↓ MCP
        Typewriter(Agent SDK / 代筆屋)

MONETの中にClaude、Typewriterの中にもClaude。Claudeの中にClaudeがいる、みたいな構成。MONETは司令塔。Typewriterは実行部隊。それぞれに頭脳があって、それぞれが考える。そういう設計。


MVP(Minimum Viable Product=実用最小限の製品)は意外とすんなりできた。

Mac環境に開発を移してから最初に着手したアプリで、React(フロントエンド)とPython(バックエンド)で画面を作って、X APIを繋いで、Agent SDKでClaudeを組み込む。Codeに指示を出しながら進めて、それなりに短期間で動くものができた。

TypewriterのUIにはAgent SDKのClaudeと話せるチャット画面があって、そこで「この話題で投稿を書いて」と頼むと下書きが出てくる。修正して、投稿ボタンを押す。Xに投稿される。5年放置してたアカウントに、新しい投稿が並ぶ(テストだからすぐ消したけど)。素直にうれしかった。

あとはMCP連携だけ。MONETからTypewriterを直接呼べるようになれば、僕はMONETと会話するだけで、裏でTypewriterが動いて投稿まで全部やってくれる。窓口が一つになる。


でも、ここからが長かった。

MCP連携。技術的には「MCPサーバーを立てて、MCPクライアントで接続する」だけの話・・・のはずが、これが動かない。SDK内蔵のMCPのバグから始まって、Codeと直しても直しても、次の壊れている箇所が出てくる。通信自体は通ってるのに、その先の連携がことごとくおかしい。一個直すと次のが出てくる。デバッグしてもデバッグしても、新しい問題が湧いてくる。

結局、MCP連携が安定して動くまで、MVPから約2週間かかった。1日1、2時間の作業とはいえ、Code曰くコードの量で言えば大した変更じゃないらしい。それに仕事しながらの作業で2週間かかった。

でもこの2週間は削れなかった。MONETからTypewriterを呼べないと、「AIがAIに指示を出す」というこのシステムの根幹が成立しない。通信が不安定なままでは何も始まらない。ここを飛ばして先の機能を作っても、土台が無い。

「Typewriterで下書きを作って」と言うと、MONETがMCP経由でTypewriterに指示を出して、Typewriterが下書きを作って、結果が返ってくる。やっと通った。


同時期に、もう一つ大きな発見があった。Agent Skills(エージェント・スキルズ)。当時出たばかりの機能で、文体やルールをシステムプロンプトに常駐させるんじゃなくて、ファイルとして定義しておいて、必要な時だけAIに装備させられる仕組み。

これを使って hiro-writing-style というスキルを作った。僕の文体ルール。語尾のパターン、文章の流れ、絶対に使わない表現を定義して、Typewriterに装備させる。

すると、それまで「なんか違う」と思ってた文章が、ちょっとだけ僕っぽくなる。まだ全然足りないけど、方向性は見えた。フィードバックを繰り返せば精度は上がるはず。


こうしてTypewriterは「MVPが動く」から「MCP連携が通って、Skillsを装備したエージェントアプリ」になった。MONETに話しかければ、裏でTypewriterが動いて、下書きが返ってくる。窓口は一つになった。

構想からここまで、だいたい2〜3週間。長いのか短いのかよくわからない。エンジニアじゃない人間がCodeと一緒に、エージェント同士の通信基盤を作って、Skillsまで実装した。まあ悪くない進捗なんじゃないかな。