English
Extracting data with AI
Most entity model pages have structured output for AI in the Download row: a JSON Schema that the structured outputs of AI models accept, with descriptions in English. Send it to an AI model together with a document, such as an e-mail or a PDF, and the model answers with the attributes of the model. This page extracts a designated emergency evacuation site (EvacuationSite) from a short notice, with the OpenAI API or the Claude API.
1. The schema and the text
bash
curl -sSfO https://datamodels.jp/adapters/ai/disaster/EvacuationSite.ai.jsonThe file is { name, description, strict, schema }. id and type are not in it: your application sets them. The text is in notice.txt, for example:
text
都立一橋高校(東京都千代田区東神田1-12-13)を、地震、高潮、内水氾濫の指定緊急避難場所に指定しました。区の番号は 13101-0012 です。指定避難所も兼ねます。Both APIs also take a PDF file as input; their documentation shows how.
2. Ask the model
The requests are built with jq, which puts the schema and the text into the body. The model names are examples: any model with structured outputs or tools works.
bash
jq -n --slurpfile s EvacuationSite.ai.json --rawfile text notice.txt '{
model: "gpt-6-astra",
messages: [
{role: "system", content: "Extract the evacuation site from the text."},
{role: "user", content: $text}
],
response_format: {type: "json_schema", json_schema: $s[0]}
}' > request.json
curl -sS https://api.openai.com/v1/chat/completions \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" --data @request.json \
| jq '.choices[0].message.content | fromjson' > site.jsonbash
jq -n --slurpfile s EvacuationSite.ai.json --rawfile text notice.txt '{
model: "claude-opus-5-5",
max_tokens: 16000,
system: "Extract the evacuation site from the text with the tool.",
tools: [{name: $s[0].name, description: $s[0].description,
input_schema: $s[0].schema}],
messages: [{role: "user", content: $text}]
}' > request.json
curl -sS https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" -H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" --data @request.json \
| jq -e 'first(.content[] | select(.type == "tool_use") | .input)' > site.json- OpenAI API: the file is the
json_schemaofresponse_formatas it is, withstrict: true. The answer has every attribute, withnullwhere the text says nothing. - Claude API: the
schemais theinput_schemaof a tool, and the answer is the tool's input. The model in the example does not accept a forcedtool_choice, so the system prompt asks for the tool; when the answer has no tool call,jq -estops with an error, and you send the request again. Claude's strict mode ("strict": trueon the tool) takes at most 16 properties that may benullper request. EvacuationSite has more, so the example leaves strict out; the answer then usually follows the schema, and step 3 checks it. For a smaller model, or after you remove the attributes you do not need, add"strict": true. - To get several sites from one text, put the schema into a list:
{"type": "object", "properties": {"sites": {"type": "array", "items": …}}}, withrequiredandadditionalProperties: falseas in the file.
Read the providers' notes on structured outputs before you rely on them: OpenAI, Claude.
3. Check the answer and make an entity
The answer has the attributes only. Remove the empty ones, drop any id or type the AI added, and add your own:
bash
jq 'walk(if type == "object" then with_entries(select(.value != null)) else . end)
| del(.id, .type)
| {id: "urn:ngsi-ld:EvacuationSite:0012", type: "EvacuationSite"} + .' \
site.json > entity.jsonThen check entity.json against the model's JSON Schema, as in Validating JSON. Strict mode keeps the shape of the answer, but the AI schema leaves some rules (minimums, rules on several attributes) to its descriptions, and without strict mode nothing is guaranteed. The JSON Schema checks them all. It cannot check the facts: a model can still misread a code or a number, so compare the values with the document before you store them.
entity.json is now a key-values entity. To send it to an NGSI-LD broker, put it into the normalized form with the @context (Sending to an NGSI-LD broker).
Your own models
For the models of a site of your own, make the same file with datamodels export --to ai. A model with an attribute that has no strict form has no AI file (Exporting to other tools).