最終更新:

全720件

🟠
Hacker News

たった1つの演算子からsin・log・πまで全部作れる?数学の「NAND」を発見した論文が話題

ブール代数のNANDに相当する「連続数学の万能演算子」が初めて発見されたという、教科書を書き換えかねない話。数学・CS・ML全部に刺さる珠玉の論文で、シンボリック回帰に興味がある方は必読です。

「すべてのブール論理はNANDゲート1つで実装できる」——デジタル回路を学んだことがあれば、この事実に衝撃を受けた記憶があるだろう。では、連続数学(実数の計算)にも同様の「万能プリミティブ」は存在するのか? 長らく「そんなものはないだろう」と思われてきたこの問いに、ポーランドの研究者Andrzej Odrzywoułekが2026年3月に驚くべき答えを提示した。 発見された演算子「eml」とは何か 論文のタイトルは All elementary functions from a single binary operator(単一の二項演算子からすべての初等関数を導く)。提案された演算子はこれだけだ: ` eml(x, y) = exp(x) - ln(y) ` つまり「xの指数関数」から「yの自然対数」を引いた値。シンプルすぎて拍子抜けするかもしれないが、この eml と定数 1 だけを組み合わせることで、sin・cos・sqrt・log・加減乗除・累乗・πやeやiといった定数まで、科学電卓が持つすべての機能を構成できることが示された。 いくつか具体例を見てみよう: ` expはそのまま exp(x) = eml(x, 1) lnは3段ネスト ln(x) = eml(1, eml(eml(1, x), 1)) 他のすべての初等関数もemlのネストで表現可能 ` 文法として書くと、これ以上ないほどシンプルになる: ` S -> 1 | eml(S, S) ` なぜこれが「驚き」なのか ブール代数では、NANDが万能ゲートであることは19世紀末から知られていた。しかし連続数学の世界では、加算・乗算・三角関数・対数はそれぞれ本質的に異なる操作として扱われてきた。「1つの演算子で全部カバーできる」という発想すら、真剣に検討されたことがなかったに等しい。 Odrzywoułekがこの演算子を見つけたのは、直感ではなく<strong>網羅的な探索(exhaustive search)</strong>によるものだという点も興味深い。「こういう構造があるはず」と理論から導いたのではなく、実際に全パターンを調べてたまたま存在を確認した——という発見のプロセスが、この結果の予想外さを物語っている。 - これまで「連続数学の万能プリミティブ」は知られていなかった - EML演算子の存在は予測されておらず、網羅探索で発見された - すべての表現が <strong>同一ノードの二分木(binary tree)</strong> になる均一構造を持つ シンボリック回帰への応用:数値データから数式を復元する この研究が単なる数学的好奇心に留まらないのは、機械学習への応用可能性があるからだ。 EMLの均一な木構造を「trainableな回路」として扱い、Adamオプティマイザで勾配降下を行うと、<strong>数値データから元の閉形式(closed-form)の数式を逆算できる</strong>可能性が示されている。これはシンボリック回帰(symbolic regression)と呼ばれる分野で、例えば物理実験のデータから「背後にある数式」を自動発見するタスクに使える。 論文では、木の深さ4以下という浅い構造で、初等関数の正確な復元が実証されている。データを生成した法則が初等関数であれば、ノイズがあっても正確な数式を回収できる可能性があるという。 `python イメージ(疑似コード) 数値データ (x, y) から eml ツリーを学習 model = EMLTree(depth=4) model.fit(x_data, y_data, optimizer='adam') print(model.to_formula()) # "exp(x)" や "ln(x+1)" などが返ってくるイメージ ` コードはarXivの補足情報として公開されており、論文ページから参照できる。 まとめ:数学の「基底」が書き換わるかもしれない この発見が持つ意味は、純粋数学・計算機科学・機械学習の3領域にまたがる。 - 純粋数学的視点:初等関数の代数的構造についての新しい洞察 - 計算機科学的視点:すべての数値計算を単一命令セットで記述できる可能性 - 機械学習的視点:シンボリック回帰の新しいアーキテクチャ基盤 個人的に特に面白いと思うのは、「複雑に見える数学の道具立て(sin・cos・log・π・i…)が、実はたった1つのシンプルなルールから生えてくる」という構造的な美しさだ。NANDがデジタル回路の「原子」であるように、eml(x,y) = exp(x) - ln(y) が連続数学の「原子」になりうる——そういうパラダイムシフトの匂いがする論文だ。 査読前のプレプリント(arXiv)段階であり、今後の検証が必要ではあるが、HNで285ポイントを集めたことからも研究コミュニティの関心の高さが伺える。元論文はarXivで無料公開されているので、数式やコードの詳細が気になる方はぜひ読んでみてほしい。

📝
Qiita

『アジャイルサムライ』で学ぶユーザーストーリーの書き方——なぜ重厚な仕様書はプロジェクトを壊すのか

「ユーザーストーリー 書き方」で検索するエンジニアにとって、名著の要点をリアルな現場感覚で整理した良記事。仕様書文化から脱却したいチームのインプットにぴったり。

アジャイル開発を学び始めたとき、「ユーザーストーリーって結局なんなの?」と思った人は多いはず。仕様書やWBSとは何が違うのか、どう書けばいいのか——その疑問に正面から答えてくれる名著が『アジャイルサムライ――達人開発者への道』だ。Qiitaに投稿された読書感想文シリーズ第3弾を題材に、この本の核心をエンジニア視点で深掘りしてみたい。 なぜ「重厚な文書化」はうまくいかないのか 本書がまず叩き台にするのは、ウォーターフォール型プロジェクトの根本的な矛盾だ。要求定義フェーズで数百ページの仕様書を作ったとしても、「顧客は自分たちの欲しいものを手に入れることはほとんどなく、開発チームは求められたものを構築しきれない」(p.101)。 これは耳が痛い話だ。現場で経験したことのあるエンジニアなら必ず頷くはずで、文書化そのものが悪いのではなく、変化への対応を前提としていない文書化が問題なのだと著者は指摘する。要求は時間とともに変わる。プロジェクト開始時点の「完璧な仕様書」は、リリースの頃には陳腐化している。 ユーザーストーリーとは何か——インデックスカードの哲学 そこで登場するのがユーザーストーリーだ。本書の定義はシンプルで明快:「顧客がソフトウェアで実現したいと思っているフィーチャーを簡潔に記述したもの」(p.105)。 重要なのは「インデックスカードに書く」という物理的な制約だ。小さなカードには長文を書けない——これは意図的な設計で、詳細を書かないことで顧客との会話を促す仕掛けになっている。キーワードだけ残しておいて、あとで顧客に確認する。なぜそこまで詳細を詰めないかといえば、「フィーチャを思いついたばかりの時点では、それが本当に必要になるかどうかはまだわからないから」(p.105)というシンプルな理由だ。 実際の書き方としては以下のフォーマットがよく使われる: ` [ユーザーの種類] として、 [何かをしたい]。 なぜなら [ビジネス上の価値] があるから。 ` 例えば「登録ユーザーとして、マイページから注文履歴を確認したい。なぜなら再購入の手間を省きたい<strong>から。」のように書く。開発者視点ではなく、</strong>ユーザーの目的とビジネス価値を軸に置くのがポイントだ。 「開発者がストーリーを書いていい」という解放感 アジャイル開発の現場でよくある誤解が「ユーザーストーリーは顧客が書くもの」という思い込みだ。確かに本来はそうあるべきだが、本書は「現実には、ほとんどのストーリーは君が書くことになるだろう」(p.113)とはっきり言い切る。 これは非常に実践的な視点で、開発者がストーリーを書いて顧客にレビューしてもらうというアプローチを肯定している。大事なのは誰が書いたかではなく、顧客との対話を通じてストーリーが正しく育てられているかどうかだ。 まとめ——アジャイルの本質は「対話の設計」にある 『アジャイルサムライ』の第3部が伝えるメッセージは、アジャイル開発とは単なる「短いイテレーションの繰り返し」ではなく、顧客との継続的な対話を仕組みとして設計することだということだ。ユーザーストーリーはそのための道具であり、あえて情報を削ぎ落とすことで会話を生み出す。 スクラムやカンバンを導入していても「なんとなくアジャイルっぽくやってる」という状態から抜け出したいエンジニアに、この本は強くおすすめできる。2011年出版ながら本質は色褪せない。Qiitaの読書感想文シリーズは第1部・第2部も公開されているので、通しで読むと理解が深まるはずだ。

