[{"data":1,"prerenderedAt":849},["ShallowReactive",2],{"content-/book-ocr-turso-knowledge-base":3,"all-pages-for-dir":847,"og-image-/book-ocr-turso-knowledge-base":848},{"id":4,"title":5,"body":6,"category":830,"description":831,"extension":832,"meta":833,"navigation":217,"ogImage":834,"path":835,"project_name":836,"published":837,"publishedAt":838,"seo":839,"stem":840,"tags":841,"todo":834,"unpublished":837,"updatedAt":834,"__hash__":846},"pages/2026-05/2026-05-02/book-ocr-turso-knowledge-base.md","yomitokuで会計書籍3冊をOCR→Turso DBへ蔵書知識ベース化（再OCR・章再構造化・shelf改善まで）",{"type":7,"value":8,"toc":816},"minimark",[9,13,25,30,38,48,59,63,70,76,83,87,97,100,178,188,192,201,204,244,251,255,269,275,281,285,291,396,402,406,413,510,517,521,527,560,565,569,574,581,587,689,692,696,705,712,719,730,737,740,775,778,812],[10,11,5],"h1",{"id":12},"yomitokuで会計書籍3冊をocrturso-dbへ蔵書知識ベース化再ocr章再構造化shelf改善まで",[14,15,16,17,21,22,24],"p",{},"book-knowledge-base リポジトリで、会計書籍3冊を yomitoku でOCRして Turso DB に格納し、章節整理（restructure）と ",[18,19,20],"code",{},"/shelf"," のUI改善まで一通り通した。途中で WAL 書込衝突によるレプリカ詰まり、WebFetch の連続失敗、サイドバー表記の見にくさ、ケース境界での前ケース末尾混入、と4種類の壁にぶつかったが、それぞれ別アプローチで解決した。1日の終わりには ",[18,23,20],{}," に「📖 DB」「済」バッジと星評価4.3(39件)、Amazonリンクが揃って表示されるところまで持っていった。",[26,27,29],"h2",{"id":28},"_1冊目-参考書228ページを35分で完走no866","1冊目: 参考書228ページを3.5分で完走（No866）",[14,31,32,33,37],{},"朝イチで小さめの参考書（228ページ）を yomitoku の GPU 逐次処理で流した。ScheduleWakeup でPCがスリープしないようにキープして、Monitor で進捗ログを横目に見ながら別作業をしていたら、",[34,35,36],"strong",{},"3分30秒で OCR が完了","した。1ページあたり1秒切るペース。",[39,40,45],"pre",{"className":41,"code":43,"language":44},[42],"language-text","[完了] No866 228p / 図74件 / 188チャンク登録\n","text",[18,46,43],{"__ignoreMap":47},"",[14,49,50,51,54,55,58],{},"図ファイル74件をリネームして ",[18,52,53],{},"yomitoku_import.py"," に通し、188チャンクが Turso に入った。チャンク数がページ数より少ないのは、",[34,56,57],{},"目次・奥付・空白ページなどでチャンクがマージされた","ため。FTS で適当な見出しを引いてヒットすることを確認して、1冊目はあっさり完了した。",[26,60,62],{"id":61},"_2冊目-消費税の参考書624ページno865","2冊目: 消費税の参考書624ページ（No865）",[14,64,65,66,69],{},"そのまま2冊目に入った。消費税系の専門書で624ページ。yomitokuの所要時間を1.5倍くらい見積もっていたが、ページ単位の図が多く OCR が重め。Monitor で進捗を見ていたら、",[34,67,68],{},"1093ファイル出力・454図","まで膨らんだ。",[39,71,74],{"className":72,"code":73,"language":44},[42],"[完了] No865 624p / 1093ファイル / 454図 / 585チャンク登録\n",[18,75,73],{"__ignoreMap":47},[14,77,78,79,82],{},"585チャンクを Turso に格納。",[18,80,81],{},"/restructure-book"," を流す前に書籍メタデータ（書影URL、星評価、レビュー数、Amazonリンク）を埋める必要があるが、ここで Amazon 取得が止まった。",[26,84,86],{"id":85},"webfetch連続失敗-agent-browser-フォールバック","WebFetch連続失敗 → agent-browser フォールバック",[14,88,89,92,93,96],{},[18,90,91],{},"amazon_metadata"," テーブルに格納するため、WebFetch で Amazon の書誌ページを取りに行ったら ",[34,94,95],{},"連続でブロック","を食らった。SSL 系のエラーかボット対策かは判別しなかったが、リトライしても通らない。",[14,98,99],{},"グローバルCLAUDE.mdに「WebFetchが失敗したら即座に agent-browser にフォールバックすること」と書いてあったのを思い出して、そのまま切り替えた。",[39,101,105],{"className":102,"code":103,"language":104,"meta":47,"style":47},"language-bash shiki shiki-themes vitesse-light vitesse-light","agent-browser open \"https://www.amazon.co.jp/dp/...\" \\\n  && agent-browser wait --load networkidle\nagent-browser eval 'document.body.innerText'\nagent-browser close\n","bash",[18,106,107,134,153,170],{"__ignoreMap":47},[108,109,112,116,120,124,127,130],"span",{"class":110,"line":111},"line",1,[108,113,115],{"class":114},"senZ8","agent-browser",[108,117,119],{"class":118},"sdGka"," open",[108,121,123],{"class":122},"sMJiu"," \"",[108,125,126],{"class":118},"https://www.amazon.co.jp/dp/...",[108,128,129],{"class":122},"\"",[108,131,133],{"class":132},"snbK4"," \\\n",[108,135,137,141,144,147,150],{"class":110,"line":136},2,[108,138,140],{"class":139},"shFtX","  &&",[108,142,143],{"class":114}," agent-browser",[108,145,146],{"class":118}," wait",[108,148,149],{"class":132}," --load",[108,151,152],{"class":118}," networkidle\n",[108,154,156,158,161,164,167],{"class":110,"line":155},3,[108,157,115],{"class":114},[108,159,160],{"class":118}," eval",[108,162,163],{"class":122}," '",[108,165,166],{"class":118},"document.body.innerText",[108,168,169],{"class":122},"'\n",[108,171,173,175],{"class":110,"line":172},4,[108,174,115],{"class":114},[108,176,177],{"class":118}," close\n",[14,179,180,181,184,185,187],{},"ユーザーのChromeプロファイルを使うので ",[34,182,183],{},"1回でメタデータが取れた","。星評価4.3、レビュー39件、書影URL、著者名、出版社情報がそのまま抜けた。",[18,186,20],{}," のカード表示に必要なフィールドが一式埋まった。",[26,189,191],{"id":190},"wal書込衝突-http直接接続にリトライ","WAL書込衝突 → HTTP直接接続にリトライ",[14,193,194,196,197,200],{},[18,195,81],{}," を Embedded Replica 経由で流したら、",[34,198,199],{},"WAL ファイルがロックされたまま開放されない","事象が起きた。前のセッションで残っていた Python subprocess が WAL を握っていたらしく、新しいトランザクションが書き込めない。",[14,202,203],{},"復旧手順：",[205,206,209,228,238],"ul",{"className":207},[208],"contains-task-list",[210,211,214,219,220,223,224,227],"li",{"className":212},[213],"task-list-item",[215,216],"input",{"checked":217,"disabled":217,"type":218},true,"checkbox"," ",[18,221,222],{},"data/replica/*.db-wal"," と ",[18,225,226],{},"*.db-shm"," を一旦退避",[210,229,231,233,234,237],{"className":230},[213],[215,232],{"checked":217,"disabled":217,"type":218}," レプリカファイルを削除して再構築（",[18,235,236],{},"syncUrl"," から fresh sync）",[210,239,241,243],{"className":240},[213],[215,242],{"checked":217,"disabled":217,"type":218}," HTTP 直接接続版の restructure に書き換えて再実行",[14,245,246,247,250],{},"Embedded Replica は読み取りキャッシュとしては効くが、書き込みが詰まると復旧コストが大きい。",[34,248,249],{},"書き込みは HTTP 直接接続で叩く","運用に倒すことにした。前日（4-30）の TAC テキスト一括取り込みで同じ判断をしていたので、スクリプト側のテンプレートはそのまま流用できた。",[26,252,254],{"id":253},"restructure-305チャンク-126セクション","restructure: 305チャンク → 126セクション",[14,256,257,258,260,261,264,265,268],{},"並行で動かしていた3冊目（過去に上下分割マージを失敗した参考書、再OCR完了済み）の ",[18,259,81],{}," を回した。元は ",[34,262,263],{},"305チャンク","でページ単位に切れていたが、ケース毎・章扉・コラム単位でセクションを再定義して ",[34,266,267],{},"126セクションに統合","した。",[39,270,273],{"className":271,"code":272,"language":44},[42],"[restructure] 305 chunks → 126 sections\n  - ケース本体: 100セクション（ケース1〜100）\n  - 章扉: 10セクション\n  - コラム: 16セクション\n",[18,274,272],{"__ignoreMap":47},[14,276,277,280],{},[34,278,279],{},"ケース毎に独立したセクション","にしたかったので、目次から拾った「ケース1」「ケース2」…の見出しをセクション境界に置いた。章扉とコラムも独立セクションに切り出して、検索結果がケース単位で返ってくる粒度にした。",[26,282,284],{"id":283},"http直書きの-amazon_metadata-がローカル-embedded-replica-から読めるか","HTTP直書きの amazon_metadata がローカル Embedded Replica から読めるか",[14,286,287,288,290],{},"restructure と並行で書き込んだ ",[18,289,91],{}," レコードが、ローカルの Embedded Replica から正しく読めるか確認した。HTTP直接接続で書き込むと、Embedded Replica は次回 sync まで古い状態のままになるリスクがある。",[39,292,296],{"className":293,"code":294,"language":295,"meta":47,"style":47},"language-ts shiki shiki-themes vitesse-light vitesse-light","// HTTP 直書き直後にローカルレプリカで読む\nawait client.sync()\nconst { rows } = await client.execute({\n  sql: 'SELECT * FROM amazon_metadata WHERE file_no = ?',\n  args: [866],\n})\n","ts",[18,297,298,304,323,354,374,390],{"__ignoreMap":47},[108,299,300],{"class":110,"line":111},[108,301,303],{"class":302},"sxvE3","// HTTP 直書き直後にローカルレプリカで読む\n",[108,305,306,310,314,317,320],{"class":110,"line":136},[108,307,309],{"class":308},"sHkkW","await",[108,311,313],{"class":312},"s4oTP"," client",[108,315,316],{"class":139},".",[108,318,319],{"class":114},"sync",[108,321,322],{"class":139},"()\n",[108,324,325,329,332,335,338,341,344,346,348,351],{"class":110,"line":155},[108,326,328],{"class":327},"stQ0i","const ",[108,330,331],{"class":139},"{",[108,333,334],{"class":312}," rows",[108,336,337],{"class":139}," }",[108,339,340],{"class":139}," =",[108,342,343],{"class":308}," await",[108,345,313],{"class":312},[108,347,316],{"class":139},[108,349,350],{"class":114},"execute",[108,352,353],{"class":139},"({\n",[108,355,356,360,363,366,369,371],{"class":110,"line":172},[108,357,359],{"class":358},"sz8Xr","  sql",[108,361,362],{"class":139},": ",[108,364,365],{"class":122},"'",[108,367,368],{"class":118},"SELECT * FROM amazon_metadata WHERE file_no = ?",[108,370,365],{"class":122},[108,372,373],{"class":139},",\n",[108,375,377,380,383,387],{"class":110,"line":376},5,[108,378,379],{"class":358},"  args",[108,381,382],{"class":139},": [",[108,384,386],{"class":385},"sM54T","866",[108,388,389],{"class":139},"],\n",[108,391,393],{"class":110,"line":392},6,[108,394,395],{"class":139},"})\n",[14,397,398,401],{},[18,399,400],{},"client.sync()"," を明示的に挟めば、ローカルから新規レコードが読めることを確認した。同期OK。",[26,403,405],{"id":404},"古い書籍データの一括削除no344","古い書籍データの一括削除（No344）",[14,407,408,409,412],{},"3冊目の再OCR が成功したので、",[34,410,411],{},"古いほうのレコードを丸ごと削除","することにした。chunks 180件 / books 1件 / amazon_metadata 1件（file_no=257）が紐づいていたので、トランザクションで一括削除。",[39,414,418],{"className":415,"code":416,"language":417,"meta":47,"style":47},"language-sql shiki shiki-themes vitesse-light vitesse-light","BEGIN;\nDELETE FROM chunks WHERE book_id = 'no344-...';\nDELETE FROM amazon_metadata WHERE file_no = 257;\nDELETE FROM books WHERE id = 'no344-...';\nCOMMIT;\n","sql",[18,419,420,429,458,479,503],{"__ignoreMap":47},[108,421,422,425],{"class":110,"line":111},[108,423,424],{"class":308},"BEGIN",[108,426,428],{"class":427},"sG7-3",";\n",[108,430,431,434,437,440,443,446,449,451,454,456],{"class":110,"line":136},[108,432,433],{"class":308},"DELETE",[108,435,436],{"class":308}," FROM",[108,438,439],{"class":427}," chunks ",[108,441,442],{"class":308},"WHERE",[108,444,445],{"class":427}," book_id ",[108,447,448],{"class":327},"=",[108,450,163],{"class":122},[108,452,453],{"class":118},"no344-...",[108,455,365],{"class":122},[108,457,428],{"class":427},[108,459,460,462,464,467,469,472,474,477],{"class":110,"line":155},[108,461,433],{"class":308},[108,463,436],{"class":308},[108,465,466],{"class":427}," amazon_metadata ",[108,468,442],{"class":308},[108,470,471],{"class":427}," file_no ",[108,473,448],{"class":327},[108,475,476],{"class":385}," 257",[108,478,428],{"class":427},[108,480,481,483,485,488,490,493,495,497,499,501],{"class":110,"line":172},[108,482,433],{"class":308},[108,484,436],{"class":308},[108,486,487],{"class":427}," books ",[108,489,442],{"class":308},[108,491,492],{"class":427}," id ",[108,494,448],{"class":327},[108,496,163],{"class":122},[108,498,453],{"class":118},[108,500,365],{"class":122},[108,502,428],{"class":427},[108,504,505,508],{"class":110,"line":376},[108,506,507],{"class":308},"COMMIT",[108,509,428],{"class":427},[14,511,512,513,516],{},"新しい再OCR版（chunks 305 → restructure 後126セクション）で置き換える形になる。",[18,514,515],{},"file_no"," が変わるので、Amazonメタデータ側も新しい file_no で取り直した。",[26,518,520],{"id":519},"shelf-画面で表示確認","/shelf 画面で表示確認",[14,522,523,524,526],{},"3冊全部のDB登録が終わったので、",[18,525,20],{}," を Chrome で開いて表示を確認した。",[205,528,530,536,542,548,554],{"className":529},[208],[210,531,533,535],{"className":532},[213],[215,534],{"checked":217,"disabled":217,"type":218}," 書影が3冊とも表示されている",[210,537,539,541],{"className":538},[213],[215,540],{"checked":217,"disabled":217,"type":218}," 「📖 DB」バッジ（青）が3冊に出ている",[210,543,545,547],{"className":544},[213],[215,546],{"checked":217,"disabled":217,"type":218}," 「済」バッジ（緑）も3冊揃って出ている",[210,549,551,553],{"className":550},[213],[215,552],{"checked":217,"disabled":217,"type":218}," 星評価 ★4.3 (39件) が表示されている",[210,555,557,559],{"className":556},[213],[215,558],{"checked":217,"disabled":217,"type":218}," Amazonリンクをクリックして商品ページに飛ぶ",[14,561,562,564],{},[18,563,20],{}," の見た目はバッジが揃って気持ちよかった。前日に追加した「📖 DB」「済」のバッジ並びがそのまま効いている。",[26,566,568],{"id":567},"ユーザー指摘-サイドバーのページタイトルがわかりづらい","ユーザー指摘: サイドバーのページタイトルがわかりづらい",[14,570,571,573],{},[18,572,20],{}," から書籍ページに飛んで、サイドバーの目次を見たユーザーから「これ、章のタイトルしか出てなくてどのケースか分からない」と指摘が来た。",[14,575,576,577,580],{},"確認すると、サイドバーは ",[34,578,579],{},"章タイトルを大見出し","として並べていて、その下に節タイトル（=ケース番号）が小さく出ているだけだった。ユーザーが探しているのは「ケース23: 〇〇」のようなケース名なのに、視覚的には章タイトルが目立っていた。",[14,582,583,584,268],{},"優先順位を逆にした。",[34,585,586],{},"ケース名（section）を主役にして、章はグループヘッダーに格下げ",[39,588,592],{"className":589,"code":590,"language":591,"meta":47,"style":47},"language-vue shiki shiki-themes vitesse-light vitesse-light","\u003C!-- 修正後: ケース名が主役、章はグループヘッダー -->\n\u003Cdiv v-for=\"chapter in chapters\" :key=\"chapter.id\">\n  \u003Ch3 class=\"chapter-header\">{{ chapter.title }}\u003C/h3>\n  \u003Cul>\n    \u003Cli v-for=\"section in chapter.sections\" :key=\"section.id\">\n      \u003Ca :href=\"section.path\">{{ section.title }}\u003C/a>\n    \u003C/li>\n  \u003C/ul>\n\u003C/div>\n","vue",[18,593,594,599,647,652,657,662,667,673,679],{"__ignoreMap":47},[108,595,596],{"class":110,"line":111},[108,597,598],{"class":302},"\u003C!-- 修正後: ケース名が主役、章はグループヘッダー -->\n",[108,600,601,604,607,610,612,614,617,620,623,625,628,631,633,635,637,639,642,644],{"class":110,"line":136},[108,602,603],{"class":139},"\u003C",[108,605,606],{"class":308},"div",[108,608,609],{"class":308}," v-for",[108,611,448],{"class":139},[108,613,129],{"class":139},[108,615,616],{"class":312},"chapter",[108,618,619],{"class":327}," in",[108,621,622],{"class":312}," chapters",[108,624,129],{"class":139},[108,626,627],{"class":139}," :",[108,629,630],{"class":114},"key",[108,632,448],{"class":139},[108,634,129],{"class":139},[108,636,616],{"class":312},[108,638,316],{"class":139},[108,640,641],{"class":312},"id",[108,643,129],{"class":139},[108,645,646],{"class":139},">\n",[108,648,649],{"class":110,"line":155},[108,650,651],{"class":427},"  \u003Ch3 class=\"chapter-header\">{{ chapter.title }}\u003C/h3>\n",[108,653,654],{"class":110,"line":172},[108,655,656],{"class":427},"  \u003Cul>\n",[108,658,659],{"class":110,"line":376},[108,660,661],{"class":427},"    \u003Cli v-for=\"section in chapter.sections\" :key=\"section.id\">\n",[108,663,664],{"class":110,"line":392},[108,665,666],{"class":427},"      \u003Ca :href=\"section.path\">{{ section.title }}\u003C/a>\n",[108,668,670],{"class":110,"line":669},7,[108,671,672],{"class":427},"    \u003C/li>\n",[108,674,676],{"class":110,"line":675},8,[108,677,678],{"class":427},"  \u003C/ul>\n",[108,680,682,685,687],{"class":110,"line":681},9,[108,683,684],{"class":139},"\u003C/",[108,686,606],{"class":308},[108,688,646],{"class":139},[14,690,691],{},"サイドバーをスクロールしたとき、目に飛び込んでくるのが「ケース23: 〇〇」になり、章タイトルは薄いグレーのグループヘッダーになった。ユーザー確認OK。",[26,693,695],{"id":694},"ケース8の境界チャンク混入-サブエージェントで一括クリーンアップ","ケース8の境界チャンク混入 → サブエージェントで一括クリーンアップ",[14,697,698,700,701,704],{},[18,699,20],{}," から飛んだケース8のページを開いたら、",[34,702,703],{},"冒頭にケース7末尾のテキストが混じっていた","。restructure でセクション境界を切ったときに、ケース7→ケース8の境界ページがケース8側に寄っていたが、そのページの上半分はケース7の続きだった。",[14,706,707,708,711],{},"「ケース8だけだろう」と思ってよく見たら、",[34,709,710],{},"他のケースでも同じパターンが出る可能性","があった。境界ページが両ケースにまたがっているケースは構造上どこでも起こりうる。",[14,713,714,715,718],{},"サブエージェントを起動して、全100ケースの先頭500文字を読み、",[34,716,717],{},"前ケース末尾と判断できる段落を一括で削除","するタスクを投げた。判定基準は：",[205,720,721,724,727],{},[210,722,723],{},"段落の終わりに「次のケースで詳述する」「→ケースX参照」のような送り表現があれば前ケース末尾",[210,725,726],{},"ケース番号の見出しより前にある本文は前ケース末尾と判断",[210,728,729],{},"ケース冒頭の見出し直後に「事例の概要」「論点」のような節があれば、それ以前は削除",[14,731,732,733,736],{},"サブエージェントが100ケース分を直列で処理して、",[34,734,735],{},"境界混入があったケースが14件","見つかった。チャンク内容を更新する SQL を生成させて、HTTP 直接接続でまとめて UPDATE。修正後、ケース8のページを開き直したら、冒頭が「ケース8: 〇〇」の見出しから始まっていた。",[26,738,739],{"id":739},"学び",[205,741,742,748,754,763,769],{},[210,743,744,747],{},[34,745,746],{},"WebFetch失敗時は即 agent-browser",": SSL/ボット対策で WebFetch がブロックされたら、悩まず agent-browser に切り替えるのが早い。Chromeプロファイルを使うので Amazon みたいな認証/対策のあるサイトでも通る",[210,749,750,753],{},[34,751,752],{},"書き込みは HTTP 直接接続、読み取りは Embedded Replica",": WAL ロック詰まりからの復旧コストが大きいので、書き込み系の処理は最初から HTTP 直接接続で叩く。読み取りキャッシュとしての Embedded Replica は維持しつつ、書き込みパスだけ別に切る",[210,755,756,762],{},[34,757,758,759,761],{},"HTTP直書き後は ",[18,760,400],{}," を明示",": HTTP直書きしたデータをローカルから読むなら、sync を明示的に呼ばないと古いキャッシュが返る。書いたら同期、を癖にする",[210,764,765,768],{},[34,766,767],{},"サイドバーは「ユーザーが探している単位」を主役にする",": 章/節のような階層構造があるとき、視覚的に目立つのは「ユーザーが探している粒度」であるべき。今回のケースでは章ではなくケースが探索対象だった",[210,770,771,774],{},[34,772,773],{},"境界ページの混入はサブエージェントで一括判定",": 100ケース分を目視確認するのは現実的ではない。判定基準を明文化してサブエージェントに投げれば、構造的な誤りを一気に潰せる",[26,776,777],{"id":777},"次にやりたいこと",[205,779,781,787,793,802],{"className":780},[208],[210,782,784,786],{"className":783},[213],[215,785],{"disabled":217,"type":218}," 残りの会計書籍（税効果会計、組織再編実務）を順次 yomitoku→Turso→restructure に流す",[210,788,790,792],{"className":789},[213],[215,791],{"disabled":217,"type":218}," サイドバーの「ケース名主役・章はグループヘッダー」パターンを他の問答形式書籍にも展開する",[210,794,796,798,799,801],{"className":795},[213],[215,797],{"disabled":217,"type":218}," 境界チャンク混入の自動検出スクリプトを ",[18,800,81],{}," の検証ステップに組み込む（restructure 直後に全セクション先頭500文字を機械チェック）",[210,803,805,807,808,811],{"className":804},[213],[215,806],{"disabled":217,"type":218}," WebFetch失敗→agent-browser フォールバックを ",[18,809,810],{},"amazon_metadata.py"," のリトライロジックに組み込む",[813,814,815],"style",{},"html pre.shiki code .senZ8, html code.shiki .senZ8{--shiki-default:#59873A;--shiki-dark:#59873A}html pre.shiki code .sdGka, html code.shiki .sdGka{--shiki-default:#B56959;--shiki-dark:#B56959}html pre.shiki code .sMJiu, html code.shiki .sMJiu{--shiki-default:#B5695977;--shiki-dark:#B5695977}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 .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);}html pre.shiki code .sxvE3, html code.shiki .sxvE3{--shiki-default:#A0ADA0;--shiki-dark:#A0ADA0}html pre.shiki code .sHkkW, html code.shiki .sHkkW{--shiki-default:#1E754F;--shiki-dark:#1E754F}html pre.shiki code .s4oTP, html code.shiki .s4oTP{--shiki-default:#B07D48;--shiki-dark:#B07D48}html pre.shiki code .stQ0i, html code.shiki .stQ0i{--shiki-default:#AB5959;--shiki-dark:#AB5959}html pre.shiki code .sz8Xr, html code.shiki .sz8Xr{--shiki-default:#998418;--shiki-dark:#998418}html pre.shiki code .sM54T, html code.shiki .sM54T{--shiki-default:#2F798A;--shiki-dark:#2F798A}html pre.shiki code .sG7-3, html code.shiki .sG7-3{--shiki-default:#393A34;--shiki-dark:#393A34}",{"title":47,"searchDepth":136,"depth":136,"links":817},[818,819,820,821,822,823,824,825,826,827,828,829],{"id":28,"depth":136,"text":29},{"id":61,"depth":136,"text":62},{"id":85,"depth":136,"text":86},{"id":190,"depth":136,"text":191},{"id":253,"depth":136,"text":254},{"id":283,"depth":136,"text":284},{"id":404,"depth":136,"text":405},{"id":519,"depth":136,"text":520},{"id":567,"depth":136,"text":568},{"id":694,"depth":136,"text":695},{"id":739,"depth":136,"text":739},{"id":777,"depth":136,"text":777},"dev","yomitokuで会計書籍2冊（228p / 624p）を Markdown 化して Turso DB に格納。並行で過去に上下分割マージを失敗した参考書（312p）を再OCRし直し、305チャンクを126セクションへ統合。WAL書込衝突→HTTP直接接続、WebFetch連続失敗→agent-browser、サイドバー章/ケース表記の優先順位修正、ケース境界の前ケース末尾混入をサブエージェント一括クリーンアップで処理。","md",{},null,"/book-ocr-turso-knowledge-base","book-knowledge-base",false,"2026-05-02T00:00:00.000Z",{"title":5,"description":831},"2026-05/2026-05-02/book-ocr-turso-knowledge-base",[842,843,844,845,115],"yomitoku","TursoDB","書籍デジタル化","Embedded Replica","UmXq-hb5jkNObyRBhSs6OYNAW7WtZrOACShIywZJ9u0",[],"https://log.eurekapu.com/og/blog/book-ocr-turso-knowledge-base.png?v=2026-05-02T00%3A00%3A00.000Z&title=yomitoku%E3%81%A7%E4%BC%9A%E8%A8%88%E6%9B%B8%E7%B1%8D3%E5%86%8A%E3%82%92OCR%E2%86%92Turso%20DB%E3%81%B8%E8%94%B5%E6%9B%B8%E7%9F%A5%E8%AD%98%E3%83%99%E3%83%BC%E3%82%B9%E5%8C%96%EF%BC%88%E5%86%8DOCR%E3%83%BB%E7%AB%A0%E5%86%8D%E6%A7%8B%E9%80%A0%E5%8C%96%E3%83%BBshelf%E6%94%B9%E5%96%84%E3%81%BE%E3%81%A7%EF%BC%89&author=Kei%20Komatsu&sig=9aafc84c4334d30f",1782528831651]