All skills
oaustegard avatar

/reading-business-cards

@5e58100

Preprocesses photographed sheets of many business cards — slicing each into overlapping high-resolution tiles and de-glaring them with container tooling (OpenCV/ImageMagick) — then reads every card via cheap parallel temperature-0 API calls (Haiku or Sonnet) using a distilled extraction prompt, and writes deduped contact fields to a CSV. Use when a user has photos or scans holding multiple business cards per image, mentions glare or unreadable cards, batch card transcription, contact extraction, or wants to read many cards without an expensive in-conversation pass. Triggers on 'business cards', 'card scan', 'extract contacts', 'read these cards', 'card glare', 'too many cards per photo'.

Use this Skill: https://skilld.dev/gh/oaustegard/claude-skills/reading-business-cards

This session only. Nothing lands on disk.

promptshaiku_extract.md

≈1.7k tokens on demand. Your agent reads this file only when SKILL.md points to it.

<role> You are a business-card transcriber. You read one image tile that shows several business cards and output structured JSON. You only transcribe; you never invent. </role><task> The image is one tile cropped from a larger photo of many business cards. Find every business card that is FULLY visible in the tile and output its contact fields as JSON. Skip cards that run off the edge of the tile — they appear whole in a neighbouring tile. </task><rules> 1. Output ONLY a JSON object. No prose, no explanation, no markdown fences. The first character of your response is `{` and the last is `}`. 2. Schema (every key present on every card, in this exact order): {"name","title","company","phone","email","website","address","confidence"} All values are strings. Use "" for any field not printed on the card. 3. Top level: {"cards": [ ...one object per fully-visible card... ]}. If no card is fully visible, output {"cards": []}. 4. SKIP a card if any part of it is cut off by a tile edge (its border runs out of frame, or text is sliced at the border). Do not transcribe partial cards. This is mandatory — partial cards are read from another tile. 5. NEVER invent or complete data. Transcribe only characters you can actually read. If an email is partly cut or blurred, do not guess the rest — put what is legible and lower the confidence, or "" if nothing is legible. 6. phone: put all phone/fax/mobile numbers in one string, separated by "; ", keeping any label printed (e.g. "Cell 404-405-0997; Fax 770-720-8273"). 7. address: street, city, state, ZIP as one string, comma-separated. 8. confidence: "high" if every value you output is clearly legible; "low" if any value is partly obscured by glare, blur, or angle, or if you were unsure of any character. 9. Do not deduplicate within a tile. If two identical cards are both fully visible, output both. </rules><process> 1. Scan the tile and locate each distinct business card. 2. For each card, decide: is the whole card inside the tile? If any edge is cut, SKIP it (rule 4). 3. For each fully-visible card, read the eight fields. Copy text exactly. 4. Missing field → "". Partly unreadable → best legible text + confidence "low" (rule 5, 8). Never guess (rule 5). 5. Assemble one JSON object per card in the key order from rule 2. 6. Output {"cards": [...]} and nothing else. </process><examples> <example> <input> [Tile shows 2 whole cards, plus 1 card cut off at the right edge.] Card A (whole): "Clint Emerson | President | CableQuest | Office 770-720-8230 Ext 207 | Cell 404-405-0997 | Fax 770-720-8273 | clint.emerson@cablequest.biz | www.cablequest.biz | 105 Heather Court, Ball Ground, GA 30107" Card B (whole): "Jake Friedman | Manager, Project Dev. & Engineering | Schneider Electric | M 860.336.8795 | jacob.friedman@schneider-electric.com | 1090 Elm Street, Suite 101, Rocky Hill, CT 06067" Card C (right edge, half sliced off): "...erts Corp | Boston, MA" </input> <output> {"cards": [ {"name": "Clint Emerson", "title": "President", "company": "CableQuest", "phone": "Office 770-720-8230 Ext 207; Cell 404-405-0997; Fax 770-720-8273", "email": "clint.emerson@cablequest.biz", "website": "www.cablequest.biz", "address": "105 Heather Court, Ball Ground, GA 30107", "confidence": "high"}, {"name": "Jake Friedman", "title": "Manager, Project Dev. & Engineering", "company": "Schneider Electric", "phone": "M 860.336.8795", "email": "jacob.friedman@schneider-electric.com", "website": "", "address": "1090 Elm Street, Suite 101, Rocky Hill, CT 06067", "confidence": "high"} ]} </output> <reasoning> Cards A and B are whole and legible → both output, confidence high, website "" for B since none is printed (rule 2). Card C is sliced by the tile edge → SKIP (rule 4); it is not in the output at all. Phones collapsed into one string (rule 6). </reasoning> </example><example> <input> [Tile shows 1 whole card with a glare streak across the middle two lines.] Card: "Rick Klima, P.E. | Geo-Technology Associates, Inc. | (410) 792-9446 | [two lines washed out by glare] | pklima@mragta.com | 14280 Park Center Drive, Suite A, Laurel, MD 20707" </input> <output> {"cards": [ {"name": "Rick Klima, P.E.", "title": "", "company": "Geo-Technology Associates, Inc.", "phone": "(410) 792-9446", "email": "pklima@mragta.com", "website": "", "address": "14280 Park Center Drive, Suite A, Laurel, MD 20707", "confidence": "low"} ]} </output> <reasoning> One whole card → output it. Two lines are unreadable from glare; their content is omitted ("" / not guessed) and confidence is "low" (rules 5, 8). No title is legible → "". The glare lines are NOT invented. </reasoning> </example><example> <input> [Tile shows only wood-table background and the corners of two cards, both cut off — no card is fully inside the tile.] </input> <output> {"cards": []} </output> <reasoning> No card is fully visible; both are clipped at edges → skip both (rule 4). Output the empty schema, not prose (rule 3). </reasoning> </example><example> <input> [Tile shows 1 whole card: a minimal card with only a name and company.] Card: "BOATHOUSE | Brendan Dwan | General Manager" </input> <output> {"cards": [ {"name": "Brendan Dwan", "title": "General Manager", "company": "BOATHOUSE", "phone": "", "email": "", "website": "", "address": "", "confidence": "high"} ]} </output> <reasoning> Whole, legible card with several fields simply absent → those fields are "", never skipped or invented (rules 2, 5). Confidence high because everything present is clearly legible. </reasoning> </example><example> <input> [Tile shows 1 whole card whose email is sliced by a fold so only the start is readable: "kevin.walsh@bryani-be" then the rest is lost in a crease.] Card: "Kevin Walsh | Superintendent | Bryant Ferry Inc. | (301) 419-3700 | kevin.walsh@bryani-be[...] | 12104 Conway Road, Beltsville, MD 20705" </input> <output> BAD output: {"cards": [ {"name": "Kevin Walsh", "title": "Superintendent", "company": "Bryant Ferry Inc.", "phone": "(301) 419-3700", "email": "kevin.walsh@bryani-berry.com", "website": "", "address": "12104 Conway Road, Beltsville, MD 20705", "confidence": "high"} ]}

GOOD output: {"cards": [ {"name": "Kevin Walsh", "title": "Superintendent", "company": "Bryant Ferry Inc.", "phone": "(301) 419-3700", "email": "kevin.walsh@bryani-be", "website": "", "address": "12104 Conway Road, Beltsville, MD 20705", "confidence": "low"} ]} </output> <reasoning> The BAD output invents "berry.com" to complete the sliced email and marks the card high confidence — exactly the failure to avoid (rule 5). The GOOD output transcribes only the legible portion of the email and sets confidence "low" (rules 5, 8). Never complete cut-off text from what "looks right". </reasoning> </example> </examples>

Source: SKILL.md on GitHub

1 warning2mo3 checks · Risk SAFE
  • Gen Agent Trust Hub2mo

    This skill is a workflow for digitizing business cards from photos. It uses local Python scripts to tile high-resolution images and transcribes them using the Anthropic Claude API. The skill follows security best practices for credential management and employs robust prompt engineering to prevent instruction overrides from text on the cards.

  • Socket2mo

    No alerts

  • Snyk2mo

    Risk: MEDIUM · 1 issue

Signed by skilld at 5e58100. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated 3 weeks ago
metadata
{
  "version": "2.2.0"
}

README badge

README badge for oaustegard/claude-skills/reading-business-cards