Skip to content

FBR65/HSKN

Repository files navigation

HSKN -- EZT Tariff Classification Agent

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.

Features

  • 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.

Architecture

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)

Core Components

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.

Requirements

  • Python 3.12 or later
  • Dependencies listed in pyproject.toml:
    • agno -- AI agent framework (optional)
    • beautifulsoup4 -- HTML parsing
    • ddgs -- DuckDuckGo search fallback (optional)
    • openai -- API client for the LLM backend
    • requests -- HTTP client
    • python-dotenv -- Environment variable management

Installation

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]"

Configuration

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:cloud

BASE_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)

Usage

Command Line Interface (Direct Classification)

# 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"

Agno Agent (AI-Guided Classification)

python main.py --agno "Kunststoff-Spritzgussmaschine"

The agent will:

  1. Analyse the product description.
  2. Query the EZT database using the keyword search tool.
  3. Evaluate explanatory notes and exclusion criteria.
  4. Return a structured JSON response with recommendation.

Package Entry Point

After installation via pip install ., the command ezt-agent is available:

ezt-agent "Kunststoffmaschine"
ezt-agent --agno --json "Spritzgussformen"

Output

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."
}

Limitations

  • 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.

License

MIT

About

An AI-powered agent for classifying products under the Harmonized System and Combined Nomenclature using the German Electronic Customs Tariff (EZT).

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages