Skip to main content

cu-sdk-author-analyzer

EXPERIMENTAL. Iteratively author and test a custom Azure AI Content Understanding analyzer for a folder of **document** files (PDFs, page images) of a single type. Walks layout extraction → schema authoring → validation → batch test → agent review → refine cycle using the typed ContentUnderstandingClient. Use when the user wants to author a custom analyzer for invoices, contracts, forms, or any other single-type document set.

Quellinformationen

Repository
Azure/azure-sdk-for-python
Letzte Quellaktivität
10. August 2026 um 23:38
Erkannte Sprache von SKILL.md
Englisch
Sterne
5.587
Forks
3.348

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
7 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
cu-sdk-author-analyzer
description
EXPERIMENTAL. Iteratively author and test a custom Azure AI Content Understanding analyzer for a folder of **document** files (PDFs, page images) of a single type. Walks layout extraction → schema authoring → validation → batch test → agent review → refine cycle using the typed ContentUnderstandingClient. Use when the user wants to author a custom analyzer for invoices, contracts, forms, or any other single-type document set.
# Author a Custom Analyzer (single document type) > **[EXPERIMENTAL - REQUIRED FIRST MESSAGE]:** Before asking questions, probing the > environment, or running commands, tell the user: "This analyzer-authoring skill > is experimental and may change. Review generated schemas and test results before > relying on them." Author a custom Content Understanding analyzer for one document type end-to-end: extract layout, draft a field schema, validate locally, create the analyzer, batch-test it on sample files, and read a quality summary. **This is an iterative, human-in-the-loop workflow.** You will typically run the schema → test → review cycle multiple times to refine field descriptions before you're happy with the extraction quality. The workflow uses the typed `ContentUnderstandingClient` shipped in this package — the same client `samples/sample_create_analyzer.py` and `samples/sample_analyze_binary.py` use. > **[COPILOT INTERACTION MODEL]:** This skill is designed to be interactive. > At each step marked with **[ASK USER]**, pause execution and prompt the user > for input or confirmation before proceeding. Do NOT silently skip these > prompts. Use the `ask_questions` tool when available. > **[USE INSTEAD]:** If the user's packet contains **multiple different > document types** (for example, an invoice, a bank statement, and a loan > application in one PDF), route them to the > [`cu-sdk-author-analyzer-classify-route`](../cu-sdk-author-analyzer-classify-route/SKILL.md) > skill instead. This skill assumes one document type per analyzer. > **[ASK USER] Modality check (first thing to confirm):** > > "Are you working with **document** files — PDFs or images of pages? This > skill supports document modalities only." > > - If the user says **document** → continue with this skill. > - If the user says **audio**, **video**, or **image** → stop this skill and > point them at the matching SDK sample > ([`samples/sample_create_analyzer.py`](../../../samples/sample_create_analyzer.py) > with `prebuilt-audio` / `prebuilt-video` / `prebuilt-imageAnalyzer`) or the > [REST tutorial](https://learn.microsoft.com/azure/ai-services/content-understanding/tutorial/create-custom-analyzer). ## Prerequisites Required: venv active, SDK installed, `.env` with `CONTENTUNDERSTANDING_ENDPOINT` (plus `CONTENTUNDERSTANDING_KEY` or `az login`), and `samples/sample_update_defaults.py` run once for this resource. Full setup lives in [`cu-sdk-setup`](../cu-sdk-setup/SKILL.md). > **[COPILOT] Probe first, then route on failure — do not duplicate setup logic here.** > > ```bash > python -c "import sys; print('venv:', 'ok' if sys.prefix != sys.base_prefix else 'INACTIVE')" > ( [ -f .env ] && grep -E '^CONTENTUNDERSTANDING_ENDPOINT=https?://' .env >/dev/null && echo 'endpoint: ok' ) || echo 'endpoint: MISSING' > ( [ -f .env ] && grep -E '^CONTENTUNDERSTANDING_KEY=.+' .env >/dev/null && echo 'key: set' ) || echo 'key: empty' > az account show >/dev/null 2>&1 && echo 'az: ok' || echo 'az: not logged in' > ``` > > | Failure | Route to | > |---|---| > | venv `INACTIVE` or `azure.ai.contentunderstanding` import fails | [`cu-sdk-setup`](../cu-sdk-setup/SKILL.md) Steps 2–3, then resume | > | endpoint `MISSING` | [`cu-sdk-setup`](../cu-sdk-setup/SKILL.md) Step 4 (env vars), then resume | > | endpoint `ok`, key `empty`, `az: not logged in` | [`cu-sdk-setup`](../cu-sdk-setup/SKILL.md) Step 4 auth section (run `az login` **or** add `CONTENTUNDERSTANDING_KEY` to `.env`), then resume | > | All env checks pass but service calls fail with model errors | [`cu-sdk-setup`](../cu-sdk-setup/SKILL.md) Step 6 (`sample_update_defaults.py`), then resume | > | All ok | ✅ Proceed to Step 1. | > > Never ask the user to paste an endpoint or API key into chat — they edit `.env` directly or run `az login`. > **[ASK USER]** "How many representative documents do you have, and where are they?" — fewer than 3 is fine, but more is better for testing coverage. ## Package directory ``` sdk/contentunderstanding/azure-ai-contentunderstanding ``` ## Scripts and templates ``` .github/skills/cu-sdk-author-analyzer/ ├── scripts/ │ ├── extract_layout.py # Stage 1 │ ├── extract_layout.sh │ ├── create_and_test.py # Stage 2 │ └── create_and_test.sh └── templates/ └── schema_template.json # Starter schema for Step 2 ``` See [`scripts/README.md`](scripts/README.md) for a one-page reference. ## Workflow ### Step 1 — Extract layout for representative documents The model behind Content Understanding sees the **text and structure** the service extracts from your file, not the original pixels. Reviewing the layout output is the fastest way to know what labels and headings you can anchor your field descriptions to. > **[ASK USER]** "Point me at one of your sample documents (or a folder of > them). I'll run layout extraction so we can see what the model will be > looking at." Run: ```bash python .github/skills/cu-sdk-author-analyzer/scripts/extract_layout.py \ --input <path-to-folder-or-file> \ --output .local_only/layout/ ``` This produces one `<doc>.layout.md` and one `<doc>.layout.json` per input. Open the `.layout.md` file in VS Code and look for the **text anchors** you want to extract from — labels (`"Invoice #:"`), section headings (`"Bill To"`), table headers, etc. > **Reference**: this is the same call pattern as > [`samples/sample_analyze_binary.py`](../../../samples/sample_analyze_binary.py) > using `prebuilt-documentSearch`. ### Step 2 — Draft a JSON field schema Start from the template instead of writing from scratch: ```bash mkdir -p .local_only/schemas cp .github/skills/cu-sdk-author-analyzer/templates/schema_template.json \ .local_only/schemas/<name>_v1.json ``` Then edit `.local_only/schemas/<name>_v1.json`: set `baseAnalyzerId`, replace every `REPLACE:` placeholder, and add/remove fields. The schema is a JSON object with two required top-level keys: - `baseAnalyzerId` — which prebuilt analyzer your custom analyzer extends. Use the table below. - `fieldSchema.fields` — the named fields you want to extract. > **[COPILOT] Read best practices before drafting fields.** Before writing > any field description, fetch the official CU best-practices page and apply > its guidance: > > 🔗 https://learn.microsoft.com/azure/ai-services/content-understanding/concepts/best-practices > > Key principles that affect schema quality: > > - Be specific and concrete in field descriptions — vague descriptions > produce vague extractions. > - Use **text anchors** (labels, headings, neighbouring fields) — never > visual cues like colour, font, or position-without-text-context. This > matches the two-stage pipeline rule in > [`cu-sdk-common-knowledge`](../cu-sdk-common-knowledge/SKILL.md#field-description-rule-the-two-stage-pipeline). > - Include **format examples** and **alternative label names** when a value > can appear in multiple wordings or formats. > - Prefer `"method": "extract"` when the value appears verbatim; use > `"generate"` only when the model needs to synthesise (summary, > classification label) and `"classify"` for fixed enumerations. > - Keep the field count focused on what the user actually needs. Extra > fields cost tokens and can dilute extraction quality on the fields that > matter. The template demonstrates **all three extraction methods** (`extract`, `generate`, `classify`) plus the **nested object** and **array of objects** shapes. Delete the example fields you don't need. > **Template comment keys**: any key whose name starts with `_` > (e.g. `_comment`, `_optional_enableOcr`) is stripped from the request body > by `create_and_test.py` before it hits the service. Use them freely as > inline documentation. > **`models.completion` is effectively required**: whenever `fieldSchema` is > present, the service needs a completion model. Leave the `models` block in > the template populated unless you've run > [`samples/sample_update_defaults.py`](../../../samples/sample_update_defaults.py) > to set resource defaults. Omitting it fails with `InvalidRequest: > 'models.completion' is not set` *after* a misleadingly successful > `[CREATE]` log line. `create_and_test.py` prints a `[WARN]` if the schema > is missing it. #### Choosing `baseAnalyzerId` See the prebuilt-analyzer table in [`cu-sdk-common-knowledge` § Choosing `baseAnalyzerId`](../cu-sdk-common-knowledge/SKILL.md#choosing-baseanalyzerid). The local validator (Step 3) rejects any value not on that list. #### Example single-type schema ```json { "baseAnalyzerId": "prebuilt-document", "description": "Extract invoice header and totals.", "config": { "estimateFieldSourceAndConfidence": true, "returnDetails": true }, "models": { "completion": "gpt-5.2", "embedding": "text-embedding-3-large" }, "fieldSchema": { "name": "invoice_v1", "description": "Invoice header fields.", "fields": { "invoiceNumber": { "type": "string", "method": "extract", "description": "Invoice number printed near the 'Invoice #' label at the top of the page.", "estimateSourceAndConfidence": true }, "totalAmount": { "type": "number", "method": "extract", "description": "Grand total at the bottom of the document; typically labelled 'Total' or 'Amount Due'. Excludes any 'Subtotal' value.", "estimateSourceAndConfidence": true } } } } ``` > **Reference**: see > [`samples/sample_create_analyzer.py`](../../../samples/sample_create_analyzer.py) > for the typed-model equivalent. The script accepts a JSON dict directly > (the SDK's `begin_create_analyzer` is overloaded for both). > **Field-description rule (two-stage pipeline):** descriptions must reference > **text content and structure** (labels, headings, neighbouring fields), not > visual appearance (colour, font, size). See > [`cu-sdk-common-knowledge`](../cu-sdk-common-knowledge/SKILL.md) § > "two-stage pipeline". ### Step 3 — Validate the schema locally ```bash python .github/skills/cu-sdk-author-analyzer/scripts/create_and_test.py \ --schema .local_only/schemas/invoice_v1.json \ --input samples/sample_files/sample_invoice.pdf \ --output .local_only/test_results/v1 ``` The script runs the local validator first. If anything is wrong (unknown `baseAnalyzerId`, missing `fieldSchema`, malformed entries) it exits with code **2** *before* any service call. ### Step 4 — Read the stdout summary After the script finishes you get something like: ``` ======================================================================== [SUMMARY] category: (single) (3 document segments) ------------------------------------------ field fill rate avg conf invoiceNumber 100.0% 0.962 totalAmount 66.7% 0.481 lowest-confidence fields: 0.461 totalAmount (mixed_financial_docs) 0.732 invoiceNumber (mixed_financial_docs) ======================================================================== ``` For each input document the script writes two files into `--output`: - `<doc>.json` — full per-document `AnalysisResult` (fields, grounding, confidences). - `<doc>.llm.md` — same result rendered via the SDK's [`to_llm_input`](../../../samples/sample_create_classifier.py) helper: YAML front matter (category, page range, fields) plus the document text. Drop this straight into an LLM prompt, or skim it in VS Code for a fast human review. ### Step 5 — Agent review and iterate > **[COPILOT]** After the summary prints, do the following **automatically** > before asking the user anything: > > 1. Open each `<doc>.llm.md` (and the underlying `<doc>.json` for grounding) > in `.local_only/test_results/` and compare extracted field values
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen