問い合わせ記録のCSVを受け取って取り込んだら、120件のはずが148件になっていた。中身を見ると、1件の記録が途中で切れて次の行に続いている。対応内容の欄に入った改行が、どうやら行の区切りとして扱われているらしい。
このファイルをそのままAIに渡したところ、原因を突き止めて、120件に直したCSVを書き出してくれました。修復用のスクリプトまで付けてきます。
ただ、同じことを3回やってみたら、3回とも違う形の答えが返ってきました。しかも3回目は、出てきたファイルは完全に正しいのに、その説明の数字が間違っていました。この記事では、実際に3回投げた記録と、返ってきたものを自分で確かめる手順をまとめます。
使うファイル
架空の問い合わせ記録を用意しました。本来120件、7列(受付日・受付番号・顧客区分・問い合わせ種別・対応内容・対応者・状態)、文字コードはCP932(Shift_JIS系)、9,229バイトです。
壊れている箇所を抜き出します。行番号はファイルの何行目かを示しています。以下、ファイルの中で改行区切りになっている見かけの1行を「物理行」と呼びます。CSVとして読んだときの1件(レコード)とは別ものです。壊れたファイルでは、この2つがずれます。
8| 2026-06-25,R2605,個人,不具合,在庫を確認
9| 取り寄せに10日かかる旨を連絡
10| 了承いただいた,佐藤,完了
11| 2026-05-13,R2606,法人,返品交換,カタログのPDFをメールで送付,伊藤,対応中
8行目から10行目までで1件です。対応内容の「在庫を確認/取り寄せに10日かかる旨を連絡/了承いただいた」という3行の記録が、そのまま3つの物理行に分かれてしまっています。8行目は5列、9行目は1列、10行目は3列にしか見えません。
11行目は普通の1件です。壊れている行と壊れていない行が、同じファイルの中に混ざっています。
そのまま投げてみる
まず、何も考えずに投げました。ファイルを添付して、次の1行だけです。
このCSVを取り込んだら行がズレてしまいます。正しく読めるようにしてください。
文字コードのことも、列数のことも、何件あるはずかも伝えていません。返ってきたのは次のような回答でした。
「対応内容」欄の改行がダブルクォートで囲まれずに出力されていることが原因でした。
書き出し元のシステムは、カンマを含む値(
"型番A-100,A-200の両方を確認"など)はきちんとクォートしているのに、改行を含む値だけクォートし忘れているという中途半端な壊れ方をしています。そのため1件のレコードが2〜3行に分断され、CSVパーサが素直に読むと 120件のはずが149行として認識され、以降の列がすべてズレます。
末尾の149行はヘッダーを含んだ数です。データだけを数えると148行になります。
そのうえで、120件に復元したCSVと、修復用のPythonスクリプトを書き出してきました。文字コードがCP932であることも自分で判定しています。
正解データと突き合わせたところ、120件すべてが7列とも一字一句正しく復元されていました。指示していないのに、機械では判断できない3件を見つけて「ここは推測が入っている」と報告までしてきます。
1回で終わりそうな話です。ここで終わらせずに、あと2回やってみました。
そもそも何が起きていたのか
結果を見る前に、原因を整理しておきます。ここが分かると、あとの話が読みやすくなります。
データ2件だけの小さなCSVを4パターン作って、それぞれをCSVとして読ませてみました。どれも本来はヘッダー1行+データ2件=3レコードです。1行目のヘッダーは 受付番号,対応内容,状態、2件目のデータは R002,通常の記録,完了 で4パターンとも共通にしてあります。違うのは R001 の行だけです。
| R001 の行 | CSVパーサーが返したレコード数 | 結果 | |
|---|---|---|---|
| A | R001,"1行目⏎2行目",完了 |
3 | 正常 |
| B | R001,1行目⏎2行目,完了 |
4 | 1件が2行に分裂 |
| C | R001,"閉じ忘れ,完了 |
2/エラー | パーサーによって挙動が変わる |
| D | R001,"A社,B社の件",完了 |
3 | 正常 |
AとBを見比べてください。中身の文字は同じで、違いはダブルクォートで囲まれているかどうかだけです。囲まれていれば正しく読め、囲まれていなければ分裂します。
Cだけは、読ませるツールによって結果が変わりました。PowerShellの Import-Csv とPythonの標準CSV機能は、閉じ忘れた引用符から後ろを全部ひとつの値として飲み込み、2レコードとして読みます。一方 .NET の TextFieldParser は「行 2 を解析できません」というエラーで止まりました。どちらにしてもデータは正しく読めません。
つまりセル内改行そのものが悪いわけではありません。改行が入っていても、ダブルクォートで囲まれていれば何も起きません。悪いのは、囲まずに出力されていることです。
これは実務上わりと重要です。「セル内改行を禁止する」という対処はよく取られますし、改行を減らせば事故が減るのも確かです。ただしそれだけでは根本の原因に届いていません。出力側がきちんとクォートしていないままなら、カンマが入った日にまた同じことが起きます。
実際、今回のファイルにも「カンマが入っているのに正しくクォートされている行」が混ざっていました。
23| 2026-04-19,R2614,代理店,不具合,"型番A-100,A-200の両方を確認",佐藤,完了
この行は壊れていません。同じファイルの中で、クォートされている行とされていない行が混在していたわけです。
120件の内訳はこうなっていました。
| 状態 | 件数 |
|---|---|
| クォートなしの改行が入っている(分裂する) | 20 |
| クォートなしで改行とカンマの両方が入っている(分裂し、かつ復元が決まらない) | 3 |
| 正しくクォートされた改行が入っている(壊れない) | 10 |
| 正しくクォートされたカンマが入っている(壊れない) | 8 |
| 改行もカンマもない | 79 |
| 計 | 120 |
分裂したのは23件です。うち18件が2つの物理行に、5件が3つの物理行に分かれました。18×1 + 5×2 = 28行ぶん余計に増えて、120件が148件として読まれます。
3回やってみた
1回目は上の素朴な1行。2回目と3回目は、扱い方を細かく指定した同じ指示文を使いました(全文は後で載せます)。3回とも、前の回のことを知らない状態で実行しています。
| 1回目 | 2回目 | 3回目(2回目と同じ指示) | |
|---|---|---|---|
| 本体CSVの件数 | 120 | 117 | 120 |
| 正解との一致 | 120/120 | 117/117 | 120/120 |
| 失われた記録 | なし | なし | なし |
| 「要確認」とした件数 | 3 | 3 | 7 |
| 出力ファイル数 | 4 | 4 | 6 |
| スクリプトの行数 | 175 | 206 | 309 |
3回とも正しく直りました。そして3回とも形が違いました。
2回目だけ117件なのは、判断できない3件を本体から外して別ファイルに分けたからです。1回目と3回目は同じ3件を本体に含めたうえで「ここは推測です」と報告しました。どちらも指示に反していません。指示には「別表で一覧にしてください」とは書きましたが、「本体に入れるか外すか」までは書いていなかったからです。
2回目と3回目は一字一句同じ指示文です。それでも件数も要確認の範囲もスクリプトの長さも違いました。
実務上、これは無視できません。2回目の本体CSVだけを見て作業を進めると3件足りません。1回目と3回目は、末尾の注記を読まないと推測を含む行が本体に混ざっていることに気づけません。
説明の数字が間違っていた
3回目の回答に、次の説明がありました。
- 2行に分断:20件(改行のクォート漏れ×1)
- 3行に分断:5件(改行のクォート漏れ×2)
- カンマ+改行のクォート漏れ:3件(旧型番B-10と新型番B-20の差異を説明の間のカンマまで消えている)23件が51物理行を占め、
51 - 23 = 28が増加ぶんです(120 + 28 = 148で一致)。
3つ目の項目は、上2つとは別枠の件数ではありません。このカンマ+改行の3件は、いずれも2つの物理行に分断されたほうに含まれています。足し算の対象は上2つです。
足してみてください。
| 計算 | 結果 | 同じ段落に書かれている値 |
|---|---|---|
| 20 + 5 | 25 | 23件 |
| 20×1 + 5×2 | 30 | +28行 |
| 20×2 + 5×3 | 55 | 51物理行 |
3つとも合いません。正しくは18件が2行に、5件が3行にです。18+5=23、18×1+5×2=28、18×2+5×3=51 で、すべて整合します。2回目は「18件が2行に、5件が3行に」と正しく報告していました。
ここで押さえておきたいことが2つあります。
1つ目。結論側の数字はすべて正しい。120件も、148件も、+28行も、51物理行も合っています。間違っているのは内訳の「18」を「20」と書いた1点だけです。数字を1つずつ眺めても気づけません。足し算をして初めて矛盾が見えます。
2つ目。出てきたCSVは完全に正しい。120件すべてが正解と一致していました。つまりファイルを開いて確かめても、説明が間違っていることは分かりません。
間違いが見えない場所が二重にあるわけです。これは能力の問題というより、文章を書くときに数字がずれた、という類のものです。なお、内訳まで書いてきたのは2回目と3回目の2回で、正しかったのは2回目だけでした。1回目は「23件が分断されていました」とだけ報告し、内訳には触れていません。
だから自分で確かめる
ここがこの記事の本題です。読者の手元には正解データがありません。何が正しいかを知らないまま、返ってきたものを受け取ることになります。
正解を知らなくてもできる確認が7つあります。
| 確認すること | やり方 | |
|---|---|---|
| 1 | 件数が合うか | 元システムの画面や送り状の「○件」と突き合わせる |
| 2 | 連番に欠番・重複がないか | 受付番号など連番の列を並べ替えて端から端まで見る |
| 3 | 全部の行で列数が揃っているか | CSVを正しく扱えるツール(表計算ソフトやエディタのCSV表示)で開き、列数が全行同じか確かめる。右端の列が埋まっているかを目で追うだけでは、列が多すぎる行や、空欄が正しい行を見落とす |
| 4 | 保存し直しても件数が変わらないか | 書き出したファイルを開き直して数え直す |
| 5 | 元々無事だった行が変わっていないか | 直す前後で、壊れていなかった行をいくつか目視で比べる |
| 6 | 説明の数字を足してみる | 内訳の合計が、書かれている合計と一致するか |
| 7 | 元のファイルが変わっていないか | 処理を始める前に元ファイルのコピーを別フォルダへ取っておき、あとで中身を突き合わせる。サイズと更新日時だけでは、変わっていない証明にはならない |
今回の値で言えば、120件、受付番号R2600〜R2719に欠番なし、全行7列、読み直しても121行(ヘッダー1+120件)、無事だった97件は1文字も変化なし、元ファイルは9,229バイトのまま。すべて確認できました。
ここで、指示文に書いたことと書かなかったことを分けて見ておきます。2回目・3回目に使った指示文(後述)には、件数・列数・書き出したファイルの読み直し・元ファイルを変えないこと、を明示的に書きました。つまり1・3・4・5・7は「頼んだからやってくれた」ぶんを含みます。
一方、2と6は3回とも頼んでいません。結果は正反対に分かれました。
| 頼まなかった確認 | 3回の実施状況 |
|---|---|
| 2 連番の欠番・重複 | 3回とも自分から確かめて報告した |
| 6 説明の数字を足す | 3回とも誰もやらなかった |
頼んでいないのに3回ともやったのが、欠番チェック。頼んでいなくて3回とも誰もやらなかったのが、自分の説明の検算です。
素朴な1行しか投げていない1回目に限れば、1から5までを頼まないうちに全部確認していました。それでも6だけはやっていません。だから6は、こちらでやる必要があります。
やることは単純です。内訳が並んでいたら足す。合計と合うか見る。それだけです。
使った指示文
2回目・3回目に使った指示文の全文です。ファイルを添付して、そのまま貼ってください。
添付のCSVを取り込むと行がズレます。正しく読める状態に直してください。
【まず確認してほしいこと】
1. このファイルの文字コードと改行コードを判定してください。
2. 1件のレコードが本来何列あるはずかを、ヘッダーから判断してください。
3. 何件のレコードがあるはずで、実際に何行として読まれてしまうのかを示してください。
【直し方の条件】
4. 分断されているレコードを結合して、全レコードが同じ列数に揃うようにしてください。
5. このファイルには、ダブルクォートで正しく囲まれた改行やカンマを含む行も混ざっています。
それらは元々壊れていないので、内容を変えないでください。
6. 結合の仕方が一通りに決まらない行があれば、推測で埋めずにそのまま残し、
別表で一覧にしてください。(どの行が、なぜ決まらないのか)
7. 直した結果は、ダブルクォートで正しく囲んだCSVとして書き出してください。
元のファイルは変更しないでください。
【最後に必ず報告してほしいこと】
8. 書き出したファイルを読み直して、レコード件数が想定どおりか
9. 元々壊れていなかった行が、処理後も変わっていないか
10. 直した手順を、次回も同じことができる形(スクリプト)で残してください
素朴な1行でも正解には到達しました。この指示文を使う意味は、精度を上げることよりも受け取るものの形を揃えることにあります。とくに5と6と9は、書いておかないと毎回違う扱いになります。
それでも今回は、同じ指示文で件数が120件と117件に分かれました。指示文を工夫しても、確認の手間はなくなりません。
スクリプトが付いてくる
3回とも、修復用のPythonスクリプトを一緒に書き出してきました。175行、206行、309行と長さは違いますが、考え方は共通しています。
- CP932で読む
- 標準のCSV機能に通す(正しくクォートされた行はここで1件として読める)
- 「日付+R番号」で始まらない行は、直前の行の続きとみなして結合する
- 結合しても列数が合わない行は、直さずに別表へ出す
この記事にスクリプトの中身は載せません。3回とも違うものが生成されたので、どれか1つを「正解」として載せると誤解を招くからです。手元のデータで検証を通したものを使うべきで、記事のものをコピーする話ではありません。
ただしスクリプトが手元に残るのは大きな違いです。毎月同じファイルを受け取るなら、翌月も同じ形式である限り、検証付きで同じスクリプトを流し直せます。逆に出力元の仕様が変われば壊れ方も変わるので、そのときは確認からやり直しです。3回目のスクリプトは、確認に1つでも失敗したらエラーで止まる作りになっていました。
ここから先は人が見る
機械では決められない箇所が3件ありました。R2627・R2642・R2714です。
37| 2026-05-08,R2627,代理店,請求,旧型番B-10,新型番B-20の差異を説明
38| 資料を送付,鈴木,保留
対応内容に改行とカンマの両方がクォートなしで入っています。この場合、カンマ自体はファイルの中に残っていますが、そのカンマが対応内容の一部なのか列の区切りなのかを見分ける情報が失われています。
「旧型番B-10」と「新型番B-20の差異を説明」の間にあるカンマが、列の区切りだったのか、それとも文章の一部だったのか。ファイルの中身だけを見ても決まりません。結合すると8列になってしまい、7列に収めるにはどこかを本文だと決めつけるしかありません。
この3件を「機械では決められない」と報告した点は3回とも共通でした。3回目は、その理由をこう書いています。
他レコードの表記(
型番A-100,A-200など8件はすべて半角カンマ・スペースなし)に合わせて半角,と推定。全角「、」や「, 」だった可能性は排除できない
判断材料としては、同じファイルの中に「型番A-100,A-200の両方を確認」のようなカンマ入りの定型文がクォート付きで存在します。同じ書き方なら半角カンマの可能性が高い。でも確定はできません。
なお、いまファイルに見えているのは半角カンマそのものです。これが元は全角「、」だったと考えるには、書き出しの途中で文字まで置き換わったという別の仮定が要ります。可能性として挙がっているだけで、そう決まったわけではありません。
ここは元の伝票なり画面なりを見て、人が判断する部分です。
この方法が使えないとき
| 条件 | 理由 |
|---|---|
| ダブルクォートが閉じられていない(前掲のパターンC) | 閉じ忘れた引用符が、そこから先のレコードを全部飲み込むか、パーサーがエラーで止まります。どこで閉じるべきかは中身からは決められません |
| レコードの先頭を見分ける目印がない | 今回は「日付+R番号」で始まる行を先頭と判定できました。連番も日付もないCSVでは、この方法は使えません |
| カンマが区切りか本文かを見分けられない | 上の3件。候補は挙げられますが確定できません |
| 毎回まったく同じ結果がほしい | 同じ指示文の2回で、件数も要確認の範囲も変わりました |
| 行数が非常に多い | 今回試したのは120件です。どこまでの規模が通るかは試していません |
| これは根本解決ではない | 3回とも指摘されました。原因は出力する側にあります |
最後の点は補足しておきます。今回のファイルは「改行やカンマを含む値をクォートするレコード」と「しないレコード」が混ざっていました。出力する側で、値を必ずダブルクォートで囲む設定にできれば、この修復作業そのものが不要になります。
受け取る側で直し続けるのは、毎月同じ手間を払い続けることです。出力元に相談できる相手がいるなら、そちらが先です。
なお今回使ったのは Claude(Opus 5)です。他のAIサービスで同じ結果になる保証はありません。同じサービスで3回とも成果物の形が異なり、同一指示で試した2回の間でも件数と要確認の範囲が変わりました。違うサービスならなおさらです。
送る前に確認すること
問い合わせ記録や対応履歴には、社外に出せない情報が入っていることがよくあります。AIサービスにファイルを送るのは、社外にデータを出すことです。勤務先によっては規定で禁止されています。試す前に、自分の職場のルールを確認してください。
送る前に見ておきたい項目です。
- 顧客名・取引先名
- 担当者名(今回の例にも入っています)
- メールアドレス・電話番号・住所
- 対応内容や備考のような自由入力欄(何が書かれているか分からない)
- 非表示の列・行、別シート、隠しシート
- ファイルのプロパティに残っている作成者名
とくに自由入力欄は要注意です。今回の記事の主題そのものですが、対応内容の欄には担当者が何を書いているか分かりません。個人名や電話番号がそのまま入っていることもあります。
行ズレを直すだけなら、対応内容の中身までは必要ないように思えます。ただし今回の直し方は「7列に揃っているか」で判断しているので、列を削ると使えなくなります。中身を伏せ字に置き換えたコピーを作る、という手はありますが、手間はかかります。
まとめ
120件が148件になっていたCSVは、ファイルを渡すだけで直りました。1回目は素朴な1行しか投げていませんが、文字コードの判定も、原因の特定も、修復用のスクリプトも、頼まないうちに出てきました。
ただし3回試して、3回とも形が違いました。件数が120件のときと117件のときがあり、「要確認」とされた件数も3件と7件に分かれました。本体CSVと別表を合わせれば、どれも120件を過不足なくカバーしています。成果物一式としてはどれも正しく、それでいてどれも形が違う。毎回同じものが返るなら1回確かめれば済みますが、変わるなら毎回確かめることになります。
そして3回目は、出てきたファイルは完全に正しいのに、説明の数字が間違っていました。ファイルを見ても分からず、数字を1つずつ眺めても分からず、足し算をして初めて見える種類の誤りです。
件数・欠番・列数・読み直し・無改変の5つは、3回とも確かめて報告してきました。うち欠番だけは、3回とも頼んでいないのに自分から確認しています。頼まないまま一度も確認されなかったのは、自分の説明の検算だけでした。足し算だけは、こちらでやってください。
なお、セル内改行そのものは悪者ではありません。ダブルクォートで囲まれていれば改行が入っていても問題は起きません。改行を減らす運用は事故を減らしますが、原因はクォートの側にあります。出力する側を直せるなら、そちらが本筋です。

