A Python-based agent for querying the German Electronic Customs Tariff (EZT-Online) at auskunft.ezt-online.de. HSKN classifies goods for import (Einfuhr) and export (Ausfuhr) by retrieving the correct commodity code (Warennummer), associated measures (Maßnahmen), and explanatory notes (Erläuterungen) directly from the official EZT database.
The agent combines a session-based HTTP client with an optional Agno AI agent layer for guided classification workflows.
- Keyword search -- Find candidate commodity codes via the EZT Stichwortsuche.
- Code lookup -- Retrieve full details for a known commodity code, including EUSt rates, import/export measures, and official notes.
- 12-digit resolution -- Automatically expand 4- or 6-digit codes to the full 12-digit level using the hierarchical nomenclature tree.
- Explanatory note validation -- Load HS/KN explanatory notes at the section, chapter, and position level. Exclusion criteria are evaluated against the product description to prune invalid branches early.
- DuckDuckGo fallback -- When the EZT keyword search returns no results, the agent searches the web for a plausible commodity code.
- Agno agent integration -- Optional AI-driven classification with structured JSON output, backed by an OpenAI-compatible API (Ollama Cloud or any compatible provider).
- JSON export -- Machine-readable output for integration with downstream systems.
hskn/
├── main.py # CLI, EZTClient, classify_product(), Agno agent
├── ezt_nomenklatur.py # Nomenclature tree parser (12-digit resolution)
├── ezt_erlaeuterungen.py # HS/KN explanatory notes loader and validator
├── pyproject.toml
├── .gitignore
└── .env # API credentials (excluded from version control)
| Component | Role |
|---|---|
EZTClient |
Session-based HTTP client for the EZT web application. Manages JSESSIONID cookies and handles EztSuche.do, StichwSucheAnzeige.do, and MnHinwAnzeige.do endpoints. |
classify_product() |
High-level classification workflow: keyword search → code lookup → optional 12-digit expansion → explanatory note retrieval. |
EZTTools |
Agno toolkit exposing search_product() and get_kn_details() as callable tools for the AI agent. |
ezt_nomenklatur.py |
Recursively expands the nomenclature tree via SeqEinreihungSucheAnzeige.do and returns all 12-digit leaf codes with relevance scoring. |
ezt_erlaeuterungen.py |
Loads structured explanatory notes (HS/KN/AV) and extracts inclusion/exclusion criteria for validation during tree traversal. |
- Python 3.12 or later
- Dependencies listed in
pyproject.toml:agno-- AI agent framework (optional)beautifulsoup4-- HTML parsingddgs-- DuckDuckGo search fallback (optional)openai-- API client for the LLM backendrequests-- HTTP clientpython-dotenv-- Environment variable management
cd hskn
python -m venv .venv
source .venv/bin/activate
pip install .For the Agno agent, install the package with the agent extras:
pip install ".[agent]"Create a .env file in the project root with the following variables:
# LLM backend (OpenAI-compatible API)
BASE_URL=https://ollama.com/v1
API_KEY=your-api-key-here
MODEL=kimi-k2.6:cloudBASE_URL must point to a v1-compatible chat completions endpoint.
MODEL is the model identifier as expected by the provider.
| Variable | Required | Description |
|---|---|---|
BASE_URL |
Yes | Base URL of the OpenAI-compatible API |
API_KEY |
Yes | API key for authentication |
MODEL |
Yes | Model name (e.g. kimi-k2.6:cloud) |
# Keyword search (default: Einfuhr)
python main.py "Kunststoffmaschine"
# Export mode
python main.py -m Ausfuhr "elektrische Motoren"
# Direct code lookup
python main.py -c 84778099
# JSON output
python main.py --json "Kaffeemaschine" > result.json
# Disable explanatory note loading (faster)
python main.py --no-erlaeuterungen "Textilien"python main.py --agno "Kunststoff-Spritzgussmaschine"The agent will:
- Analyse the product description.
- Query the EZT database using the keyword search tool.
- Evaluate explanatory notes and exclusion criteria.
- Return a structured JSON response with recommendation.
After installation via pip install ., the command ezt-agent is
available:
ezt-agent "Kunststoffmaschine"
ezt-agent --agno --json "Spritzgussformen"The JSON output format:
{
"product": "Kunststoff-Spritzgussmaschine",
"mode": "Einfuhr",
"warennummer": "84771000900",
"warenbeschreibung": "Spritzgießmaschinen",
"eust": "19,00 %",
"stichwort_treffer": 3,
"massnahmen": [
{
"mn_index": 12345,
"gebietscode": "1011",
"art": "Drittlandszollsatz",
"schluessel": "103",
"wert": "2,70 %",
"beginn": "01.01.2026",
"ende": "31.12.2028",
"erlaeuterungen": {
"Bedingungen": "...",
"Rechtsvorschrift": "...",
"Fußnoten": "...",
"Länderausschluss": "..."
}
}
],
"hinweise": [],
"justification": "Stichwort 'Kunststoff-Spritzgussmaschine' -> 3 Treffer. Beste Codenummer: 847710 -> 12-Steller: 84771000900. Spritzgießmaschinen. 3 Maßnahmen, 0 Hinweise."
}- The EZT web application requires a stateful HTTP session (JSESSIONID cookie). Sessions expire after a period of inactivity.
- The DuckDuckGo fallback is inherently imprecise and should only be used as a last resort.
- Explanatory note exclusion logic uses heuristic word matching; it does not replace professional customs expertise.
- This tool is intended to assist classification, not to provide legally binding tariff information.
MIT