海外の開発委託先から毎月届く英文のタイムシートと請求書を読み取り、要員ごと・日ごとの工数を契約の単価と上限時間に照らして、超過と請求額の食い違いを支払の前に拾う
海外の開発委託先から毎月届く英文のタイムシートと請求書を読み取り、要員ごと・日ごとの工数を表にそろえます。契約の単価と月の上限時間に照らして、超過・単価の違い・請求額の食い違いを支払の前に拾います。
- 生成AI
- ChatGPT/Claude/Gemini
- AIサービス
- AWS Textract/Azure AI/Google Document AI
- 連携・自動化
- Python
- 対象業界
- IT・SaaS/小売/製造/金融
- 対象部門
- 情報システム/経理
- 対象業務
- データ入力・転記/内容確認・チェック
- 主な課題
- 人手が足りない/入力作業が多い/確認ミスが多い
- AIで行う処理
- 読み取り(OCR)
- 主な効果
- 入力漏れ削減/品質標準化/工数削減
- 導入難易度
- ★★☆☆☆
- 実装レベル
- 本格構成
- 費用感
- API連携(中)
- 人間の確認
- 条件付き
01導入前 / 導入後の業務フロー
- 開発管理の担当が、委託先から届いたタイムシートと請求書のPDFを共有フォルダに保存する
- タイムシートを1枚ずつ開き、日ごとの時間を表計算に打ち直して、要員ごとの月の合計を出す
- 契約の台帳を開き、要員が名簿に載っているか、月の上限時間を超えていないかを見比べる
- 請求書の明細を開き、要員ごとの時間と単価と金額が、2番の合計と契約の単価に合っているかを見比べる
- 食い違いがあれば、委託先の窓口に英文で問い合わせのメールを書く
- 合っていれば、経理に支払の承認を回す
- 人開発管理の担当が、届いたタイムシートと請求書のPDFを受領用の保管先に入れる
- 自動保存をきっかけに処理が動き、タイムシートか請求書かをファイル名と1ページ目で分ける
- 自動タイムシートは表の分析、請求書は請求書の分析でOCRにかける
- 自動生成AIが、読み取り結果を「要員・日付・時間・作業」の行と、請求書の明細の行にそろえる
- 自動プログラムが要員ごとに時間を足し、名簿・上限時間・単価と照合し、請求書の明細と突き合わせる
- 自動要員ごとに `match` / `over_cap` / `amount_mismatch` / `needs_human` を付け、問い合わせの下書きを作る
- 人担当が `match` 以外のものだけを開き、タイムシートの原本と見比べる
- 人問い合わせが要るものは下書きを直して委託先へ送り、回答を待つ
- 人食い違いが片付いた委託先から、経理に支払の承認を回す
各工程の詳しい説明を読む
- 開発管理の担当が、委託先から届いたタイムシートと請求書のPDFを共有フォルダに保存する
- タイムシートを1枚ずつ開き、日ごとの時間を表計算に打ち直して、要員ごとの月の合計を出す
- 契約の台帳を開き、要員が名簿に載っているか、月の上限時間を超えていないかを見比べる
- 請求書の明細を開き、要員ごとの時間と単価と金額が、2番の合計と契約の単価に合っているかを見比べる
- 食い違いがあれば、委託先の窓口に英文で問い合わせのメールを書く
- 合っていれば、経理に支払の承認を回す
(a)打ち直しに時間がかかる。 1人分のタイムシートは1か月で20行前後あり、120人分を打ち直すと、それだけで月初の2日がなくなります。 打ち直しの誤りで、合っている請求を食い違いとして問い合わせたこともあります。
(b)上限の超過は、合計でしか見えない。 日ごとの時間は1行ずつ見れば普通の数字で、月の合計を出してはじめて上限を超えていることが分かります。 2番を省いて請求書の合計だけを見ると、超過は請求書の金額の中に埋もれます。
(c)請求書とタイムシートの食い違いは、行の対応から始まる。 請求書の明細の名前と、タイムシートの名前の表記が違うことがあります。誰の行と誰のタイムシートを比べるかを決めるところで、まず時間がかかります。
(d)期限があるので省かれる。 支払の承認の期限が近い月は、請求書の合計と前月の差だけを見て承認に回すことがあります。 その月の超過は、翌月以降の契約の見直しのときに見つかります。
- 【人】 開発管理の担当が、届いたタイムシートと請求書のPDFを受領用の保管先に入れる
- 【自動】 保存をきっかけに処理が動き、タイムシートか請求書かをファイル名と1ページ目で分ける
- 【自動】 タイムシートは表の分析、請求書は請求書の分析でOCRにかける
- 【自動】 生成AIが、読み取り結果を「要員・日付・時間・作業」の行と、請求書の明細の行にそろえる
- 【自動】 プログラムが要員ごとに時間を足し、名簿・上限時間・単価と照合し、請求書の明細と突き合わせる
- 【自動】 要員ごとに
match/over_cap/amount_mismatch/needs_humanを付け、問い合わせの下書きを作る - 【人】 担当が
match以外のものだけを開き、タイムシートの原本と見比べる - 【人】 問い合わせが要るものは下書きを直して委託先へ送り、回答を待つ
- 【人】 食い違いが片付いた委託先から、経理に支払の承認を回す
7番目が、この設計の分かれ目です。 要員ごとの合計が上限の内側にあり、請求書の金額とも合うものは、一覧で流し見て終わりにします。人の時間は、超過と食い違いの説明を確かめることに使います。
5番目で計算をプログラムに置いているのも意図してのことです。 時間の合計と金額の掛け算は、何度やっても同じ答えになる処理です。生成AIにさせるのは、ばらばらな書式の表を同じ形の行にそろえるところまでです。
02今回想定するシステム構成
英文のタイムシートと請求書(メール添付のPDF) │ 開発管理の担当が受領用の保管先へ ▼【トリガー】保管先への保存 AWS Lambda ── タイムシートか請求書かの振り分け、形式・パスワードの確認 ├──▶ タイムシート:AWS Textract(StartDocumentAnalysis:TABLES・FORMS) └──▶ 請求書 :AWS Textract(StartExpenseAnalysis:明細と合計) ▼ Claude API ── 行のそろえ直し │ ① 要員の名前 ② 日付 ③ 時間 ④ 作業・チケット番号 ⑤ 請求書の明細の行 ▼ Python ── 要員ごとの集計/名簿・上限時間・単価との照合/請求書との突き合わせ ▼ 要員ごとの判定(match / over_cap / amount_mismatch / needs_human)+ 問い合わせの下書き ▼ 【開発管理の担当が印の付いたものを確認】 ├──▶ 委託先への問い合わせ └──▶ 経理へ支払の承認
| 役割 | 想定する製品 | 代替候補 |
|---|---|---|
| OCR | AWS Textract(StartDocumentAnalysis/StartExpenseAnalysis) | Azure AI Document Intelligence、Google Document AI |
| 生成AI | Claude API(行のそろえ直しと、問い合わせの下書き) | OpenAI API、Gemini API |
| 集計 | Python(要員ごとの集計と、契約の条件・請求書との照合) | 表計算の関数 |
| 連携 | AWS Lambda(保存と完了の通知を起点に処理を動かす) | Amazon EventBridge |
| 保管 | Amazon S3(原本、読み取り結果、照合の結果、確認の記録) | 社内のファイルサーバー |
契約の台帳と会計システムは、新しく足すものではありません。 最初の準備は、契約の台帳を「委託先・要員の名前・役割・時間単価・月の上限時間・契約の期間」の列を持つ表にすることです。SOWの PDF のままでは、プログラムで照合できません。
OCRに AWS Textract を選ぶのは、タイムシートと請求書が英文だからです。 公式の上限の表では、対応言語は英語、フランス語、ドイツ語、イタリア語、ポルトガル語、スペイン語で、手書きの認識は英語だけとされています。委託先の国の言語で書かれた書類は、この構成では扱えません。英語で出すことを契約の条件にしておきます。
この題材で効くのは、書類の種類ごとに分析の機能を選べることです。 タイムシートは StartDocumentAnalysis の TABLES で表として読み、セルの行と列の位置を取ります。請求書は StartExpenseAnalysis で読み、公式の説明では明細の行(EXPENSE_ROW)と、ITEM・QUANTITY・UNIT_PRICE・PRICE、合計の TOTAL や SUBTOTAL などの標準の項目が、書式によらず同じ名前で返ります。
03どうやって実装するのか
処理の起点を決める
受領用の保管先(Amazon S3 のバケット)にPDFが保存されたことを起点にします。 月初に3社から届くたびに動かし、3社分がそろうのを待ちません。 先に届いた委託先から照合が終わり、問い合わせを早く出せます。
保存のたびに Lambda が動き、ファイル名の規則と1ページ目の文字で、タイムシートか請求書かを振り分けます。 委託先には「<委託先コード>_<年月>_TS_<要員>.pdf」「<委託先コード>_<年月>_INV.pdf」の名前で送ってもらうよう、あらかじめ頼んでおきます。名前で決まらないものは1ページ目に「Invoice」の文字があるかで分けます。
分析の開始には ClientRequestToken を付けます。 同じトークンで呼ぶと同じ JobId が返るとされているので、ファイルのハッシュ値を使えば同じPDFを二重に分析しません。 完了の状態は Amazon SNS に届き、2つ目の Lambda が結果を取りに行きます。JobId は7日間だけ有効なので、結果はすぐに保管します。
委託先1社分のタイムシートと請求書がそろった時点で、照合を始めます。 そろったかどうかは、契約の台帳の名簿の人数と、届いたタイムシートの枚数で決めます。
入力データを集める
| データ | 中身 | 取得元 |
|---|---|---|
| タイムシート | 要員ごとの日付・時間・作業内容・チケット番号・承認者 | 受領用の保管先 |
| 請求書 | 請求書番号、請求の期間、要員ごとの明細(名前・時間・単価・金額)、小計・税・合計 | 受領用の保管先 |
| 読み取り結果 | 表とセル、キーと値の組、請求書の標準の項目と明細の行、それぞれの信頼度 | AWS Textract |
| 契約の台帳 | 委託先・要員の名前と別名・役割・時間単価・月の上限時間・契約の期間・超過の承認の記録 | スプレッドシート(読み取りのみ) |
| 自社の稼働日の暦 | 祝日と、委託先の国の祝日の一覧 | 開発管理の担当が用意する一覧 |
質を決めるのは、契約の台帳の「要員の別名」の列です。 タイムシートの名前は「Nguyen Van A」、請求書の明細は「A. Nguyen」のように、同じ人の表記が書類によって違います。 別名の列があれば、プログラムで同じ人に寄せられます。
超過の承認の記録も台帳に持たせます。 上限を超える作業を事前に承認していれば、超過は食い違いではありません。承認の記録が無いと、承認済みの超過まで全部問い合わせることになります。
データの取得方法を決める
タイムシートは GetDocumentAnalysis、請求書は GetExpenseAnalysis で結果を取り出します。
| 取るもの | どこから | 何に使うか |
|---|---|---|
| タイムシートの表 | TABLE・CELL と RowIndex/ColumnIndex、COLUMN_HEADER | 日付・時間・作業の列を見分けて行を取る |
| 表の合計の行 | EntityTypes が TABLE_SUMMARY や TABLE_FOOTER のセル | 委託先が書いた合計(照合の参考) |
| 要員の名前・期間・承認者 | KEY_VALUE_SET(FORMS) | 「Resource:」「Period:」「Approved by:」など |
| 請求書の明細 | EXPENSE_ROW と ITEM・QUANTITY・UNIT_PRICE・PRICE | 要員ごとの時間・単価・金額 |
| 請求書の合計 | TOTAL・SUBTOTAL・TAX・INVOICE_RECEIPT_ID・PO_NUMBER・DUE_DATE | 合計との照合と、支払の期日 |
表の列の見出しは COLUMN_HEADER で見分けます。 公式の説明では、表のセルには COLUMN_HEADER(列の見出し)、TABLE_SUMMARY(合計の行)などの種類が付きます。「Hours」「Hrs」「Effort」のように見出しの言葉が委託先ごとに違っても、どの列が見出しかが分かれば、生成AIで同じ名前に寄せられます。
委託先が書いた合計の行は、照合には使いません。 合計の行の数字は委託先の計算で、それが日ごとの行の和と合っているかを確かめるのが、この構成の仕事の1つです。 合計の行は別の項目として取り、プログラムの合計との差を見ます。
請求書の明細は、公式の説明では書式によらず ITEM・QUANTITY・UNIT_PRICE・PRICE の名前で返り、ラベルの原文が LabelDetection、値が ValueDetection に入ります。 時間が QUANTITY に入るか ITEM の文に混ざるかは委託先によるので、そのそろえ直しを生成AIに任せます。
AIへ渡す前に整形する
- 形式の確認 …
StartExpenseAnalysisは JPEG・PNG・PDF を扱うとされています。Excel で届いたタイムシートは PDF にしてから入れます - パスワードの確認 … PDF はパスワードで保護されていてはならないとされています。保護されたものは、委託先に保護のない版を頼みます
- 文字の大きさ … 検出できる文字の高さの下限は15ピクセル(150 DPI で8ポイント)です。表計算から縮小して印刷したタイムシートは、この下限を割ることがあります
- 期間の確認 … タイムシートの期間が請求の月と合っているかを、ファイル名と「Period」の値で確かめます。前月分が混ざっていれば分けます
- 名簿との突き合わせ … ファイル名の要員が契約の台帳の名簿に載っているかを先に見ます。載っていなければ、照合の前に
needs_humanの印を付けます
3番目は、委託先に書式を頼むほうが早く片付きます。 1枚に1か月を収めようとして縮小したタイムシートが多いので、2ページに分かれてよいと伝えます。
AIに処理させる
させるのは、読み取り結果を決まった形の行にそろえることだけです。
| 項目 | させること | 判断できないときの扱い |
|---|---|---|
| 要員の名前 | タイムシートの名前と請求書の明細の名前を、そのまま写す | 1枚に複数の名前があれば ambiguous |
| 日付 | 日付の列を年月日にそろえる。週の表は曜日と週の開始日から日付にする | 日と月の並びが決められなければ ambiguous |
| 時間 | 時間の列を数にする。「7:30」は7.5、「7.5」は7.5 | 数として読めなければ unreadable |
| 作業 | 作業内容とチケット番号を写す | 空なら空のまま |
| 請求書の明細 | 明細の行ごとに、要員の名前・時間・単価・金額を分ける | 時間が書かれていない明細は時間を空にする |
時間の書き方をそろえるのが、生成AIにいちばん向いている仕事です。 「7:30」「7.5」「7h30m」「7.30」が委託先によって混ざり、「7.30」が7時間30分なのか7.3時間なのかは、同じ表のほかの行を見ないと決まりません。表の中で書き方が一定しているかを見て決め、一定していなければ ambiguous にします。
| させないこと | 理由 |
|---|---|
| 時間の合計・金額の計算 | プログラムが行う。読み落としの行が結果に紛れ込む |
| 上限を超えたかの判定 | 契約の台帳に照らしてプログラムが決める |
| 名前の寄せ合わせ | 台帳の別名の列でプログラムが行う |
| 空の時間の補完 | 「書かれていない」という事実が消える |
指示内容を固定する
あなたは情報システム部門で、海外の開発委託先から届いた英文のタイムシートと
請求書を、照合のための行にそろえる担当です。
渡すのは AWS Textract の読み取り結果(表のセル、キーと値の組、
請求書の明細と標準の項目)だけです。書かれていないことを推測で埋めないでください。
【タイムシートでそろえる行】
- resource_name: 書かれた名前をそのまま写す
- date: YYYY-MM-DD
- hours: 数。"7:30" は 7.5、"7h30m" は 7.5
- task: 作業内容、ticket: チケット番号(無ければ空)
【請求書でそろえる行】
- resource_name, hours, unit_rate, amount, currency
【厳守事項】
- 時間の合計、金額の掛け算、上限との比較をしないでください。
- "7.30" のように、時間と分の区切りか小数かが決められない書き方があるときは、
同じ表のほかの行の書き方を見て決めてください。決められなければ
status を ambiguous にし、raw に元の文字列を写してください。
- 時間の欄が空の行は hours を null にしてください。0 にしないでください。
- 委託先が書いた合計の行は rows に入れず、vendor_total に別に写してください。
- 名前の表記をそろえたり、似た名前を同じ人とみなしたりしないでください。
- 週ごとの表で日付が無いときは、週の開始日と曜日から日付にし、
date_source を derived にしてください。週の開始日が無ければ ambiguous です。
- evidence には、根拠にしたセルの文字列をそのまま写してください。
- confidence は OCR が返した値をそのまま入れてください。
【書類の種類】{doc_type}
【委託先】{vendor_code}
【読み取り結果】{textract_result}
「空の時間を0にしない」を書かないと、空欄が0として入ります。 0と空は合計では同じに見えますが、空はタイムシートの記入漏れで、0は作業しなかった日です。 記入漏れの日を委託先に確かめる理由が、0にすると消えます。
「似た名前を同じ人とみなさない」も同じ理由です。 同じ委託先に同じ姓の要員が複数いることは珍しくありません。寄せるのは台帳の別名の列で、生成AIの判断ではありません。
出力形式を固定する
応答は、Claude API の構造化出力で次の形の JSON に固定します。 公式の説明では、output_config.format に type: "json_schema" とスキーマを渡すと、スキーマに合う JSON が返るとされています。
{
"doc_id": "V02_202609_TS_017",
"doc_type": "timesheet",
"vendor_code": "V02",
"resource_name": "Nguyen Van A",
"period": { "from": "2026-09-01", "to": "2026-09-30" },
"rows": [
{ "date": "2026-09-01", "date_source": "explicit", "hours": 8.0,
"raw": "8:00", "task": "API bug fix", "ticket": "PRJ-1182",
"status": "ok", "confidence": 97.8, "evidence": "8:00" }
],
"vendor_total": { "hours": 168.0, "raw": "168:00" },
"approved_by": ""
}
照合の結果はプログラムが付けます。
| プログラムが付ける項目 | 決め方 |
|---|---|
sum_hours | rows の hours の和。null の行は数えず、件数を別に数える |
vendor_total_diff | sum_hours と vendor_total の差 |
cap_check | 契約の台帳の月の上限時間との比較。超過の承認の記録があれば approved_over |
rate_check | 請求書の unit_rate と台帳の役割の時間単価が同じか |
amount_check | sum_hours × 台帳の単価と、請求書の amount の差 |
calendar_flags | 土日・祝日・1日の時間が多すぎる日の一覧 |
verdict | 条件 |
|---|---|
match | 上限の内側(または承認済み)、単価が同じ、金額の差が0、vendor_total_diff が0 |
over_cap | 上限を超え、承認の記録が無い |
amount_mismatch | 単価が違う、金額に差がある、委託先の合計が行の和と合わない |
needs_human | ambiguous・unreadable・null の時間、名簿に無い名前、calendar_flags がある |
JSON で受ける理由は、層を分けられることです。 契約の上限時間や単価が改まっても、保存した行に新しい条件を当て直すだけで、照合をやり直せます。 タイムシートを読み直す必要はありません。
システムへ連携する
| つなぎ先 | 方式 | 内容 |
|---|---|---|
| 受領用の保管先(Amazon S3) | 保存の通知で Lambda を起動 | 新しいPDFを検知し、種類で振り分ける |
| AWS Textract | StartDocumentAnalysis/StartExpenseAnalysis と各 Get 操作 | 分析を始め、完了の通知のあとに結果を取る |
| Claude API | Messages API(構造化出力) | 行のそろえ直しと、問い合わせの下書き |
| 契約の台帳 | スプレッドシートを読む | 名簿・別名・単価・上限時間・承認の記録 |
| 照合の一覧 | 表を書き出す | 要員ごとの判定と理由 |
| 会計システム | 既存の入力経路 | 支払の承認は人が回す |
会計システムへは書き込みません。 この構成が出すのは照合の結果までで、支払の承認は開発管理の担当と経理が行います。 契約の台帳にも書き込みません。超過の承認の記録を足すのは、承認した人です。
人が確認する
開発管理の担当が開くのは match 以外のものだけです。
needs_humanを先に見る … 時間が空の日、名簿に無い名前、土日・祝日の作業を、タイムシートの原本で確かめますover_capの理由を確かめる … 事前の承認が台帳に載っていないだけなら、承認した人に記録を頼みますamount_mismatchの差を確かめる … 単価の違いか、時間の読み違いかを原本で見ます- 問い合わせを送る … 下書きを直して委託先の窓口へ送ります。送信は人が行います
3番目を省かないでください。 金額の差の原因が、OCRが「7.5」を「75」と読んだことだった、ということがありえます。問い合わせの前に原本を見るのは、空振りの1通を避けるためです。
目標は、120件をならして1件3分です。 開くのは2〜3割という想定です。それより多い月は、台帳の別名か超過の承認の記録が足りていません。
例外に対処する
| 起きること | 対応 |
|---|---|
| パスワードで保護された PDF | 分析に回さず、委託先に保護のない版を頼む |
| Excel でタイムシートが届く | PDF にしてから分析する |
| 英語以外の欄がある | 読めない前提で扱う。英語で出すよう委託先に頼む |
| タイムシートが届かない要員がいる | 請求書に明細があれば needs_human。タイムシートの無い請求は照合しない |
| 請求書に名簿に無い要員の明細がある | needs_human。契約の変更が台帳に反映されていないかをまず見る |
| 時間の書き方が決められない | ambiguous。原本で見て直す |
分析が FAILED で終わる | 保管先に残し、担当へ通知する |
| 同時に始めた分析が多すぎる | LimitExceededException。少し待って始め直す |
4行目と5行目は、契約の変更と書類の流れのずれから起きます。 要員の交代が台帳より先に起きると、名簿に無い人の請求と、タイムシートの無い人の請求が同じ月に出ます。
記録を残す
- タイムシートと請求書の原本と、受け取った日時・委託先
- Textract の結果の全文と
JobId - 生成AIがそろえた行の JSON と、そのときのプロンプトの版
- 照合の結果(
sum_hours、cap_check、amount_check、verdict)と、そのとき参照した契約の台帳の内容 - 人が判定を覆した記録 … どの要員を、どの理由で
matchにしたか - 問い合わせの日時、委託先の回答、訂正された請求書との対応
4つ目で「そのときの台帳の内容」を残すのは、契約が月の途中で改まることがあるからです。 当時の単価と上限が残っていないと、後から照合の結果を説明できません。
04実装レベルの3段階
最小構成では120人分はさばけません。 確かめるための段階です。 半自動化で、①の打ち直しが無くなります。 1件12分は6分前後になります。本格構成で照合がプログラムに移り、3分になります。 照合の規則を書くには、契約の台帳が表の形になっている必要があるので、半自動化の間に台帳を整えます。
05工数削減シミュレーション
導入後 120件 × 3分 ÷ 60 = 6 時間/月
自社条件で導入効果を整理したい方へ
このユースケースを自社に当てはめた場合の前提値と削減見込みを、業務ヒアリングをもとに整理します。
06向いている企業・向いていない企業
- 海外の開発委託先に時間単価(タイム・アンド・マテリアル)で開発や保守を委託し、要員ごとの英文のタイムシートと請求書を毎月まとめて受け取っているソフトウェア会社、金融機関や小売・製造の情報システム部門。タイムシートの時間を表計算に打ち直して契約の上限時間と見比べている場合。上限の超過や単価の違いに、支払った後で気づいたことがある場合。
- 委託先の工数が自社のチケット管理の仕組みに直接記録され、タイムシートのPDFを読む必要がない場合。固定金額の請負契約で、時間による精算をしていない場合。タイムシートが英語以外(中国語・ベトナム語・日本語など)で書かれている場合(この構成のOCRは英語、フランス語、ドイツ語、イタリア語、ポルトガル語、スペイン語しか読めず、手書きは英語だけです)。なお、超過分を支払うか、委託先と精算の条件をどう取り決めるかの判断は、契約の担当と情報システムの責任者が行うもので、この構成では代替できません。
07最小構成で試す方法
- 先月の委託先1社分のタイムシートから10人分と、その月の請求書を選ぶ
- 手元の生成AIの画面にタイムシートを1枚ずつ渡し、「日付・時間・作業の表にしてください。空欄は空のままにし、合計は出さないでください」と指示する
- 出てきた表を表計算に貼り、自分で合計を出して、当時の打ち直しの結果と比べる
- 請求書も同じように明細の表にさせ、要員ごとの時間と金額を比べる
合計は必ず自分で出してください。 最小構成で確かめたいのは、表の読み取りが正しいかです。生成AIに合計まで出させると、どこで違ったのかが分かりません。
| 出てきた内容 | 判断 |
|---|---|
| 行が当時の打ち直しと同じ | OCRのAPIとプログラムでの照合に進む |
| 空欄が0や推測の時間で埋まった | 指示の書き方で直る。本格構成では構造化出力で防ぐ |
| 縮小されたタイムシートの数字が読めない | 委託先に書式を頼むのが先 |
08実装時につまずきやすいポイント
| 問題 | 対策 |
|---|---|
| 空欄の時間が0として入る | 指示で禁じ、null と0を分けて数える |
| 生成AIに合計を出させてしまう | 合計と掛け算はプログラムに置く |
| 「7.30」の読み方が委託先で違う | 表の中の書き方で決め、決まらなければ ambiguous |
| 名前の表記が書類で違う | 台帳に別名の列を持たせ、プログラムで寄せる |
| 承認済みの超過まで問い合わせる | 超過の承認の記録を台帳に持たせる |
| 委託先の合計の行を照合に使う | 合計の行は別に取り、行の和との差を見る |
| 縮小したタイムシートの数字が読めない | 文字の高さの下限は15ピクセル。2ページに分けてよいと伝える |
| 英語以外の欄が混ざる | 英語で出すことを契約の条件にする |
| 問い合わせが自動で送られる | 下書きまでにする。 送信は人が行う |
上の2行が、この構成の失敗のほとんどです。 どちらも「合計が合っているように見える」という同じ見た目になり、記入漏れの日と読み落としの行が、照合の結果から消えます。
09セキュリティ・AIガバナンス上の注意点
この構成で扱うデータ: 委託先の要員の氏名と、日ごとの作業時間・作業内容、時間単価と請求金額、そして自社のチケット番号と作業の内容です。
- 生成AIに渡す範囲を絞る … 渡すのはOCRの結果だけで、契約の台帳と単価の一覧は渡しません。 照合はプログラムの側で行います
- 要員の作業時間を評価に使わない … タイムシートは委託契約の精算のための書類です。この構成の結果を、委託先の要員個人の評価に転用しないでください
- 作業内容に自社の情報が含まれることを前提にする … チケットの件名にシステム名や顧客名が入ることがあります。保管先のアクセスを開発管理と経理に絞ります
- 精算の判断を代替しない … 超過分を支払うか、どう精算するかは、契約の担当と情報システムの責任者が決めます
- 問い合わせを自動で送らない … 委託先との関係に直接ひびきます
- 保管先を暗号化する …
KMSKeyIdを指定すると結果の暗号化の鍵を選べ、指定しないときは SSE-S3 で暗号化されるとされています
誤りが起きた場合のリスクは、超過を見落として支払うことと、合っている請求を問い合わせることの2つです。 前者は空欄の扱いと合計の行で、後者は時間の読み違いで起きます。前者は設計で、後者は人の確認で防ぎます。
10まず何から始めるか
1週目:契約の台帳を表にする
3社の SOW から、委託先・要員の名前・役割・時間単価・月の上限時間・契約の期間を表に写します。要員の別名の列と、超過の承認の記録の列も足します。
2週目:10人分で試す
先月の1社分から10人分を選び、手元の生成AIに行の表にさせます。空欄が0や推測で埋まっていないかを最優先で見ます。
3週目:委託先に書式を頼む
ファイル名の規則、英語で出すこと、縮小しないことを、3社の窓口に伝えます。 書式そのものは変えてもらう必要はありません。
4週目:保存から一覧までをつなぐ
保管先への保存を起点に分析を始め、生成AIで行をそろえ、一覧に書き出すところまで作ります。この時点では照合をせず、行だけを見ます。
2か月目: 集計と照合を足し、verdict を出します。needs_human の件数と理由を毎月数えます。3か月目以降: 問い合わせの下書きを足し、1件12分が何分になったかを実測します。月初の5営業日のうちに3社分の照合が終わり、支払の承認に余裕をもって回せた時点で、この構成は完成です。
11関連ユースケース
12この仕組みを理解するための記事
13技術仕様の確認日・参考情報
| 確認した内容 | 情報源 | 確認日 |
|---|---|---|
| 対応形式が JPEG・PNG・PDF・TIFF。非同期で PDF・TIFF が500MB・3,000ページ。パスワード付き PDF は不可。対応言語が英・仏・独・伊・葡・西で、手書きは英語だけ。文字の高さの下限が15ピクセル(150 DPI で8ポイント) | AWS: Set Quotas in Amazon Textract | 2026-10-09 |
請求書の分析が、書式によらず標準の項目(INVOICE_RECEIPT_ID・PO_NUMBER・DUE_DATE・TOTAL・SUBTOTAL・TAX、明細の ITEM・QUANTITY・UNIT_PRICE・PRICE)と EXPENSE_ROW を返し、ラベルの原文を LabelDetection、値を ValueDetection に入れ、信頼度を付けること。標準に合わない項目は OTHER になること | AWS: Analyzing Invoices and Receipts | 2026-10-09 |
StartExpenseAnalysis が JPEG・PNG・PDF を扱い、GetExpenseAnalysis で結果を取ること。ClientRequestToken・JobTag・KMSKeyId(指定しないときは SSE-S3)。JobId が7日間有効なこと | AWS: StartExpenseAnalysis | 2026-10-09 |
FeatureTypes に TABLES・FORMS などを指定できること。ClientRequestToken で同じ JobId が返ること。LimitExceededException | AWS: StartDocumentAnalysis | 2026-10-09 |
TABLE・CELL と RowIndex/ColumnIndex。セルの種類として COLUMN_HEADER・TABLE_SUMMARY・TABLE_FOOTER などがあること。KEY_VALUE_SET | AWS: Block | 2026-10-09 |
構造化出力を output_config.format(type: "json_schema")で指定すること | Claude: Structured outputs | 2026-10-09 |
超過分の支払と精算の条件は、契約の担当と情報システムの責任者が契約に照らして決めてください。 海外への支払に伴う税務の扱いは本記事の対象外です。本記事は公開仕様で確認できた範囲だけを扱っています。
実装ステータス:構成例。 公開仕様に基づいて設計した構成であり、当社で実際に構築・検証したものではありません。工数の数値はモデル条件による試算です。
自社の業務に使えるAI活用候補を整理します
このユースケース(UC-1219)についてのご相談はこちらから。
