[{"data":1,"prerenderedAt":385},["ShallowReactive",2],{"content-/kindle-import-8books-parallel-pipeline":3,"all-pages-for-dir":383,"og-image-/kindle-import-8books-parallel-pipeline":384},{"id":4,"title":5,"body":6,"category":365,"description":366,"extension":367,"meta":368,"navigation":335,"ogImage":369,"path":370,"project_name":371,"published":372,"publishedAt":373,"seo":374,"stem":375,"tags":376,"todo":369,"unpublished":372,"updatedAt":369,"__hash__":382},"pages/2026-06/2026-06-21/kindle-import-8books-parallel-pipeline.md","Kindle取込パイプラインを並列化して1日に8冊取り込んだ",{"type":7,"value":8,"toc":357},"minimark",[9,18,22,29,43,116,122,128,132,139,142,148,153,156,245,248,251,254,261,264,272,275,278,282,289,292,295,298,301,304,317,320,323,353],[10,11,12,13,17],"p",{},"book-knowledge-base のKindle取込パイプラインに小説・描き方シリーズの除外ロジックを足し、午前4冊・午後4冊で計8冊を1日で取り込んだ。最初は直列で待ち時間を寝かせていたが、スラッシュコマンドを読み返して並列化したところ撮影とOCRが噛み合った。途中で方向誤判定と Chrome の ",[14,15,16],"code",{},"Tabs cannot be edited right now"," を踏んだので、リカバリも含めて残す。",[19,20,21],"h2",{"id":21},"取り込み対象から外す本にタグを付けた",[10,23,24,25,28],{},"朝のセッションは、進捗ファイル ",[14,26,27],{},"memo/2026-06-19/kindle-import-progress.md"," の冒頭に「次に取り込む候補トップ10」を表示させたかったところから始まった。ただ候補リストに小説や画集が混ざっていたので、まずは取り込まないものを切り捨てた。",[10,30,31,34,35,38,39,42],{},[14,32,33],{},"kindle_library_tagger.py"," に ",[14,36,37],{},"novel"," タグの判定ロジックを追加して dry-run を走らせた。43件ヒットしたが、鈴木みそ（Kindle出版ノウハウ）と前田裕二（人生の勝算）が誤って小説判定に流れていたので除外条件を足した。寺田寅彦の随筆7冊は ",[14,40,41],{},"amazon_metadata.author"," 側に「寺田 寅彦」の半角スペース表記しか入っておらず、英語表記しか見ていなかった判定ロジックを直したら拾えるようになった。最終的に47件に novel タグを付けた。",[44,45,50],"pre",{"className":46,"code":47,"language":48,"meta":49,"style":49},"language-python shiki shiki-themes vitesse-light vitesse-light","# 集計とスキップ判定の双方に novel/drawing を追加\nSKIP_TAGS = {\"comic\", \"novel\", \"drawing\", \"excluded\"}\n","python","",[14,51,52,61],{"__ignoreMap":49},[53,54,57],"span",{"class":55,"line":56},"line",1,[53,58,60],{"class":59},"sxvE3","# 集計とスキップ判定の双方に novel/drawing を追加\n",[53,62,64,68,72,75,79,83,85,88,91,93,95,97,99,102,104,106,108,111,113],{"class":55,"line":63},2,[53,65,67],{"class":66},"snbK4","SKIP_TAGS",[53,69,71],{"class":70},"shFtX"," =",[53,73,74],{"class":70}," {",[53,76,78],{"class":77},"sMJiu","\"",[53,80,82],{"class":81},"sdGka","comic",[53,84,78],{"class":77},[53,86,87],{"class":70},",",[53,89,90],{"class":77}," \"",[53,92,37],{"class":81},[53,94,78],{"class":77},[53,96,87],{"class":70},[53,98,90],{"class":77},[53,100,101],{"class":81},"drawing",[53,103,78],{"class":77},[53,105,87],{"class":70},[53,107,90],{"class":77},[53,109,110],{"class":81},"excluded",[53,112,78],{"class":77},[53,114,115],{"class":70},"}\n",[10,117,118,119,121],{},"続いて描き方シリーズ。デッサンやイラスト技法書の ",[14,120,101],{}," タグを足したら12件ヒットして、ここは誤判定なしで一発で通った。途中で「英単語1100」が紛れ込みかけたのでタイトルキーワードを絞った。",[10,123,124,125,127],{},"進捗ジェネレーターにも同じスキップ判定を入れ、ついでに「次に取り込む候補トップ10」を進捗ファイルの冒頭に出すよう改造した。これで朝イチで進捗ファイルを開いただけで、次に何を取り込むかが見えるようになった。Audrey Tan の本（B09MQDL4XF）は読まない判断にしたので ",[14,126,110],{}," タグでスキップ化した。",[19,129,131],{"id":130},"_1冊目バッチ-直列で待っていたら指摘された","1冊目バッチ: 直列で待っていたら指摘された",[10,133,134,135,138],{},"最初に着手したのが経営KU精鋭4冊（コンサル一年目 / イシューからはじめよ / 目的ドリブン / 仮説行動）。",[14,136,137],{},"/yomitoku-kindle"," でコンサル一年目（B00MA671WW）の撮影を始めた。117ページ・約8分で撮影が終わり、OCRをバックグラウンドに投げてOCR完了通知をひたすら待っていた。",[10,140,141],{},"ここでユーザーから指摘が入った。",[143,144,145],"blockquote",{},[10,146,147],{},"非同期的にやってもらいたいんですけど、OCR待ってる間、例えばスクリーンショットのプロセス、次のやつ進められたりするじゃないですか。てかそれ、スラッシュコマンドに書いてませんでしたっけ？",[10,149,150,152],{},[14,151,137],{}," のスラッシュコマンドの Step 16 を読み返したら「バッチ実行中なら次の本の撮影／OCR／DB投入に進む」と書いてあった。仕様としては並列を想定していたのに、自分が単発実行の頭のまま直列でブロックしていた。",[10,154,155],{},"並列に組み替えた。1冊目のOCRが走っている間に2冊目（イシュー）のスクショを別ウィンドウで開始。1冊目のDB投入と紐付け（90チャンク → kindle_library + amazon_metadata）が終わった時点で、restructure はサブエージェントに非同期で投げた。restructure は数分かかる目次整形タスクなので、メインのスレッドはそのまま3冊目（目的ドリブン）の撮影に進める。",[157,158,159,181],"table",{},[160,161,162],"thead",{},[163,164,165,169,172,175,178],"tr",{},[166,167,168],"th",{},"本",[166,170,171],{},"スクショ",[166,173,174],{},"OCR",[166,176,177],{},"DB投入",[166,179,180],{},"restructure",[182,183,184,201,217,231],"tbody",{},[163,185,186,190,193,195,198],{},[187,188,189],"td",{},"コンサル一年目（117p）",[187,191,192],{},"完了",[187,194,192],{},[187,196,197],{},"90チャンク",[187,199,200],{},"サブエージェントへ",[163,202,203,206,209,212,215],{},[187,204,205],{},"イシュー（195p）",[187,207,208],{},"並行",[187,210,211],{},"順次",[187,213,214],{},"134チャンク",[187,216,200],{},[163,218,219,222,224,226,229],{},[187,220,221],{},"目的ドリブン（269p）",[187,223,208],{},[187,225,211],{},[187,227,228],{},"217チャンク",[187,230,200],{},[163,232,233,236,238,240,243],{},[187,234,235],{},"仮説行動（208p）",[187,237,208],{},[187,239,211],{},[187,241,242],{},"—",[187,244,242],{},[10,246,247],{},"この構成にしたら、撮影律速の本（200ページ前後で約8分）の間にOCR（3〜5分）と restructure（サブエージェントに投げきり）が裏で進む。1冊あたりのウォールクロックが2倍くらい縮んだ感覚があった。",[19,249,250],{"id":250},"午後の2冊目バッチで方向誤判定を踏んだ",[10,252,253],{},"午後は不動産投資2冊（B0CV4SLXBG / B00GX1Q0YU）＋ DD論（B07F1189D3）＋仮説行動（B0DF1TPKVQ）の4冊。",[10,255,256,257,260],{},"1冊目 B0CV4SLXBG は方向 ",[14,258,259],{},"auto"," で開始して問題なく通った。72チャンク格納してFTSも全クエリヒット、restructure サブエージェントを起動。並行で2冊目 B00GX1Q0YU の撮影を開始した。",[10,262,263],{},"問題は2冊目のOCR完了直後。p.1の画像を確認したら奥付が映っていた。方向判定が逆転していた。",[44,265,270],{"className":266,"code":268,"language":269},[267],"language-text","撮影方向: ltr で開始\n実体: 和書（rtl）\n結果: p.1 が奥付・p.118 が表紙\n","text",[14,271,268],{"__ignoreMap":49},[10,273,274],{},"ここはDB投入前のリカバリだったので、画像ファイルの並び順を反転 → md再生成 → OCR再実行で済んだ。再実行後の p.1 は表紙になり、紐付けまで通って94チャンク格納。restructure サブエージェントに投げて50セクションに整形された。",[10,276,277],{},"DB投入後だと restructure までやり直す必要があるので、p.1の方向判定はOCR完了直後の必須チェックとして体に刻まれた。",[19,279,281],{"id":280},"chrome-の-tabs-edit-エラーを2回踏んだ","Chrome の Tabs edit エラーを2回踏んだ",[10,283,284,285,288],{},"3冊目 B07F1189D3（DD論）の撮影が45枚で ",[14,286,287],{},"error / Tabs cannot be edited right now"," で中断した。Chrome 側の干渉エラーで、Chrome 拡張がタブを編集しようとした瞬間に拒否された。タブを閉じて新規タブで開き直し、rtl で再開した。",[10,290,291],{},"そのまま続けると、また同じエラーで2枚で停止した。2回目で初めて画面をよく見たら、Kindle Cloud Reader のダイアログ「Most Recent Page Read」が出ていた。前回の読了位置に飛ぶか聞いてくるダイアログで、これが開いているとタブ操作が阻害される。ダイアログを閉じてから rtl で再開したら、最後まで撮影が通った。138枚撮影完了。",[10,293,294],{},"学びとして残したいのは、Chrome 拡張のタブ操作系エラーは「Chrome 全体の状態」ではなくて「ページ上に開いているダイアログ」で再現することが多い、ということ。次に同じエラーが出たら、Chrome を再起動する前に Cloud Reader のダイアログを疑う。",[19,296,297],{"id":297},"バッチ完了と進捗",[10,299,300],{},"午前4冊＋午後4冊で計8冊を取り込み、進捗は取込済 11冊 → 17冊、KU借中 19冊 → 15冊残まで進んだ。各書籍は撮影約8分・OCR約3〜5分・DB投入とrestructureは並行で消化、というリズムで回った。",[10,302,303],{},"今回の構成で固まったパイプラインは次の形になった。",[305,306,307,311,314],"ol",{},[308,309,310],"li",{},"メインスレッド: 撮影 → OCR起動 → DB投入 → 紐付け → 次の本の撮影開始",[308,312,313],{},"サブエージェント: restructure（目次整形・セクション統合）を非同期で消化",[308,315,316],{},"進捗ジェネレーター: 冒頭に並列処理ルールと次の取込候補トップ10を出す",[10,318,319],{},"書籍取込はOCR・DB投入・restructure それぞれが別の I/O 待ちを持つので、サブエージェント並列の効きが分かりやすい。直列で寝かしていた時間が、別の本の撮影で埋まる構図にできた。",[19,321,322],{"id":322},"明日に持ち越したこと",[324,325,328,338,344],"ul",{"className":326},[327],"contains-task-list",[308,329,332,337],{"className":330},[331],"task-list-item",[333,334],"input",{"disabled":335,"type":336},true,"checkbox"," KU借中の残り15冊を、撮影律速で消化していく",[308,339,341,343],{"className":340},[331],[333,342],{"disabled":335,"type":336}," 方向判定はOCR完了直後の p.1 チェックを毎回回す（DB投入後だと restructure までやり直し）",[308,345,347,349,350,352],{"className":346},[331],[333,348],{"disabled":335,"type":336}," Chrome の ",[14,351,16],{}," が出たら、まず Cloud Reader のダイアログを疑う",[354,355,356],"style",{},"html pre.shiki code .sxvE3, html code.shiki .sxvE3{--shiki-default:#A0ADA0;--shiki-dark:#A0ADA0}html pre.shiki code .snbK4, html code.shiki .snbK4{--shiki-default:#A65E2B;--shiki-dark:#A65E2B}html pre.shiki code .shFtX, html code.shiki .shFtX{--shiki-default:#999999;--shiki-dark:#999999}html pre.shiki code .sMJiu, html code.shiki .sMJiu{--shiki-default:#B5695977;--shiki-dark:#B5695977}html pre.shiki code .sdGka, html code.shiki .sdGka{--shiki-default:#B56959;--shiki-dark:#B56959}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":49,"searchDepth":63,"depth":63,"links":358},[359,360,361,362,363,364],{"id":21,"depth":63,"text":21},{"id":130,"depth":63,"text":131},{"id":250,"depth":63,"text":250},{"id":280,"depth":63,"text":281},{"id":297,"depth":63,"text":297},{"id":322,"depth":63,"text":322},"dev","小説・描き方シリーズの除外タグを整備しつつ、Kindleのスクショ／OCR／DB投入／restructureを並列に組み替えて1日で8冊取り込んだ。方向誤判定とTabs editエラーを2回踏みながらリカバリした記録。","md",{},null,"/kindle-import-8books-parallel-pipeline","book-knowledge-base",false,"2026-06-21T00:00:00.000Z",{"title":5,"description":366},"2026-06/2026-06-21/kindle-import-8books-parallel-pipeline",[377,174,378,379,380,381],"Kindle","yomitoku","Turso","並列パイプライン","サブエージェント","JAU4KSTe0EYiI1oL-9SaR1Uc8v3x-URyPvHN0AUffog",[],"https://log.eurekapu.com/og/blog/kindle-import-8books-parallel-pipeline.png?v=2026-06-21T00%3A00%3A00.000Z&title=Kindle%E5%8F%96%E8%BE%BC%E3%83%91%E3%82%A4%E3%83%97%E3%83%A9%E3%82%A4%E3%83%B3%E3%82%92%E4%B8%A6%E5%88%97%E5%8C%96%E3%81%97%E3%81%A61%E6%97%A5%E3%81%AB8%E5%86%8A%E5%8F%96%E3%82%8A%E8%BE%BC%E3%82%93%E3%81%A0&author=Kei%20Komatsu&sig=e69562c870e41069",1782176332551]