GrepBoard/Manuals
84 manuals ·

Write a quote email from a line-item table, VAT copied as-is

·updated ·claude-sonnet-5-5 (ChatGPT could not be run, so Claude was used) · run 2026-10-20·6 steps

A quote email prompt that makes the model copy amounts from your table only, plus a Python check that recomputes subtotal, VAT and total against the email.

You have a qty × unit price table and no quote email yet. The wording is easy to hand to an AI, but if VAT is off by one won against the table, the customer will see it first. Finish the arithmetic in the table and let the email copy it.

[1] The input is six made-up office-supply lines. VAT is 10% of the subtotal, with the fraction dropped (spreadsheet ROUNDDOWN(subtotal*0.1, 0)). The unit prices make 10% of 569,825 equal 56,982.5, so dropping gives 56,982 and rounding gives 56,983.

quote.en.txt
Item | Qty | Unit price (KRW) | Amount (KRW)A4 copy paper (box) | 12 | 23,400 | 280,800Black ballpoint pen (pack) | 30 | 3,150 | 94,500Document folder | 20 | 1,870 | 37,400Sticky notes | 25 | 2,260 | 56,500Staples | 40 | 890 | 35,600Whiteboard marker | 15 | 4,335 | 65,025Subtotal | | | 569,825VAT (10%) | | | 56,982Total | | | 626,807Valid until: 2026-11-13Delivery: 3 business days after order, no shipping fee

[2] Start short: give only qty and unit price and ask for "the subtotal, VAT and total too". The two runs did not agree on the body: one wrote VAT 56,982, the other rounded up to 56,983 (total 626,808). Both added a note after the email, which is the second problem.

output
- The unit prices are treated as VAT-exclusive, with Korea's standard 10% VAT added on top. If they already include VAT, the figures need to change.- VAT is 56,982.5, rounded up to 56,983. If your invoicing practice truncates fractions of a won, use 56,982 and a total of 626,807.

No rule was given, so the model picked a rounding on its own (differently in the two runs) and listed the other. Copy that into the email and the customer sees two VATs.

[3] Fix the prompt. The arithmetic is already in the table, so the email only copies numbers. This follows the Gemini guide (split calculation from wording) and the OpenAI guide (state the rules explicitly). Wrap the table in <quote>.

text
Write a quote email to a customer from the line-item table inside <quote>. Rules:- Copy every amount exactly as it appears in the table. Do not calculate, correct or invent any amount. Do not write an amount that is not in the table.- Include the table (item, qty, unit price, amount), then subtotal, VAT and total, in the table's order.- In the body, give one sentence each for: what the quote covers, how long it is valid, and the next step (how to place the order).- Leave company name, contact name and contact details as placeholders such as [Company].- Output the email only. Add no notes, assumptions or comments. <quote>{table copied from your spreadsheet · validity · delivery terms}</quote>

[4] Put quote.en.txt into the prompt and run it through stdin. The end of the first run (item rows trimmed).

console
$ claude -p --model claude-sonnet-5-5 --max-turns 1 --tools "" --setting-sources "" --strict-mcp-config < prompt.en.txt > out.en.txt
output
| Subtotal | | | 569,825 || VAT (10%) | | | 56,982 || Total | | | 626,807 | This quote covers the six office supply items listed above, with delivery 3 business days after order and no shipping fee. The quote is valid until 2026-11-13. To place your order, please reply to this email or contact us at [Contact Details], and we will arrange delivery right away.

The notes are gone and the amounts were the same in both runs. The second run folded "what the quote covers" into its opening line and put delivery into the order sentence, so check that all three are there.

[5] Recompute yourself. Redo it in the spreadsheet, or run this script: it recomputes from the table and checks that every comma-formatted number in the email is in that set.

check.py
#!/usr/bin/env python3"""usage: check.py quote.txt mail.txt — recompute from qty x unit price, compare with every comma number in the mail"""import re, sysrows = [l.split("|") for l in open(sys.argv[1], encoding="utf-8") if l.split("|")[1:2] and l.split("|")[1].strip().isdigit()]unit = {int(r[2].replace(",", "")) for r in rows}lines = [int(r[1]) * int(r[2].replace(",", "")) for r in rows]supply = sum(lines)vat = supply // 10          # ROUNDDOWN(supply * 0.1, 0)want = {"subtotal": supply, "VAT": vat, "total": supply + vat}seen = {int(n.replace(",", "")) for n in re.findall(r"\d{1,3}(?:,\d{3})+", open(sys.argv[2], encoding="utf-8").read())}bad = 0for k, v in want.items():    bad += v not in seen    print("OK  " if v in seen else "MISS", k, f"{v:,}")for v in sorted(seen - set(lines) - set(want.values()) - unit):    bad += 1    print("EXTRA", f"{v:,}")sys.exit(1 if bad else 0)
console
$ python3 -I check.py quote.en.txt out.en.txt; echo "exit $?"OK   subtotal 569,825OK   VAT 56,982OK   total 626,807exit 0

The short-prompt email (out1.en.1.txt) is the instructive one: its body says VAT 56,983 and total 626,808, and the script reports both as EXTRA. It prints no MISS, because the note under the email also quotes 56,982 and 626,807. Read the EXTRA lines first.

[6] What if the table itself is wrong? A sheet that used ROUND shows VAT 56,983 and total 626,808. With that table in the same prompt the model copied the numbers as told, both runs, and raised no warning. The script did.

console
$ python3 -I check.py quote.en.txt out2.sheet.en.1.txt | grep -v OKMISS VAT 56,982MISS total 626,807EXTRA 56,983EXTRA 626,808

"Copy the table" is safe only when the table is right. Whoever agreed the rounding rule with the customer decides which figure is correct; ROUNDDOWN here is an assumption.

#quote-email#vat#claude#sales