🟠
Hacker News

AIスクレイパーを無限ループに閉じ込める「Miasma」— Rustで作られたクローラー対策ツールの仕組みと導入方法

robots.txtを無視するAIクローラーへの「毒餌罠」という発想が秀逸。NginxとCargoさえあれば30分で導入できる手軽さも含め、自サイトを持つエンジニア全員に刺さる内容だと思い取り上げた。

AIクローラーに自分のサイトを勝手に学習データにされたくない人へ 「うちのサイトの文章がいつの間にかAIの学習データになっている」——そんな状況に憤りを感じているウェブ管理者は少なくないはずだ。robots.txt でブロックしようにも、それを無視するクローラーも存在する。そんな中、Hacker Newsで注目を集めたOSSツール Miasma は、AIスクレイパーを「追い払う」のではなく「罠にはめる」という発想の転換で対抗する。 Miasmaとは何か?仕組みを理解する MiasmaはRustで書かれた超軽量HTTPサーバーだ。動作の仕組みはシンプルかつ巧妙—— - 隠しリンクをサイト内に仕込み、スクレイパーだけが踏む罠を作る - そのリンクはNginx経由でMiasmaサーバーにプロキシされる - MiasmaはAI学習に有害なポイズンデータ<strong>(poison fountainから取得)と、さらにMiasma自身へ戻る</strong>自己参照リンクを複数含むHTMLを返す - スクレイパーはそのリンクを辿り、延々と無意味なデータを取得し続ける無限ループに陥る 人間のユーザーには display: none + aria-hidden="true" で完全に不可視。スクリーンリーダーにも検知されない。スクレイパーだけが踏む仕掛けだ。 インストールと基本セットアップ Cargoが入っていればワンコマンドでインストールできる。 `sh cargo install miasma ` 1. サイトに隠しリンクを埋める `html <a href="/bots" style="display: none;" aria-hidden="true" tabindex="1"> Amazing high quality data here! </a> ` 2. Nginxで /bots をMiasmaにプロキシ `nginx location ~ ^/bots($|/.*)$ { proxy_pass http://localhost:9855; } ` 3. Miasmaを起動 `sh miasma --link-prefix '/bots' -p 9855 -c 50 ` -c 50 はmax同時接続数。50接続時のピークメモリは約50〜60MB。これを超えるリクエストは即座に 429 で弾かれる(キューには入らない)。 4. robots.txtでGooglebotを守る `text User-agent: Googlebot User-agent: Bingbot Disallow: /bots Allow: / ` Google/Bingなど正規のクローラーは罠に誘導しないよう明示的に除外することを忘れずに。 主な設定オプション | オプション | デフォルト | 説明 | |---|---|---| | --port / -p | 9999 | バインドするポート | | --max-in-flight / -c | 500 | 最大同時接続数 | | --link-prefix | / | 自己参照リンクのパスプレフィックス | | --link-count | 5 | レスポンスに含める自己参照リンク数 | | --force-gzip | false | 常時gzip圧縮(通信コスト削減に有効) | 所感——「戦わず、飼いならす」という発想 正直、これはかなり面白いアプローチだと思う。robots.txt や User-Agent ブロックは「来るな」と伝えるだけで、無視されれば終わりだ。一方Miasmaは、来てしまったスクレイパーに対してリソースを浪費させながら有害なデータを食わせる。多大なコンピュータリソースで他人のコンテンツを無断収集するAI企業への、静かでしかし効果的な抵抗だ。 Rust製なのでパフォーマンスも高く、サーバー側のオーバーヘッドはほぼゼロに近い。個人サイトからエンタープライズまで、自分のコンテンツを守りたいすべてのウェブ管理者に試してほしい一本。

🔥
Zenn

Reactのフラグ地獄を完全解消——TypeScript Discriminated Union × 状態遷移テーブルで設計する実践ガイド

「フラグを足すのをやめろ、状態を設計しろ」という本質的なメッセージを、TypeScript の型システムと FSM で実践的に示した良記事。非同期 UI を量産するフロントエンドエンジニア全員に読んでほしい。

「isLoading、isError、hasData……フラグが増えるたびにコードが壊れていく」——Reactを書いていれば誰もが一度は踏んだ落とし穴だ。この記事では、そのフラグ地獄を<strong>有限状態機械(FSM)+テーブル駆動設計</strong>で根本解消する方法を、実動コード付きで解説する。 フラグ管理はなぜ破綻するのか——2のn乗問題 boolean フラグが n 個あると、理論上 2^n 通りの状態組み合わせが生まれる。実際に有効な状態はそのうちほんの数パターンに過ぎないが、コード上は不正な組み合わせを防ぐ仕組みがない。 | フラグ数 | 組み合わせ数 | 有効な状態数 | |---------|------------|------------| | 3個 | 8通り | 3〜4通り | | 5個 | 32通り | 5〜6通り | | 10個 | 1024通り | 10〜15通り | isLoading: true かつ isError: true かつ hasData: true——現実には起こりえない状態がコード上では成立してしまう。さらに問題なのが、フラグを別々の useState で管理する構造だ。fetchUsers を呼び出した際に hasData をリセットし忘れると、再取得中やエラー発生後に古いデータが画面に残り続けるバグが生まれる。 `typescript // Bad: フラグが独立しているため「set忘れ」がバグの温床 const [isLoading, setIsLoading] = useState(false); const [isError, setIsError] = useState(false); const [hasData, setHasData] = useState(false); // fetch開始時にリセットされない! ` 解決策——状態を「ひとつの値」として表現する 根本的な解決策はシンプルだ。状態を「フラグの集合」ではなく <strong>「排他的な1つの値」</strong> として定義する。idle | loading | success | error は同時に複数を取れないため、不正な組み合わせはゼロになる。 これを TypeScript で表現するのが <strong>Discriminated Union(判別可能なユニオン型)</strong>だ。 `typescript // types/async-state.ts export type AsyncState = | { status: "idle" } | { status: "loading" } | { status: "success"; data: User[]; fetchedAt: Date } | { status: "error"; error: Error }; export type AsyncEvent = | { type: "FETCH" } | { type: "RESOLVE"; data: User[] } | { type: "REJECT"; error: Error } | { type: "RETRY" }; ` status フィールドがタグとして機能し、state.status === "success" と絞り込んだ時点で TypeScript が state.data の存在を自動的に保証してくれる。ランタイムエラーではなくコンパイル時にバグを検出できる設計だ。 状態遷移テーブル——設計を「表」から始める 実装の前にまず遷移マトリクスを設計する。行に「現在の状態」、列に「発生するイベント」を置き、セルに「遷移先」を記入する。 | 状態 \ イベント | FETCH | RESOLVE | REJECT | RETRY | |--------------|---------|---------|--------|--------| | idle | loading | — | — | — | | loading | — | success | error | — | | success | loading | — | — | — | | error | — | — | — | loading | この表から読み取れる設計ポイントは3つ: - 不正な遷移は構造的に発生しない(各状態で受け付けるイベントが限定される) - success 状態からの FETCH は再取得を意味する(idle と同じ遷移先) - error 状態からの脱出は RETRY のみ(直接 FETCH には戻れない) この表をそのままコードに写すのがテーブル駆動設計の本質だ。useReducer の switch 文でも実装できるが、状態×イベントのマトリクスを Map や Record で明示的に定義することで、設計と実装の対応が一目瞭然になる。 まとめ——「フラグを足す」前に設計を疑え フラグ地獄は「設計の問題」であり「コーディングスキルの問題」ではない。次のフローで取り組むだけで、コードの健全性は大きく変わる: 1. 遷移マトリクスを紙に書く(状態×イベントの表) 2. Discriminated Union で型定義(状態ごとに持つべきデータを型に乗せる) 3. テーブル駆動で useReducer を実装(switch のネストではなくテーブル参照) 4. UI は state.status だけで分岐(フラグを見ない) 個人的に刺さったのは「不正な状態を表現できない型を設計する」という発想の転換だ。フラグを管理するのではなく、そもそも不正な状態が型として存在できない世界を作る——これは XState や Zod などが掲げる思想とも共鳴する。元記事には動作する GitHub リポジトリも公開されており、Bad/Good 両パターンを手元で比較できる。非同期処理をフラグで管理しているコンポーネントを抱えている方に強くお勧めしたい一記事だ。

🔥
Zenn

ハーネスエンジニアリングとは何か?「Git Workflowのbash再実装」という辛口考察が刺さる件

「ハーネスエンジニアリング」バズの全体像を俯瞰しつつ、「実は新しくない」と喝破する視点が鋭い。Claude Code/Codexを使い始めたエンジニアがレイヤー1止まりになっていないか自己点検するための記事として、今まさに読むべきタイミング。

2026年3月、「ハーネスエンジニアリング<strong>」という言葉がAIエージェント界隈で突然バズった。Anthropic・OpenAI・Martin Fowler・arXiv論文と、各所から一斉に解説記事が出回り、Zennやはてブでも大量の考察が投稿された。そんな中、Zennに「全部読んだ。でもこれ、</strong>Git WorkflowをBashで書き直してるだけじゃないか?」という強烈な一石を投じる記事が登場した。 ハーネスエンジニアリングとは何か?各プレイヤーの主張を整理する まず用語の出所から。命名者は <strong>Mitchell Hashimoto(HashiCorp共同創業者)</strong> で、2026年2月のブログ記事「My AI Adoption Journey」で定義された。 > エージェントがミスを犯すたびに、二度とそのミスが起こらないような仕組みを作ること 各プレイヤーはこれを以下のように解釈している: - Anthropic公式: 長時間エージェントのコンテキスト消失問題 → CLAUDE.mdに状態を書き、hookで品質を担保、MCPで外部ツールを接続せよ - OpenAI公式: 3人のエンジニアがCodexで5ヶ月・100万行・手動コーディング0を達成(タスク並列実行の活用) - <strong>逆瀬川さん(@gyakuse)</strong>: 7原則の体系化(はてブ672users)、Claude Code vs Codex比較表付き - LangChain: ハーネス改良だけでTerminal Bench 2.0スコアが <strong>52.8% → 66.5%(+14%)</strong> に向上 「全部GitHubに既にあるじゃないか」という指摘 記事著者はすべての主張を並べた上で、以下の対応表を示す。 | ハーネスエンジニアリング | GitHub/Git の同等機能 | |---|---| | 破壊的操作の禁止ルール | ブランチ保護ルール | | PreToolUse / PostToolUseフック | GitHub Actions(CI/CD) | | 計画→承認→実行の分離 | PRレビュー + Approve | | linterゲート | ステータスチェック(必須パス) | | CLAUDE.md / AGENTS.md | PRテンプレート / CODEOWNERS | | タスクYAML定義 | GitHub Actionsワークフロー定義 | | セッション間の状態管理 | コミットログ + ブランチ | なぜ「ハーネスエンジニアリング」という新語が必要になったのか?答えはシンプルで、AIエージェントがGitHubのUI経由ではなくターミナルで直接ファイルを書き換えるからだ。人間向けのGitHubワークフローがそのままでは効かない。だからCLI側で同じ仕組みを再実装する必要が生じた、という解釈だ。 3つのレイヤーで整理すると本質が見えてくる 著者はハーネスエンジニアリングを以下の3レイヤーに分類する。 | レイヤー | やること | 難易度 | |---|---|---| | セットアップ | hookを設定、CLAUDE.mdを書く、MCPを繋ぐ | 簡単 | | ワークフロー移植 | Git Workflowと同じ品質ゲートをローカルに再実装 | 中 | | 未踏領域の設計 | マルチエージェント協調、自律復帰、安全装置 | 難 | 「世の中の記事の9割はレイヤー1〜2の話をしている」と著者は言う。LangChainの+14%も「開発環境の設定を最適化したらスコアが上がった」と言い換えれば当たり前の話だ、と。 本当のエンジニアリングはレイヤー3から始まる。著者自身が構築した「将軍システム」(10台のAIエージェントを戦国時代の指揮系統で動かすマルチエージェントシステム、v1.0は2025年11月)では、GitHubに対応物がない問題に直面し続けている: - エージェント間の非同期通信 → inbox_write.sh + YAML Queue を自作 - 応答しないエージェントの復帰 → エスカレーション階層(ナッジ→Escape→/clear) - タスクの認知レベル別ルーティング → Bloom-based QC routing - 殿の命令でも拒否する安全装置 → Tier 1禁止リスト + インジェクション防御 所感:「名前がついたことに価値はある」という着地が誠実 辛口に見えて、著者の結論は意外と建設的だ。「ハーネスエンジニアリング」と名付けられたことで「AIにもプロセス管理をちゃんと入れよう」が議論の俎上に載った——その点は評価している。バイブコーディングから入ったエンジニアにとって、これは本物の気づきになり得る。 一方で「CLAUDE.mdに『テスト書いてね』と書いているだけなら、それはエンジニアリングじゃなくてお願いだ」という一文は、現場で使っている人間には刺さる指摘だろう。まずhookを設定し、ルールを書き、MCPでツールを繋ぐ。それは「セットアップ」。Git Workflowを移植するのは「引っ越し」。本当のエンジニアリングはその先から始まる、という主張はシンプルで明快だ。Claude Codeやcodexを日常的に使い始めたエンジニアが「次のステップ」を考える上で、レイヤー分類の視点は実用的に使えると思う。元記事にはマルチエージェント将軍システムのGitHubリポジトリも公開されているので、レイヤー3の設計例として一読の価値がある。

🟠
Hacker News

世界の公共交通データを可視化するOSS「Public Transit Systems」—— 東京メトロから北京地下鉄まで比較できるターミナル風UIが面白い

ターミナル風UIで世界の鉄道データを横断比較できる、開発者の遊び心が詰まったプロジェクト。オープンデータ活用や地図・交通系アプリに興味あるエンジニアには設計の参考になる一品。

「世界の地下鉄・路面電車のデータを一括で調べたい」「路線数・駅数・延長距離を横断比較したい」——そんな需要に応えるWebサービスが Hacker News に登場した。publictransit.systems は、世界各地の公共交通システムの路線・駅・車両・歴史データを集約したデータベースサイトだ。 ターミナル風UIが開発者心をくすぐる アクセスすると最初に目に飛び込んでくるのが、CLIライクなインターフェース。 ` $ query --list systems Found 9 transit systems in database > Displaying public transit information... ` こういう「エンジニアが趣味で作った感」全開のUIは、技術者として素直に好きだ。実用性と遊び心が両立しており、⌘K でグローバル検索が走るなど操作感も快適に仕上がっている。 現在収録されている9システムのデータ概観 2026年3月時点で収録されているのは以下の9路線: - NYC Subway(ニューヨーク):472駅・25路線・日間利用者360万人。世界最多駅数 - Tokyo Metro(東京):180駅・9路線・日間684万人。年間利用者数は世界最多クラス - Beijing Metro(北京):527駅・28路線・日間1,050万人。2023年に延長距離で上海を抜き世界最長 - CTA(シカゴ):146駅・8路線。名称の「L」は高架鉄道(Elevated)に由来 - WMATA(ワシントンD.C.):98駅・6路線・日間62.6万人 - BART(サンフランシスコ湾岸):50駅・6路線・延長131マイル - Sound Transit(シアトル):50駅・3路線 - Light RailLink / Metro SubwayLink(ボルチモア):2システム収録 グローバル統計として 総駅数1,570・総路線89・総延長1,506マイル がまとめられており、サイドバイサイド比較ツールも用意されている。 技術的に注目すべきポイント Hacker Newsのコメントでも議論されているが、このプロジェクトが面白いのはデータ構造の設計にある。 - <strong>路線(Lines)・駅(Stations)・車両(Railcars)・歴史(History)</strong> を独立したエンティティとして管理 - 比較ツールで複数システムを並列表示できる設計 - APIドキュメントが公開されており、外部からデータ利用が可能 - Next.jsベースのSSR構成(ページソースより確認) データの出典や更新頻度については現時点では詳細が少ないが、「About This Project」ページにコントリビュート方法が記載されており、コミュニティ主導での拡充が期待される。 日本の交通インフラデータ活用の文脈で考える 東京メトロはすでに収録されているが、都営地下鉄・JR・私鉄各社のデータは未収録。日本は交通ICカードのオープンデータ化が進んでおり、国土数値情報(MLIT)や GTFS-JP 形式のデータも公開されている。このプロジェクトにコントリビュートするか、あるいはこのアーキテクチャを参考に国内版を作るのも面白いアイデアだ。 交通データ・オープンデータ・地図可視化に興味があるエンジニアにとって、設計の参考になる良いケーススタディだと思う。まずは比較ツールで東京メトロとNYC Subwayの数字を見比べてみてほしい。

🟠
Hacker News

lat.md とは?AIエージェント向けコードベース知識グラフをMarkdownで構築する新ツール

AGENTS.mdの「単一ファイル地獄」に悩んでいるなら、このアプローチは刺さるはず。AIエージェントに渡す文脈をMarkdownグラフで管理するという発想、地味だが実用性が高い。

AGENTS.md の限界を超える:lat.md が解決する問題 AIコーディングエージェント(CursorやGitHub Copilotなど)に「このプロジェクトの文脈」を伝える方法として、最近 AGENTS.md という単一ファイルに設計方針やルールを書くアプローチが広まっている。しかしこれには致命的なスケール問題がある——コードベースが成長するにつれてファイルが肥大化し、重要な設計判断が埋もれ、AIエージェントはあるべき知識を持てずに幻覚(ハルシネーション)を起こす。 lat.md はその問題に真正面から挑んだツールだ。プロジェクトルートに lat.md/ ディレクトリを作り、相互リンクしたMarkdownファイル群でコードベースの知識グラフを構築する。 技術的な仕組み:ナビゲート可能な知識グラフ lat.md の核心は3つの連携機構にある。 - [[wiki links]] によるセクション間の相互参照([[auth#OAuth Flow]] のような記法) - ソースコードへのバックリンク([[src/auth.ts#validateToken]] で実装箇所を直接参照) - // @lat: [[section-id]] アノテーション:ソースコード側から知識グラフへの逆参照 ディレクトリ構成はこうなる: ` my-project/ ├── lat.md/ │ ├── architecture.md # システム設計・重要な意思決定 │ ├── auth.md # 認証・認可ロジック │ └── tests.md # テスト仕様 ├── src/ │ ├── auth.ts # // @lat: [[auth#OAuth Flow]] │ └── server.ts # // @lat: [[architecture#Request Pipeline]] ` Markdownファイルはそのまま人間が読めるし、Obsidian でグラフビュー表示もできる。AI専用のフォーマットではなく「人間にも読める設計書」として機能するのが面白い。 主要CLIコマンドと実践的な使い方 インストールはnpmで一発: `bash npm install -g lat.md lat init # lat.md/ ディレクトリをスキャフォールド ` 主なコマンド一覧: | コマンド | 用途 | |---|---| | lat check | wikiリンクとコード参照の整合性検証 | | lat locate "OAuth Flow" | セクション名でファジー検索 | | lat section "auth#OAuth Flow" | セクション詳細とリンク表示 | | lat search "how do we auth?" | ベクトル埋め込みによる意味検索 | | lat expand "fix [[OAuth Flow]]" | プロンプト内の [[refs]] を展開してエージェントへ渡す | | lat mcp | MCPサーバー起動(Cursor/VS Code統合) | lat check が特に実用的で、ドキュメントとコードの乖離(ドリフト)を自動検出してくれる。「ドキュメントは更新されたがコードは古いまま」という状態を防げる。 技術スタック・動作要件 - Node.js 22+(ESMモジュール)、TypeScript 5.7 - Markdownパース:remark-parse、AST解析:web-tree-sitter(正規表現ではなく本物のASTレベル解析) - セマンティック検索:@libsql/client(libSQL/Turso SQLite)でベクトル埋め込みを保存。OpenAI APIキーまたはVercel AI Gatewayキーが必要 - MCPサーバー:@modelcontextprotocol/sdkでエディタ統合 セマンティック検索には LAT_LLM_KEY 環境変数でAPIキーを渡す。ファイル参照やシェルコマンド経由の取得にも対応しており、キー管理が柔軟だ。 まとめ:AIエージェント時代の「生きたアーキテクチャドキュメント」 lat.md が提案するのは、単なるドキュメントツールではなく「AIとともに保守し続けるアーキテクチャ知識基盤」だ。コードとドキュメントを双方向にリンクし、ズレを自動検出し、エージェントが必要な文脈をオンデマンドで取得できる——これはAIエージェント駆動開発が当たり前になる時代に向けた、実践的なアプローチだと感じる。 v0.11.0時点ではまだ発展途上だが、Claude CodeやCursorをフル活用しているチームなら今すぐ試す価値がある。MCP統合があるので、エディタに直接組み込んでエージェントに渡す文脈を制御できるのは大きな強みだ。

🟠
Hacker News

Google SheetsをCRUD APIに変換するSheet Ninja──AIコーディングツールと組み合わせてバックエンド不要でアプリを爆速リリース

VibeコーディングブームでAIがフロントを書いてくれても「バックエンドどうする問題」が残るのが現実。Sheet NinjaはそこをGoogleスプレッドシートで強引に解決する割り切りが潔く、MVPを翌日公開したいエンジニア・非エンジニア問わず刺さるツールだ。

「バックエンドを書く前にアイデアが死ぬ」問題、あなたにも心当たりはないだろうか。LovableやReplit、Cursorなどでフロントを爆速生成できる時代になったのに、データの永続化のためにSupabaseやFirebaseを設定して、APIエンドポイントを書いて──という作業で勢いが止まる。Sheet Ninjaはそのボトルネックを「Googleスプレッドシートをそのままバックエンドにする」という逆転の発想で消し去るツールだ。 どういう仕組みか 使い方は驚くほどシンプルだ。 1. Googleスプレッドシートを開き、1行目をヘッダー行にする 2. Sheet NinjaにシートのURLを貼り付ける 3. 即座にREST APIが生成される 生成されたAPIエンドポイントは<strong>CRUD操作(GET/POST/PUT/DELETE)</strong>に対応しており、シートのセルを編集するとリアルタイムでAPIのレスポンスにも反映される。スキーマ定義もマイグレーションも不要。「Row 1 is your header. Rows 2+ are your data. Congratulations, you just architected a database.」という公式のコピーが妙に刺さる。 AIコーディングとの組み合わせが強烈 Sheet Ninjaが特に輝くのは、VibeコーディングのAIツールとの連携だ。対応ツールは以下の通り: - Replit / Lovable / Bolt.new / V0.dev - Claude / ChatGPT / Gemini - Cursor / Windsurf Sheet NinjaがAPIプロンプトを自動生成してくれるので、それをそのままAIに渡せばフロントエンドのデータ連携コードを書かせることができる。つまり「スプレッドシートを設計する → Sheet NinjaでAPI化 → AIにUI/ロジックを実装させる」という完全ノーバックエンドのフローが成立する。 意外と多様なユースケース 「スプレッドシートがDB」と聞くとオモチャっぽく聞こえるが、公式が挙げるユースケースはなかなか実用的だ: - AIエージェントのメモリストア: Q&Aペアや長期記憶をセルに保存。ハルシネーションしたらセルを直接修正すればいい - ウェイトリスト収集: 夜9時にアイデアが浮かんで、10時にはメール収集フォームを公開できる - マーケティングCMS: エンジニアを介さずコピーライターがH1やCTAを直接編集・A/Bテスト - <strong>QRコードメニュー(飲食店向け)</strong>: 値段変更はセルを1つ書き換えるだけ。PDFの再印刷不要 - Streamlitダッシュボード: CSVをシートに貼り付けてPythonで即可視化 `python StreamlitとSheet Ninja APIを繋ぐイメージ import requests import streamlit as st import pandas as pd API_URL = "https://api.sheetninja.io/v1/your-sheet-id" data = requests.get(API_URL).json() df = pd.DataFrame(data) st.dataframe(df) ` 使う前に確認しておきたいこと Googleスプレッドシートをバックエンドにする設計には当然トレードオフがある。同時書き込みの競合、行数が増えた際のパフォーマンス、アクセス権限管理の粒度など、本番スケールでは考慮が必要な点もある。プロトタイプ・MVP・社内ツール・小規模プロダクトに特に向いており、ユーザー数が爆発的に増えるサービスの本番DBとして使うのは現実的ではないだろう。無料ティアで始めて、限界を感じたら別のバックエンドへ移行するという割り切りが正しい使い方だ。 とはいえ、「アイデアを思いついた夜に動くものを作る」という体験の価値は本物だ。バックエンドのセットアップで消耗するくらいなら、Sheet Ninjaで検証してから本格実装を考えるのは十分合理的な選択肢だと思う。Product Hunt公開中で現在クーポンコード PH20 で20%オフとのこと。

📝
Qiita

デザイントークンとは?チームの「言葉」を統一するデザインシステムの核心

「デザインシステム=コンポーネント集」だと思っていた人に刺さる視点の転換。命名の統一こそが本質という気づきは、デザイナーだけでなくエンジニアリードにも読んでほしい一本。

「あのボタンの色、何色だっけ?」「このspacing、8pxだったっけ16pxだったっけ?」——デザイナーとエンジニアが別々の言葉で同じものを呼んでいる状況、心当たりはないだろうか。レコチョクのプロダクトデザイナー・河野氏が公開した記事では、<strong>デザイントークンを軸にチーム全体の「単語を統一する」こと</strong>こそがデザインシステムの本質だと喝破している。 デザインシステムの目的を再定義する 同社ではEggsとGIGGSという2つのプロダクトのUIを、<strong>「Sauna」という名前のデザインシステム</strong>で管理している。Saunaのミッションは「あらゆる階層のデザインがととのうための仕組みをそろえる」、ビジョンは「関わる人のあらゆる迷いを減らす」だ。 記事の著者が社内向け勉強会を準備する中で気づいたことが興味深い。デザイントークンの命名も、コンポーネント名のルール化も、突き詰めれば同じものを同じ言葉で呼べるようにする活動に収束する、という発見だ。デザインシステムの究極の目的は「チームで使われる単語を統一すること」——この一言で全てが説明できる。 デザイントークンが解決する課題 デザイントークンとは、色・スペーシング・タイポグラフィなどのデザイン上の値を、意味のある名前で一元管理する仕組みだ。例えば: - #1A73E8 という色コードではなく color.primary.500 という名前で管理する - 16px という数値ではなく spacing.md として定義する - Figmaのスタイルとコードの変数を同じトークン名で紐づける こうすることで、デザイナーがFigmaで「color.primary.500を使った」と言えば、エンジニアも迷わず同じ値を実装できる。<strong>ツールをまたいでも「言葉」が共通</strong>になるのだ。 Figmaとコードの橋渡しとしてのトークン設計 Saunaでの実践では、トークンを3階層で設計している点が参考になる: ` [Primitive] → [Semantic] → [Component] 例: blue.500 → color.primary.default → button.bg.default ` - Primitiveトークン:blue.500のような生の値。パレットそのもの - Semanticトークン:color.primary.defaultのように「意味」を付与したもの - Componentトークン:button.bg.defaultのようにUIパーツに紐づけたもの この階層設計があることで、ダークモード対応やブランドカラー変更の際もSemanticレイヤーの値を差し替えるだけで全体に反映できる。 まとめ:命名こそがデザインシステムの本質 デザインシステムの導入を検討しているチームが最初に悩むのは「コンポーネントライブラリをどう作るか」だが、この記事が示す本質は違う。何をどう呼ぶか、命名の哲学こそが先にあるのだ。ツールはFigmaでも何でも良い。チームが同じ言語で話せるかどうか——デザイントークンはその「共通言語の辞書」として機能する。 シリーズ記事として命名管理・OOUI編、Figma運用Tips編も公開予定とのことで、実務レベルのノウハウが続々と提供されそうだ。自社プロダクトにデザインシステムを導入したいと考えているデザイナー・フロントエンドエンジニアには必読の内容だ。

🔥
Zenn

図形入りPowerPointをMarkdownに変換する方法|GitHub Copilot × OpenXML SDKの仕組みを徹底解説

「LLMに指定言語を使わせるのが難しい」という実践的な知見が刺さる記事。PowerPoint変換の技術的な仕組みだけでなく、プロンプトエンジニアリングの現場感を伝えており、GitHub Copilot Agentを業務利用しているエンジニアに特にオススメしたい。

「PowerPointの複雑な図形をそのままMarkdownに変換したい」——そんな需要は意外と多い。ドキュメント整備やGitHub管理、AI読み込み用テキスト化など、用途はさまざまだ。今回は日本マイクロソフトのKazuki Otaさんが公開したリポジトリ github-copilot-excel-lab を実際に動かした際の知見をまとめた記事を紹介する。 環境構築:WSLにdotnetが無い場合の対処法 ローカルWSLに .NET実行環境 がない場合、Dev Containerで即座に解決できる。手順はシンプルだ。 1. Docker + VS Code拡張機能をインストール 2. リポジトリをクローン後、Ctrl+Shift+P → Dev Containers: Add Dev Container Configuration Files 3. C#(.NET) テンプレートを選択してコンテナで再起動 環境構築を省きたいなら GitHub Codespaces が最速。dotnet・Pythonなど開発ツールが最初から揃っており、ブラウザだけで作業完結する。 ハマりポイント①:dotnet runの自動承認 GitHub Copilot経由でターミナルコマンドを実行するたびに承認を求められると作業が止まる。.vscode/settings.json に以下を追記することで、dotnet run - で始まるコマンドを自動承認できる。 `json { "chat.tools.terminal.autoApprove": { "/^dotnet run -/": { "approve": true, "matchCommandLine": true } } } ` ハマりポイント②:LLMがPythonに逃げる問題 これが一番面白い知見だ。スキルファイルで「dotnetを使え」と指示しているのに、LLMはなぜかPythonで実装しようとする。この挙動はCopilotに限らず多くのLLMで観測される傾向で、「Pythonの学習データが圧倒的に多いからでは」という推測が面白い。 解決策は スラッシュコマンドでスキルを明示的に指定 すること。 ` /scripting-guide /workspaces/github-copilot-excel-lab/pptx/抜粋.pptx に対して OpenXML SDK 等を使って解析を行い、mermaid 形式の図を含んだ markdown に変換してください。 最終成果物は /workspaces/github-copilot-excel-lab/pptx/report.md に出力してください。 ` もう一つのポイントは 絶対パスで記述すること<strong>。相対パスより絶対パスの方がスクリプト実行の成功率が高いという実測結果は、プロンプトエンジニアリングの実践知として覚えておきたい。なお、記事中では「</strong>Claude Sonnet 4.6くらいの賢いモデルであればMarkdownへの変換はほぼ成功する」との記述もあり、モデル選定が変換品質に直結することも示唆されている。 変換の仕組み:OpenXML SDKで何をしているか GitHub Copilotが生成するC#コードは、大きく2段階で処理される。 第1段階:構造把握 - .pptxをOpenXML SDKで開き、各スライドのXMLを読み込む - テキスト(<a:t>要素)を抽出 - 図形(sp)・コネクタ(cxnSp)・画像(pic)・グラフィックフレームの数を集計 第2段階:座標・接続関係の解析 - 各図形の位置(<a:off>)とサイズ(<a:ext>)を取得 - コネクタの接続先IDから「どの図形とどの図形がつながっているか」を解析 - この位置関係・接続情報をもとにLLMが意味を推測し、Mermaid記法に変換 コードの先頭にある #:package DocumentFormat.OpenXml はC#スクリプト実行環境でNuGetパッケージをその場で宣言する記法。通常の .csproj 管理とは異なるアプローチで、Copilotがインタラクティブに試行錯誤できる構造になっている。 生成されたMarkdownの確認環境 生成物をそのまま読むのは辛いので、devcontainer.jsonに以下のVS Code拡張機能を追加しておくと快適だ。 `json "extensions": [ "TakumiI.markdowntable", // テーブルの整形 "bierner.markdown-mermaid", // Mermaidのプレビューレンダリング "yzane.markdown-pdf" // PDFへのエクスポート ] ` まとめ:「AIにdotnetを使わせる」プロンプト設計の難しさ この記事の本質は、PowerPoint変換の技術解説であると同時に、LLMへの指示設計の実践報告でもある。「スキルで言語指定しても無視される」「絶対パスの方が成功率が高い」——こういった泥臭い知見は、公式ドキュメントには載っていないリアルな情報だ。Dev Container構築からプロンプト改善まで一気通貫で試せる環境が公開されているので、Copilot AgentやMCP連携を試している方は元リポジトリと合わせてぜひ手を動かしてみてほしい。

🔥
Zenn

GoのBCE(境界チェック除去)を意識してループを最大30%高速化する方法

「コンパイラが証明しやすいコードを書く」という発想の転換が面白い。encoding/hexの実PRを題材に、デバッグフラグの使い方まで丁寧に解説されており、今すぐ自分のホットループに適用できる実践的な内容だ。

Goでパフォーマンスチューニングをしているとき、「コードのロジックは変えていないのに遅い」という壁にぶつかることがある。その原因のひとつが <strong>境界チェック(Bounds Check)</strong> だ。Goはスライスや配列へのアクセス時にインデックスが範囲内かどうかを実行時に検証する。安全性のための仕組みだが、ホットループの中で何万回も実行されると無視できないオーバーヘッドになる。 Goコンパイラには <strong>BCE(Bounds Check Elimination)</strong> という最適化がある。SSA(Static Single Assignment)の解析パスで「このアクセスは絶対に範囲内」と証明できた場合、境界チェックを自動的に除去してくれる仕組みだ。つまり、コンパイラが証明しやすいコードを書くだけで速くなる。ロジックは一切変えなくていい。 標準ライブラリの encoding/hex パッケージにまさにこのBCEを活かした最適化PRが提出されており、Decode 関数が 15%高速化 されている。変更点はたった数行。ループの書き方を変えただけだ。 `go // 変更前: j-1 インデックスアクセス(境界チェックが残る) for ; j < len(src); j += 2 { p := src[j-1] // コンパイラがj-1 >= 0を証明できない q := src[j] } // 変更後: j, j+1 インデックスアクセス(境界チェックが除去される) for ; j < len(src)-1; j += 2 { p := src[j] // j < len(src)-1 なので安全と証明できる q := src[j+1] // j+1 <= len(src)-1 なので安全と証明できる } ` j-1 の場合、j が1から始まるので人間には安全だとわかる。しかしGoコンパイラのproveパスは コンパイル速度を重視した軽量設計 であり、ループ変数の初期値から減算結果の下界を導くような複雑な推論は行わない。一方 j < len(s)-1 という条件があれば、j+1 < len(s) はトリビアルに証明できる。 この最適化が効いているかどうかは以下のコマンドで確認できる。 `bash go build -gcflags='-d=ssa/check_bce/debug=1' ./... ` Found IsInBounds という出力が境界チェックが残っている箇所だ。パフォーマンスが重要なループで一度確認してみると、意外なところでチェックが残っていることに気づくはずだ。 BCEを活かすための実践ポイントをまとめると: - += 2 ステップのペアアクセスは s[j-1] より s[j] と s[j+1] に書き直す - ループ条件を j < len(s)-1 にすれば j+1 も安全と証明される - リスライス s[i:i+2:i+2] で窓を切る方法も有効(境界チェックがリスライス時の1回に集約) - go build -gcflags='-d=ssa/check_bce/debug=1' で残存チェックを可視化する 実際のベンチマークでは PairSumOld(素朴な実装)に対して PairSumNew(ループ条件変更)が 約30%高速化 という結果が出ている。たった1行の変更でこれだけ差が出るのは、ループ内で境界チェックが毎回実行されていたからだ。 アルゴリズムの改善ではなく、コンパイラの最適化を邪魔しないコードを書くという視点は、Goのパフォーマンスチューニングにおいて見落とされがちなアプローチだ。encoding/hexのPRはその好例で、コードの意味を変えずに15%高速化している。ホットループを書く機会があれば、ぜひBCEを意識してみてほしい。元記事にはベンチマークコードのリポジトリも公開されており、手元でそのまま試せる。

🟠
Hacker News

go.modのgoディレクティブを誤用していませんか? バージョン指定の正しい意味と落とし穴

Goのgo.modを「自分のバージョン設定ファイル」と思い込んでいる人がいたら今すぐ読んでほしい記事。推移的依存を通じてエコシステム全体に影響する話なので、OSSメンテナーには特に刺さります。

go.mod の go ディレクティブ、あなたは正しく使えていますか? Goプロジェクトを運用していると、go.mod に必ず書く go 1.xx.x という一行を何となく「自分が使っているGoのバージョン」として設定していませんか? 実はこれ、Go 1.21以降に広まった典型的な誤用で、あなたのライブラリを使う全員に影響を与えてしまいます。 何が問題なのか? go.mod の go ディレクティブが意味するのは、<strong>「このプロジェクトをコンパイルできる最小バージョン」</strong>です。「自分がビルドに使っているバージョン」ではありません。 Go 1.21より前は go 1.21 のようにマイナーバージョンまでしか書けませんでしたが、1.21からパッチバージョンまで含む形式(go 1.21.0)が導入されました。これを機に、多くのプロジェクトが go mod init や go mod tidy のデフォルト挙動のまま最新パッチ番号をそのまま書くようになり、問題が急増しています。 ` これは「1.25.7以上でないとビルド不可」を全依存元に強制することになる go 1.25.7 本来あるべき姿:実際に依存する最小バージョンを明示する go 1.21 ` なぜ「ウイルス的」に広がるのか この問題が厄介なのは、<strong>推移的依存(transitive dependency)</strong> を通じて伝播する点です。 - あなたのライブラリAが go 1.25.7 と書く - ライブラリBがAに依存する - アプリCがBに依存する - → CはAのコードを一行も直接使っていなくても、Go 1.25.7以上でないとビルドできない 大規模なモノレポや組み込み・レガシー環境では、Goのバージョンを最新に保てない事情が多々あります。ライブラリ作者がこの1行を安易に設定するだけで、見知らぬ誰かのCIが壊れる可能性があるのです。 よくある誤解と正しい対応 - <strong>「最新バージョンを強制することでセキュリティを高められる」</strong> → それはライブラリ作者の仕事ではありません。依存元が自分でバージョン管理を行うべきです - <strong>「GitHub ActionsのSetup-Goが go ディレクティブを読んでバージョンを決定する」</strong> → これはCI側の設計ミス。toolchain ディレクティブや actions/setup-go の go-version-file オプションを正しく使いましょう - <strong>「go mod init がデフォルトで最新版を入れるから正しいはず」</strong> → これはGoのデフォルト設定が悪いのであって、仕様の意図は「最小バージョン」です。手動で適切な値に下げることを推奨します `bash go.modを開いて、本当に必要な最小バージョンに修正する 例:Go 1.21の機能を使っているなら go 1.21 ビルドに使うバージョンを明示したい場合はtoolchainディレクティブを使う toolchain go1.25.7 ` まとめ・所感 go ディレクティブは「自分の開発環境バージョン」ではなく、<strong>「このコードが動く最低ラインの宣言」</strong>です。特にOSSライブラリを公開している方は、不用意に高いパッチバージョンを書かないよう意識してほしいところです。 「ビルドに使うバージョンを固定したい」という正当なニーズには toolchain ディレクティブが用意されています。用途を正しく分離することで、エコシステム全体の互換性を守れます。元記事ではさらに詳細なFAQと具体的なワークアラウンドが紹介されているので、Goでライブラリを公開・メンテナンスしている方はぜひ一読することをおすすめします。

🟠
Hacker News

TreeTrek — Gitリポジトリをブラウザで閲覧できる軽量PHPビューアの使い方

GitHubに頼らず自前サーバーでコードを公開したい人に刺さる軽量ツール。PHP単体で動くシンプルさが潔く、Git内部構造を学ぶ入門教材としても面白い一本。

<strong>「GitHubなしで自分のリポジトリをWeb公開したい」</strong> と思ったことはないだろうか。VPSやレンタルサーバーにコードを置いているけれど、ブラウザからサクッとファイルツリーを眺めたい——そんなニーズに刺さるOSSが TreeTrek だ。 TreeTrekとは何か TreeTrekは、<strong>生のGitリポジトリ(bare repo)を直接読み取り、Webブラウザ上でファイルツリーとコンテンツを表示するPHP製のビューアアプリ</strong>だ。GitHubやGitLabのような重厚なプラットフォームではなく、シンプルに「.gitディレクトリを覗く」ことに特化している。依存ライブラリも最小限で、PHPが動くサーバーさえあれば動作する。 リポジトリ構造を見ると、model/・pages/・render/・styles/ という明確なレイヤー分離が見て取れる。Gitオブジェクト(blob/tree/commit)を読み取るロジックをモデル層に集約し、HTMLレンダリングを分離するシンプルなMVC的設計だ。 技術的な仕組み Gitリポジトリは本質的にはファイルシステム上のオブジェクトDBだ。TreeTrekはPHPから直接 .git/objects/ を解析し、以下のような流れでコンテンツを返す: - HEAD → ブランチ参照 → コミットオブジェクト を辿ってルートtreeを特定 - treeオブジェクト を再帰的に展開してファイル一覧を構築 - blobオブジェクト をデコードしてファイル本文を表示 データベース不要・外部APIなし。git コマンドすら不要で、Pure PHPでオブジェクトを読む設計になっているとみられる(Config.php で bare リポジトリパスを指定する形式)。 セルフホストして使う方法 公開されている INSTALL.md に従えばセットアップは数分で完了するはずだ。基本的な手順はこうなる: `bash bare リポジトリを用意(例) git clone --bare https://github.com/yourname/yourrepo.git /var/repos/yourrepo.git TreeTrek をWebサーバーのドキュメントルートに配置 git clone https://repo.autonoma.ca/treetrek /var/www/treetrek Config.php でリポジトリパスを指定 → ブラウザで http://yourserver/treetrek にアクセスするだけ ` ApacheやNginxでPHPが動いていれば追加設定はほぼ不要。Lolipopやさくらのレンタルサーバーでもそのまま動作するはずで、コマンドラインが使えない環境でもFTPでファイルを置くだけというお手軽さが魅力だ。 こんな用途に刺さる - プライベートサーバーのコードをチームや顧客に読み取り専用で公開したい - Gitea/Giteaほどの機能は要らないが、ファイルツリーだけ見せたい - Git内部の仕組みを学ぶ教材として、PHPコードを読んで理解したい - GitHub Pagesが使えないオンプレ環境での軽量代替 Hacker Newsへの投稿時点ではポイント・コメント数ともに少なく、まだ知名度は低い。しかしそのシンプルさは、過剰な機能を嫌う「Unix哲学」的なエンジニアには刺さるプロジェクトだと思う。ソースコード自体もTreeTrek上でブラウズできる点が粋で、ドッグフーディングとして完璧なデモになっている。

🔥
Zenn

同人作品ビューアをRust + SvelteKit + Tauriで自作した話——要件定義から始めるDLsite Playクローン設計

「AIに全部作ってもらったのに3日で使わなくなる」という痛烈な自己批判から始まる要件定義の話が本質を突いている。Rust + Tauri構成の個人開発として技術的にも読み応えがあり、Claude Code活用の実例としても参考になる一本。

「DLsite Playみたいなビューアを自分で作れないか」——そう思ったことがある人は少なくないはずだ。この記事では、Zennに投稿されたエンジニアの実践記録をもとに、同人作品ビューアの自作プロセスと、その根幹にある「要件定義」の考え方を掘り下げる。 なぜDLsite Playクローンが必要なのか DLsite Playは2015年から提供されている同人作品ビューアで、ZIPを解凍せずブラウザ上で画像・音声・動画・PDFを横断的に閲覧できる優れたサービスだ。しかし致命的な問題がある——サークルが退会・販売終了すると購入済み作品も読めなくなること、そしてDLsite以外のコンテンツを登録できないことだ。買ったはずの作品がある日突然消える体験は、デジタルコンテンツの「所有」の曖昧さを突きつける。 要件定義こそが自作の肝 著者が強調するのは「Claude Codeに全部盛りを作ってもらっても3日で使わなくなる」という現実だ。機能を闇雲に詰め込む前に、本当になければ即捨てるコア機能を言語化する必要がある。 既存ツールの比較分析を経て定義したコア要件はシンプルだった: - フラットな作品一覧と階層フォルダ構造を完全に区別して表示できる - ファイルシステムの制約を受けない<strong>別名(作品名)表示</strong>ができる - 画像・PDF・音声・動画・テキストを新しいタブを開かずに閲覧できる この3点に絞り込んだことが重要で、著者はこれを「作品フォルダ指向のプレビュー付きファイルマネージャ」と定義した。LANraragi・Komga・Kikoeru・Stashなど多数の既存OSSを比較した結果、この3要件を同時に満たすアプリは存在しなかった。 技術スタック:Rust + SvelteKit + Tauri 既存ツールに限界を感じた著者は自作を決断。採用した構成はこうだ: - バックエンド: axum(Rust製非同期Webフレームワーク) - フロントエンド: SvelteKit - デスクトップモード: Tauri(Rust製クロスプラットフォームアプリフレームワーク) - コーディング支援: Claude Code コーディングの多くをClaude Codeに任せつつも、Rustを選んだ理由は「自分でチェックしやすいから」。AIが生成したコードを人間がレビューする前提で、自分の得意言語を選ぶという判断は非常に実践的だ。デモ版は公開されており、実際に触れる。 所感:要件定義 × AI開発の組み合わせ 「3日で使わなくなるアプリ」を量産しないための処方箋として、この記事の要件定義プロセスは示唆に富む。DLsite Playを「いいところ・よくないところ」の両面から分析し、既存ツールをMECE的に比較分類して、自分が本当に欲しいものを言語化する——このプロセスは同人ビューアに限らずあらゆる個人開発に応用できる。Claude Codeをはじめとする生成AIが「実装速度」を劇的に上げた時代だからこそ、何を作るかの言語化がより重要になっている。Rust・SvelteKit・Tauriの組み合わせに興味がある方にも、コードの詳細を含む元記事は必見だ。

🔥
Zenn

Docling の使い方|PDFをMarkdownに変換してLLM・RAGの精度を上げる

LLMアプリやRAGを本番運用しているエンジニアなら必ず突き当たるドキュメント前処理の壁を、IBMのOSSが正面から解決してくれる。コマンド一発で試せる手軽さも◎。

PDFをLLMに渡すとき、構造が壊れていませんか? LLMを使ったアプリケーションを開発していると、必ず直面するのが「PDF・Word・PowerPointをどうインプットに変換するか」という問題だ。pdfminer や PyMuPDF でテキスト抽出はできても、見出し・表・リスト構造が失われた「ベタ打ちテキスト」をLLMに渡しても精度は上がらない。RAGの回答品質が低い原因の多くは、モデルではなくドキュメント前処理にあるというのは、現場で痛感している方も多いはずだ。 そこで今回紹介するのが <strong>Docling(ドックリング)</strong>。IBM Research Zurichが開発したオープンソースの文書変換ライブラリで、文書の構造を保ったままMarkdownやJSONに変換できる。 Doclingのアーキテクチャ:なぜ「構造を保てる」のか Doclingの核心は、入力形式に応じて処理パイプラインを切り替え、最終的に DoclingDocument という統一形式に変換するアーキテクチャにある。 - StandardPdfPipeline:PDFや画像入力に対して、レイアウト解析・OCR・表構造認識を実行して構造を再構成 - SimplePipeline:Word・HTML・AsciiDocなど、もともと構造情報を持つ形式はその情報を活かして変換 この設計により、見出し・段落・表・リスト・図版といった要素を反映したデータとして扱えるようになる。後続のチャンク分割やRAGへの組み込みもシンプルになるのが大きな強みだ。 インストールとCLI基本操作 Pythonパッケージとして提供されており、pip 一発でインストールできる。 `bash pip install docling ` インストール後は docling コマンドが使えるようになる。代表的な使い方をまとめる。 `bash PDFをMarkdownに変換(最もシンプル) docling sample.pdf JSON形式で出力 docling --to json sample.pdf 複数PDFを一括処理 docling --output ./output *.pdf URLから直接変換 docling https://example.com/sample.pdf OCRエンジンをTesseractに変更 docling --ocr-engine tesseract sample.pdf デバッグ用ログ表示 docling --verbose sample.pdf ` 出力形式は --to オプションで Markdown / JSON / YAML / HTML を選択できる。docling --help で全オプションを確認しよう。 Pythonスクリプトへの組み込み CLIだけでなく、アプリケーションに直接組み込むことも簡単だ。 `python from docling.document_converter import DocumentConverter source = "https://arxiv.org/pdf/2408.09869" converter = DocumentConverter() result = converter.convert(source) with open("output.md", "w", encoding="utf-8") as f: f.write(result.document.export_to_markdown()) ` URLを渡すだけでMarkdownが得られる。RAGパイプラインの前処理ステップとして組み込む場合、result.document オブジェクトを直接操作してチャンク分割やメタデータ抽出に活用することもできる。 まとめ:モデルより前処理を疑え LLMの回答精度が思うように上がらないとき、真っ先に疑うべきは入力ドキュメントの品質だ。Doclingは「単なるテキスト抽出」を超えて、文書の構造・意味的まとまりを保ったままLLMに渡せる形に変換してくれる。arxivの論文PDFを実際に変換してみると、見出しや段落がかなり自然にMarkdown化されるとのこと。RAGの構築・改善に取り組んでいるなら、まず pip install docling から試してみる価値は十分にある。

🔥
Zenn

CursorからClaude Code(cmux)に移行してわかった:快適に使うための7つの設定

CursorからClaude Codeへの移行でつまずきがちな「初期設定の不便さ」を丁寧に解消した実践記録。cmux/Ghostty/yazi/gripの組み合わせは知らなかった人も多いはずで、すぐ試せる設定が詰まっている。

<strong>「CursorよりClaude Codeのほうが使いやすい」</strong> という状態にたどり着くまで、何を設定したのか——Zennに投稿されたこの記録が、AI開発環境の移行を検討しているエンジニアにとって非常に参考になる内容だったので紹介したい。 Claude Codeはターミナルベースの AIコーディングアシスタントで、cmux(Claude Multiplexer)と組み合わせることでGUI的な操作感を得られる。ただし初期設定のままでは「ちょっと使いにくい」と感じる部分が多い。著者は約1週間かけて環境を整備し、「トータルでCursorより使いやすい」と言える状態に仕上げた。 やったこと一覧 1. Ghosttyでcmuxの見た目を整える cmuxは内部的に Ghostty をターミナルエンジンとして使っている。そのため外観カスタマイズはGhosttyの設定ファイルを書くことで実現できる。 ` theme = "Kanagawa Wave" window-theme = dark font-family = "SF Mono" font-size = 13 cursor-color = #7e9cd8 selection-background = #2d4f67 unfocused-split-opacity = 0.7 ` フォントに SF Mono を指定(brew install font-sf-mono で追加可能)、テーマは Kanagawa Wave でダーク系の落ち着いた配色にしている。 2. Starship + zshrcでシェルを快適化 プロンプトは Starship で整備。表示項目をディレクトリ・gitブランチ・gitステータス・コマンド実行時間に絞り、aws/gcloud/nodejs等の不要モジュールを全て無効化してノイズを排除した。 `toml format = """ $directory\ $git_branch\ $git_status\ $cmd_duration\ $line_break\ $character""" ` zshrc側では以下が特に実用的: - zsh-autosuggestions:履歴ベースのコマンド候補をグレー表示、Ctrl+Fで確定 - zsh-syntax-highlighting:コマンドの構文ハイライト - ↑↓キー:入力中のコマンドにマッチする履歴を遡る - h 関数:pecoで履歴検索してそのまま実行 - c 関数:過去に訪れたディレクトリをpecoで選んでcd - rmのtrash置き換え:誤削除防止のため trash コマンドにエイリアス 3. ファイルツリーはyaziで解決 GUIのファイルツリーが恋しい場合は yazi(Rust製のターミナルファイルマネージャ)を導入。隠しファイルのデフォルト表示、fzf検索(Fキー)、ファイルパスのクリップボードコピー(yp)などカスタムキーマップも追加している。 `toml [[mgr.prepend_keymap]] on = ["F"] run = 'shell "root=$(git rev-parse --show-toplevel 2>/dev/null || echo .); file=$(cd \"$root\" && fd --type f --hidden --exclude .git | fzf --layout=reverse); [ -n \"$file\" ] && ya emit reveal \"$root/$file\"" --block' desc = "fzf search" ` 4. Markdownプレビューはgripで grip(GitHub風レンダリングサーバー)とシェルスクリプトを組み合わせ、yaziで選択したMarkdownファイルをcmuxのブラウザタブで即プレビューできる環境を構築。ホットリロード対応・プロセス重複防止も実装済み。CSSは ~/.grip/settings.py に書いてダークテーマに統一している。 移行してみての所感 Cursorからの移行でネックになりがちなのが「GUI前提の操作感との乖離」だが、cmux + yazi + gripの組み合わせでファイルブラウズ・Markdownプレビューをターミナル内で完結できる点が大きい。特に Starshipのノイズ排除 と peco連携の履歴検索 は、一度使うと手放せない快適さだ。 設定ファイルの量は多いが、著者が「1週間で整備できた」と言っているように、段階的に積み上げていける範囲。Claude Codeへの移行を検討しているなら、この記事の設定を丸ごと参考にするのが最短ルートだろう。

📝
Qiita

AWS Bedrock AgentCoreがMacでは動くのにWindowsでエラーになる原因を内部実装から解明した

AgentCoreを社内展開・教材化しようとしている方に刺さる実践的な検証記事。公式ドキュメントの空白を埋めるソースコードレベルの調査は、同じ問題で詰まったときの道標になる。

MacでOK、WindowsでNG — AgentCoreの謎のエラーを追いかけた話 Amazon Bedrock AgentCore を使い始めたエンジニアが最初につまずく落とし穴のひとつが、OS・アーキテクチャ差による動作の違いだ。「Macでは何も指定しなくて動くのに、Windowsでは500エラーになる」という現象に遭遇した著者が、公開ソースコードを地道に追うことで原因を特定した記事が公開された。公式ドキュメントには載っていない検証内容だけに、AgentCoreを本格導入しようとしているチームには刺さる内容だ。 発生するエラーと環境差 問題のエラーはこちら。 ` ERROR: Workload access token has not been set. If invoking agent runtime via SIGV4 inbound auth, please specify the X-Amzn-Bedrock-AgentCore-Runtime-User-Id header and retry. ` 同じコマンド uv run agentcore invoke '{"prompt": "利用できるツールを教えて"}' を叩いても、環境によって結果が変わる。 | 項目 | Mac | Windows | |------|-----|---------| | OSアーキテクチャ | linux/arm64 (ネイティブ) | linux/amd64 | | Docker Desktop | あり | なし | | --user-id なしで invoke | ✅ 動く | ❌ エラー | 注目すべきは、エラーがローカルPCで起きているのではなく AWS上で動いているコンテナ内 で発生している点。CloudWatch Logsのスタックトレースを見ると、エラー発生箇所は bedrock_agentcore/identity/auth.py の _get_workload_access_token() だとわかる。 なぜアーキテクチャで挙動が変わるのか 著者が辿り着いた根本原因は deploy時のビルドパス分岐 にある。 - AgentCoreのCLIは agentcore deploy 時にDockerイメージをビルドしてAWSにプッシュする - Mac (arm64) と Windows (amd64) では、ビルドプロセスで選択されるベースイメージやコンテキストが異なる - その差異が、コンテナ実行時の DOCKER_CONTAINER 環境変数の有無や認証情報の受け渡し方に影響する - Identity / Gateway / Runtime を組み合わせた構成でツール呼び出しを行うとき、IdentityへのWorkload Access Tokenの受け渡しがアーキテクチャ差によって失敗するケースがある ポイントをまとめると: - Runtime単体(ツールなし)ではこのエラーは発生しない - Identity認証を挟むツール呼び出しがあるとき初めて問題が顕在化する - Mac環境では環境変数やコンテナ構成の違いにより、tokenが自動的にセットされる経路に乗っている 対処法と実践的な注意点 エラーメッセージの指示通り --user-id を明示的に付与することで回避できる: `bash uv run agentcore invoke --user-id <your-user-id> '{"prompt": "利用できるツールを教えて"}' ` ただし、これは「症状を抑える」対処であって根本原因を理解せずに使うと、CI/CDパイプラインやクロス環境のハンズオン教材を作るときに同じ罠にはまりやすい。元記事では内部実装コードの該当箇所まで深掘りしており、auth.py の _get_workload_access_token がどの条件でTokenをセット済みとみなすかのロジックも確認できる。 実運用で気をつけるべきポイント: - チーム開発では開発者のOSアーキテクチャが混在することを前提にする - agentcore deploy 時のアーキテクチャ(ビルドマシン)を揃えるか、CIで固定する - Windows開発者は --user-id を必須オプションとして認識しておく - Runtime + Identity + Gatewayの3層構成を使う場合は特に注意 まとめ Amazon Bedrock AgentCoreはまだドキュメントが薄く、こういった「動く環境と動かない環境がある」系の問題は個人が検証して知見を共有してくれる記事が最も頼りになる。特にエンタープライズ環境ではMac + Windows混在は当たり前なので、今後AgentCoreを展開しようとしているチームは早めにこの挙動差を把握しておきたい。著者が「ハンズオン教材を作ろうとしてぶつかった」という経緯も、現場感があってリアルだ。