{"id":34,"date":"2026-04-10T14:09:26","date_gmt":"2026-04-10T12:09:26","guid":{"rendered":"http:\/\/serwer402453.lh.pl\/autoinstalator\/serwer402453.lh.pl\/wordpress143401\/?p=34"},"modified":"2026-05-07T14:57:39","modified_gmt":"2026-05-07T12:57:39","slug":"ai-llm-integration","status":"publish","type":"post","link":"https:\/\/chmielinski-konrad.info\/index.php\/2026\/04\/10\/ai-llm-integration\/","title":{"rendered":"AI \/ LLM Integration"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"pl\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>AI \/ LLM Integration &mdash; Konrad Chmielinski<\/title>\n    <link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n    <link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\n    <link rel=\"stylesheet\" href=\"https:\/\/fonts.googleapis.com\/css2?family=JetBrains+Mono:wght@400;500;700&#038;family=Sora:wght@300;400;600;700&#038;display=swap\" media=\"print\" onload=\"this.media='all'\">\n    <noscript>\n        <link rel=\"stylesheet\" href=\"https:\/\/fonts.googleapis.com\/css2?family=JetBrains+Mono:wght@400;500;700&#038;family=Sora:wght@300;400;600;700&#038;display=swap\">\n    <\/noscript>\n    <style>\n    :root {\n        --accent: #7C3AED;\n        --accent-dim: #5B21B6;\n        --accent-bg: #F3EEFF;\n        --mono: 'JetBrains Mono', monospace;\n        --sans: 'Sora', sans-serif;\n    }\n\n    * {\n        box-sizing: border-box;\n        margin: 0;\n        padding: 0;\n    }\n\n    body {\n        background: #fff;\n        color: #111;\n        -webkit-overflow-scrolling: touch;\n        overflow-x: hidden;\n    }\n\n    .blog-root {\n        font-family: var(--sans);\n        color: #111;\n        max-width: 100%;\n        margin: 0 auto;\n        padding: 2rem 1rem 4rem;\n        line-height: 1.7;\n    }\n\n    .eyebrow {\n        font-family: var(--mono);\n        font-size: 11px;\n        letter-spacing: .12em;\n        color: var(--accent-dim);\n        text-transform: uppercase;\n        margin-bottom: .75rem;\n        display: flex;\n        align-items: center;\n        gap: 8px;\n    }\n\n    .eyebrow::before {\n        content: '';\n        display: inline-block;\n        width: 24px;\n        height: 1.5px;\n        background: var(--accent);\n    }\n\n    h1.blog-title {\n        font-family: var(--sans);\n        font-size: 2.2rem;\n        font-weight: 700;\n        line-height: 1.2;\n        margin-bottom: .5rem;\n        color: #111;\n    }\n\n    .subtitle {\n        font-size: 1.05rem;\n        color: #555;\n        font-weight: 300;\n        margin-bottom: 1.75rem;\n    }\n\n    .meta-row {\n        display: flex;\n        align-items: center;\n        gap: 1rem;\n        padding: .75rem 0;\n        border-top: .5px solid #ddd;\n        border-bottom: .5px solid #ddd;\n        margin-bottom: 2rem;\n        flex-wrap: wrap;\n    }\n\n    .meta-chip {\n        font-family: var(--mono);\n        font-size: 11px;\n        background: #f4f4f2;\n        border: .5px solid #ddd;\n        border-radius: 4px;\n        padding: 3px 8px;\n        color: #555;\n    }\n\n    .meta-chip.purple {\n        background: var(--accent-bg);\n        color: var(--accent-dim);\n        border-color: #C4B5FD;\n    }\n\n    .tech-grid {\n        display: grid;\n        grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n        gap: 10px;\n        margin: 1.5rem 0 2rem;\n    }\n\n    .tech-card {\n        background: #fff;\n        border: .5px solid #ddd;\n        border-radius: 12px;\n        padding: .875rem 1rem;\n        position: relative;\n    }\n\n    .tech-card .tc-label {\n        font-family: var(--mono);\n        font-size: 10px;\n        color: #777;\n        letter-spacing: .08em;\n        text-transform: uppercase;\n        margin-bottom: 4px;\n    }\n\n    .tech-card .tc-name {\n        font-size: 14px;\n        font-weight: 600;\n        color: #111;\n        margin-bottom: 4px;\n    }\n\n    .tech-card .tc-note {\n        font-size: 12px;\n        color: #555;\n        line-height: 1.4;\n    }\n\n    .tech-card .tc-dot {\n        position: absolute;\n        top: 12px;\n        right: 12px;\n        width: 7px;\n        height: 7px;\n        border-radius: 50%;\n        background: var(--accent);\n    }\n\n    .section-header {\n        display: flex;\n        align-items: center;\n        gap: 10px;\n        margin: 2.25rem 0 1rem;\n    }\n\n    .section-header h2 {\n        font-family: var(--sans);\n        font-size: 1.15rem;\n        font-weight: 600;\n        color: #111;\n    }\n\n    .sh-line {\n        flex: 1;\n        height: .5px;\n        background: #ddd;\n    }\n\n    .sh-badge {\n        font-family: var(--mono);\n        font-size: 10px;\n        background: var(--accent-bg);\n        color: var(--accent-dim);\n        border-radius: 4px;\n        padding: 2px 8px;\n        white-space: nowrap;\n        border: .5px solid #C4B5FD;\n    }\n\n    p.body {\n        font-size: 15px;\n        color: #111;\n        margin-bottom: 1rem;\n    }\n\n    .pipeline-visual {\n        background: #f7f7f5;\n        border: .5px solid #ddd;\n        border-radius: 12px;\n        padding: 1.25rem 1.5rem;\n        margin: 1.5rem 0;\n        overflow-x: auto;\n        -webkit-overflow-scrolling: touch;\n        touch-action: pan-x pan-y;\n    }\n\n    .pipeline-row {\n        display: flex;\n        align-items: center;\n        gap: 8px;\n        flex-wrap: nowrap;\n    }\n\n    .pipeline-col {\n        display: flex;\n        flex-direction: column;\n        gap: 6px;\n    }\n\n    .pipe-step {\n        background: #fff;\n        border: .5px solid #ddd;\n        border-radius: 6px;\n        padding: 6px 12px;\n        font-family: var(--mono);\n        font-size: 11px;\n        color: #111;\n        white-space: nowrap;\n        font-weight: 500;\n    }\n\n    .pipe-step.hl {\n        background: var(--accent-bg);\n        border-color: #C4B5FD;\n        color: var(--accent-dim);\n    }\n\n    .pipe-step.sm {\n        font-size: 10px;\n        padding: 4px 10px;\n    }\n\n    .pipe-arrow {\n        color: #999;\n        font-size: 12px;\n        flex-shrink: 0;\n    }\n\n    .code-block {\n        background: #f7f7f5;\n        border: .5px solid #ddd;\n        border-left: 2.5px solid var(--accent);\n        border-radius: 0 8px 8px 0;\n        padding: 1rem 1.25rem;\n        margin: 1rem 0 1.5rem;\n        font-family: var(--mono);\n        font-size: 12px;\n        color: #555;\n        line-height: 1.65;\n        overflow-x: auto;\n    }\n\n    .code-block .kw {\n        color: #7C3AED;\n        font-weight: 500;\n    }\n\n    .code-block .str {\n        color: #BA7517;\n    }\n\n    .code-block .cmt {\n        color: #999;\n    }\n\n    .tag-cloud {\n        display: flex;\n        flex-wrap: wrap;\n        gap: 6px;\n        margin: 1rem 0 1.5rem;\n    }\n\n    .tag {\n        font-family: var(--mono);\n        font-size: 11px;\n        padding: 4px 10px;\n        border-radius: 100px;\n        border: .5px solid #ccc;\n        color: #555;\n        background: #fff;\n    }\n\n    .tag.primary {\n        background: var(--accent-bg);\n        border-color: #C4B5FD;\n        color: var(--accent-dim);\n        font-weight: 500;\n    }\n\n    .callout {\n        background: #f7f7f5;\n        border-left: 2px solid var(--accent);\n        border-radius: 0 8px 8px 0;\n        padding: 1rem 1.25rem;\n        margin: 1.5rem 0;\n        font-size: 14px;\n        color: #555;\n        line-height: 1.65;\n    }\n\n    .callout strong {\n        color: #111;\n        font-weight: 600;\n    }\n\n    .stat-row {\n        display: grid;\n        grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n        gap: 10px;\n        margin: 1.5rem 0;\n    }\n\n    .stat-card {\n        background: #f7f7f5;\n        border-radius: 8px;\n        padding: 1rem;\n        text-align: center;\n    }\n\n    .stat-card .stat-num {\n        font-size: 2rem;\n        font-weight: 700;\n        color: var(--accent-dim);\n        font-family: var(--mono);\n    }\n\n    .stat-card .stat-label {\n        font-size: 12px;\n        color: #555;\n        margin-top: 4px;\n    }\n\n    .employer-row {\n        display: grid;\n        grid-template-columns: 1fr;\n        gap: 10px;\n        margin: 1rem 0;\n    }\n\n    .employer-card {\n        display: flex;\n        gap: 12px;\n        align-items: flex-start;\n        background: #fff;\n        border: .5px solid #ddd;\n        border-radius: 12px;\n        padding: .875rem 1rem;\n    }\n\n    .emp-logo {\n        width: 36px;\n        height: 36px;\n        border-radius: 8px;\n        background: var(--accent-bg);\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        font-family: var(--mono);\n        font-size: 10px;\n        font-weight: 700;\n        color: var(--accent-dim);\n        flex-shrink: 0;\n        letter-spacing: -.02em;\n        text-align: center;\n        line-height: 1.3;\n    }\n\n    .emp-body .emp-name {\n        font-size: 13px;\n        font-weight: 600;\n        color: #111;\n    }\n\n    .emp-body .emp-desc {\n        font-size: 12px;\n        color: #555;\n        margin-top: 3px;\n        line-height: 1.5;\n    }\n\n    \/* Model table with group rows *\/\n    .model-table {\n        width: 100%;\n        border-collapse: collapse;\n        font-size: 13px;\n        margin: 1.5rem 0;\n    }\n\n    .model-table th {\n        font-family: var(--mono);\n        font-size: 10px;\n        letter-spacing: .08em;\n        text-transform: uppercase;\n        color: #777;\n        font-weight: 500;\n        padding: 8px 12px;\n        border-bottom: .5px solid #ddd;\n        text-align: left;\n    }\n\n    .model-table td {\n        padding: 8px 12px;\n        border-bottom: .5px solid #f0f0f0;\n        color: #555;\n        vertical-align: top;\n    }\n\n    .model-table td:first-child {\n        font-weight: 600;\n        color: #111;\n        white-space: nowrap;\n    }\n\n    .model-table tr:last-child td {\n        border-bottom: none;\n    }\n\n    \/* Group header rows inside table *\/\n    .model-table .group-row td {\n        background: #f7f7f5;\n        font-family: var(--mono);\n        font-size: 10px;\n        letter-spacing: .08em;\n        text-transform: uppercase;\n        color: #999;\n        font-weight: 500;\n        padding: 6px 12px;\n        border-bottom: .5px solid #eee;\n        border-top: .5px solid #eee;\n    }\n\n    .model-table .group-row.purple td {\n        background: var(--accent-bg);\n        color: var(--accent-dim);\n        border-color: #C4B5FD;\n    }\n\n    \/* Status badges *\/\n    .status-badge {\n        display: inline-block;\n        font-family: var(--mono);\n        font-size: 10px;\n        padding: 2px 7px;\n        border-radius: 4px;\n        border: .5px solid #ddd;\n        background: #f4f4f2;\n        color: #555;\n        white-space: nowrap;\n    }\n\n    .status-badge.prod {\n        background: #ECFDF5;\n        color: #065F46;\n        border-color: #6EE7B7;\n    }\n\n    .status-badge.eval {\n        background: #FFF7ED;\n        color: #92400E;\n        border-color: #FCD34D;\n    }\n\n    .status-badge.local {\n        background: #EFF6FF;\n        color: #1E40AF;\n        border-color: #93C5FD;\n    }\n\n    .rag-diagram {\n        background: #f7f7f5;\n        border: .5px solid #ddd;\n        border-radius: 12px;\n        padding: 1.25rem 1.5rem;\n        margin: 1.5rem 0;\n        overflow-x: auto;\n    }\n\n    .rag-row {\n        display: flex;\n        align-items: flex-start;\n        gap: 8px;\n    }\n\n    .rag-col {\n        display: flex;\n        flex-direction: column;\n        gap: 6px;\n        align-items: center;\n    }\n\n    .rag-label {\n        font-family: var(--mono);\n        font-size: 9px;\n        color: #999;\n        text-transform: uppercase;\n        letter-spacing: .06em;\n        text-align: center;\n        margin-top: 2px;\n    }\n\n    .footer-note {\n        font-family: var(--mono);\n        font-size: 11px;\n        color: #777;\n        border-top: .5px solid #ddd;\n        margin-top: 3rem;\n        padding-top: 1rem;\n        display: flex;\n        justify-content: space-between;\n        flex-wrap: wrap;\n        gap: 4px;\n    }\n    <\/style>\n<\/head>\n<body>\n    <div class=\"blog-root\">\n\n        <div class=\"eyebrow\">Engineering Blog &middot; Konrad Chmielinski<\/div>\n        <p class=\"subtitle\">Embedding large language models into production automation workflows &mdash; not as chatbots, but as transformation engines.<\/p>\n\n        <div class=\"meta-row\">\n            <span class=\"meta-chip purple\">LLM Engineering<\/span>\n            <span class=\"meta-chip\">Azure OpenAI &middot; LangChain &middot; RAG<\/span>\n            <span class=\"meta-chip\">GPT-4o &middot; Claude &middot; Mistral &middot; Llama &middot; Agentic<\/span>\n            <span class=\"meta-chip\">Katowice, PL &middot; Remote OK<\/span>\n        <\/div>\n\n        <p class=\"body\">There is a wide gap between &#8220;using ChatGPT&#8221; and &#8220;integrating LLMs into production automation pipelines.&#8221; The first is a conversation. The second is an engineering discipline &mdash; involving prompt design, structured output contracts, confidence handling, agentic orchestration, retrieval systems, and rigorous testing against real business data.<\/p>\n        <p class=\"body\">I crossed that gap in production at ArcelorMittal Luxembourg in 2024, and have been building on those foundations ever since &mdash; adding RAG architectures, tool-calling agents, and LangGraph-based workflows to my stack. My model coverage now extends across OpenAI, Anthropic, Mistral, and locally-hosted open-source models via Ollama. This post covers every layer of how I work with LLMs in automation contexts.<\/p>\n\n        <div class=\"stat-row\">\n            <div class=\"stat-card\">\n                <div class=\"stat-num\">~60%<\/div>\n                <div class=\"stat-label\">end-to-end accuracy on AI offer generation pipeline (AM Luxembourg)<\/div>\n            <\/div>\n            <div class=\"stat-card\">\n                <div class=\"stat-num\">GPT-4o<\/div>\n                <div class=\"stat-label\">primary production model via Azure OpenAI<\/div>\n            <\/div>\n            <div class=\"stat-card\">\n                <div class=\"stat-num\">3<\/div>\n                <div class=\"stat-label\">agentic frameworks used: LangChain, LangGraph, custom tool-calling<\/div>\n            <\/div>\n            <div class=\"stat-card\">\n                <div class=\"stat-num\">RAG<\/div>\n                <div class=\"stat-label\">retrieval-augmented generation in active use for enterprise knowledge pipelines<\/div>\n            <\/div>\n        <\/div>\n\n        <div class=\"section-header\">\n            <h2>My core philosophy<\/h2>\n            <div class=\"sh-line\"><\/div>\n            <div class=\"sh-badge\">LLM as step, not product<\/div>\n        <\/div>\n        <p class=\"body\">\n            The most important design decision when integrating an LLM is treating it as \n            <em>one step<\/em>\n             in a larger pipeline &mdash; not as the whole product. In every system I have built, the LLM sits between structured data retrieval and structured output validation. It never owns the I\/O contract. That contract belongs to the surrounding automation layer.\n        <\/p>\n\n        <div class=\"pipeline-visual\">\n            <div class=\"pipeline-row\">\n                <div class=\"pipe-step hl\">Data source<\/div>\n                <div class=\"pipe-arrow\">&rarr;<\/div>\n                <div class=\"pipe-step\">Retrieve &amp; chunk<\/div>\n                <div class=\"pipe-arrow\">&rarr;<\/div>\n                <div class=\"pipe-step hl\">Prompt builder<\/div>\n                <div class=\"pipe-arrow\">&rarr;<\/div>\n                <div class=\"pipe-step\">LLM inference<\/div>\n                <div class=\"pipe-arrow\">&rarr;<\/div>\n                <div class=\"pipe-step hl\">Output parser<\/div>\n                <div class=\"pipe-arrow\">&rarr;<\/div>\n                <div class=\"pipe-step\">Validate<\/div>\n                <div class=\"pipe-arrow\">&rarr;<\/div>\n                <div class=\"pipe-step hl\">Action<\/div>\n            <\/div>\n        <\/div>\n\n        <div class=\"section-header\">\n            <h2>Models I work with<\/h2>\n            <div class=\"sh-line\"><\/div>\n            <div class=\"sh-badge\">production + evaluation<\/div>\n        <\/div>\n\n        <table class=\"model-table\">\n            <thead>\n                <tr>\n                    <th>Model<\/th>\n                    <th>Provider \/ Runtime<\/th>\n                    <th>Use case<\/th>\n                    <th>Status<\/th>\n                <\/tr>\n            <\/thead>\n            <tbody>\n\n                <!-- OpenAI -->\n                <tr class=\"group-row\">\n                    <td colspan=\"4\">OpenAI &mdash; via Azure OpenAI<\/td>\n                <\/tr>\n                <tr>\n                    <td>GPT-4o<\/td>\n                    <td>Azure OpenAI<\/td>\n                    <td>Structured output, entity extraction, offer generation, classification<\/td>\n                    <td><span class=\"status-badge prod\">Production<\/span><\/td>\n                <\/tr>\n                <tr>\n                    <td>GPT-4<\/td>\n                    <td>Azure OpenAI<\/td>\n                    <td>Complex reasoning, document summarisation<\/td>\n                    <td><span class=\"status-badge prod\">Production<\/span><\/td>\n                <\/tr>\n                <tr>\n                    <td>Embedding models<\/td>\n                    <td>Azure OpenAI \/ HuggingFace<\/td>\n                    <td>Vector embeddings for RAG retrieval<\/td>\n                    <td><span class=\"status-badge prod\">Production<\/span><\/td>\n                <\/tr>\n\n                <!-- Anthropic Claude -->\n                <tr class=\"group-row purple\">\n                    <td colspan=\"4\">Anthropic &mdash; Claude family<\/td>\n                <\/tr>\n                <tr>\n                    <td>Claude 3.5 Sonnet<\/td>\n                    <td>Anthropic API<\/td>\n                    <td>Complex reasoning, long-context document analysis, instruction following, code generation<\/td>\n                    <td><span class=\"status-badge eval\">Evaluated<\/span><\/td>\n                <\/tr>\n                <tr>\n                    <td>Claude 3 Opus<\/td>\n                    <td>Anthropic API<\/td>\n                    <td>High-accuracy classification tasks, nuanced structured output where GPT-4o underperforms<\/td>\n                    <td><span class=\"status-badge eval\">Evaluated<\/span><\/td>\n                <\/tr>\n                <tr>\n                    <td>Claude 3 Haiku<\/td>\n                    <td>Anthropic API<\/td>\n                    <td>Low-latency, cost-efficient inference for high-volume classification and extraction tasks<\/td>\n                    <td><span class=\"status-badge eval\">Evaluated<\/span><\/td>\n                <\/tr>\n\n                <!-- Mistral -->\n                <tr class=\"group-row\">\n                    <td colspan=\"4\">Mistral AI<\/td>\n                <\/tr>\n                <tr>\n                    <td>Mistral Large<\/td>\n                    <td>Mistral API \/ Azure AI<\/td>\n                    <td>European-hosted alternative to GPT-4 for GDPR-sensitive workloads; function calling, structured output<\/td>\n                    <td><span class=\"status-badge eval\">Evaluated<\/span><\/td>\n                <\/tr>\n                <tr>\n                    <td>Mistral 7B \/ 8x7B (Mixtral)<\/td>\n                    <td>Self-hosted \/ Ollama<\/td>\n                    <td>On-premise inference, fast local classification, cost-free experimentation<\/td>\n                    <td><span class=\"status-badge local\">Local<\/span><\/td>\n                <\/tr>\n                <tr>\n                    <td>Mistral Embed<\/td>\n                    <td>Mistral API<\/td>\n                    <td>Multilingual embeddings for RAG pipelines handling PL\/FR\/DE documents<\/td>\n                    <td><span class=\"status-badge eval\">Evaluated<\/span><\/td>\n                <\/tr>\n\n                <!-- Meta Llama -->\n                <tr class=\"group-row\">\n                    <td colspan=\"4\">Meta &mdash; Llama family (via Ollama)<\/td>\n                <\/tr>\n                <tr>\n                    <td>Meta Llama 3 (8B \/ 70B)<\/td>\n                    <td>Ollama (local only)<\/td>\n                    <td>Local inference for prototyping and offline experimentation; run entirely on-device via Ollama, no cloud dependency<\/td>\n                    <td><span class=\"status-badge local\">Local<\/span><\/td>\n                <\/tr>\n\n                <!-- Ollama runtime -->\n                <tr class=\"group-row\">\n                    <td colspan=\"4\">Ollama &mdash; local inference runtime<\/td>\n                <\/tr>\n                <tr>\n                    <td>Ollama runtime<\/td>\n                    <td>Local \/ Docker<\/td>\n                    <td>Unified local inference layer for Llama, Mistral, Phi, Gemma and other open-source models. Used for rapid prototyping, offline testing, and air-gapped deployments<\/td>\n                    <td><span class=\"status-badge local\">Local<\/span><\/td>\n                <\/tr>\n                <tr>\n                    <td>Phi-3 Mini (via Ollama)<\/td>\n                    <td>Microsoft \/ Ollama<\/td>\n                    <td>Ultra-lightweight inference on CPU; edge deployment testing<\/td>\n                    <td><span class=\"status-badge eval\">Evaluated<\/span><\/td>\n                <\/tr>\n                <tr>\n                    <td>Gemma 2 (via Ollama)<\/td>\n                    <td>Google \/ Ollama<\/td>\n                    <td>Alternative open-weight baseline for classification benchmarking<\/td>\n                    <td><span class=\"status-badge eval\">Evaluated<\/span><\/td>\n                <\/tr>\n\n            <\/tbody>\n        <\/table>\n\n        <div class=\"section-header\">\n            <h2>Prompt engineering<\/h2>\n            <div class=\"sh-line\"><\/div>\n            <div class=\"sh-badge\">the craft layer<\/div>\n        <\/div>\n        <p class=\"body\">Prompt engineering in a production context is not about clever phrasing &mdash; it is about designing deterministic, testable input contracts that produce consistent structured output. I work with system prompts that define output schema explicitly, few-shot examples drawn from real production data, and chain-of-thought instructions for multi-step reasoning tasks.<\/p>\n\n        <div class=\"tag-cloud\">\n            <span class=\"tag primary\">System prompt design<\/span>\n            <span class=\"tag primary\">Structured JSON output<\/span>\n            <span class=\"tag primary\">Few-shot examples<\/span>\n            <span class=\"tag primary\">Chain-of-thought prompting<\/span>\n            <span class=\"tag\">Temperature control<\/span>\n            <span class=\"tag\">Token budget management<\/span>\n            <span class=\"tag\">Prompt versioning<\/span>\n            <span class=\"tag\">Negative examples<\/span>\n            <span class=\"tag\">Role prompting<\/span>\n            <span class=\"tag\">Output length constraints<\/span>\n        <\/div>\n\n        <p class=\"body\" style=\"font-size:13px;color:#777;margin-bottom:.5rem;\">Below is an example prompt used to extract steel products from client emails &mdash; illustrating the structured output approach with Azure OpenAI:<\/p>\n        <div class=\"code-block\">\n<pre style=\"margin:0;font-family:inherit;font-size:inherit;line-height:inherit;white-space:pre;\"><span class=\"kw\">from<\/span> openai <span class=\"kw\">import<\/span> AzureOpenAI\n<span class=\"kw\">import<\/span> json\n<span class=\"kw\">import<\/span> re\n\nclient = AzureOpenAI(\n    azure_endpoint=AZURE_ENDPOINT,\n    api_key=AZURE_API_KEY,\n    api_version=<span class=\"str\">\"2024-02-01\"<\/span>,\n)\n\nSYSTEM_PROMPT = <span class=\"str\">\"\"\"\nYou are a structured data extraction engine for steel products.\nExtract every steel product and its quantity from the email.\nRules:\n- Return ONLY valid JSON\n- Format: {\"product_name\": quantity_or_null}\n- Quantities are integers (tonnes)\n- If no quantity \u2192 null\n- No explanations, no text outside JSON\n\"\"\"<\/span>\n\n<span class=\"kw\">def<\/span> extract_products(email_body: str) -> dict:\n    response = client.chat.completions.create(\n        model=<span class=\"str\">\"YOUR_DEPLOYMENT_NAME\"<\/span>,  <span class=\"cmt\"># Azure: deployment name, not model name<\/span>\n        temperature=0,\n        messages=[\n            {<span class=\"str\">\"role\"<\/span>: <span class=\"str\">\"system\"<\/span>, <span class=\"str\">\"content\"<\/span>: SYSTEM_PROMPT},\n            {<span class=\"str\">\"role\"<\/span>: <span class=\"str\">\"user\"<\/span>,   <span class=\"str\">\"content\"<\/span>: email_body},\n        ],\n    )\n    raw = response.choices[0].message.content\n    <span class=\"cmt\"># safer JSON extraction<\/span>\n    match = re.search(r<span class=\"str\">\"\\{.*\\}\"<\/span>, raw, re.DOTALL)\n    <span class=\"kw\">if not<\/span> match:\n        <span class=\"kw\">raise<\/span> ValueError(f<span class=\"str\">\"Invalid JSON response: {raw}\"<\/span>)\n    <span class=\"kw\">return<\/span> json.loads(match.group())\n<\/pre>\n        <\/div>\n\n        <div class=\"section-header\">\n            <h2>Tool calling &amp; agentic systems<\/h2>\n            <div class=\"sh-line\"><\/div>\n            <div class=\"sh-badge\">LLM that acts<\/div>\n        <\/div>\n        <p class=\"body\">\n            Beyond simple inference, I build agentic workflows where the LLM decides \n            <em>which tools to call<\/em>\n             and in what order &mdash; dynamically routing through a pipeline based on the content of the input. This is qualitatively different from a fixed pipeline: the model reasons about the task and selects the appropriate execution path.\n        <\/p>\n\n        <div class=\"tech-grid\">\n            <div class=\"tech-card\">\n                <div class=\"tc-dot\"><\/div>\n                <div class=\"tc-label\">Framework<\/div>\n                <div class=\"tc-name\">LangChain<\/div>\n                <div class=\"tc-note\">Chain composition, tool binding, memory management. Used for single-agent, multi-step workflows.<\/div>\n            <\/div>\n            <div class=\"tech-card\">\n                <div class=\"tc-dot\"><\/div>\n                <div class=\"tc-label\">Framework<\/div>\n                <div class=\"tc-name\">LangGraph<\/div>\n                <div class=\"tc-note\">Graph-based agentic flows with explicit state machines. Used where branching logic and loops are required.<\/div>\n            <\/div>\n            <div class=\"tech-card\">\n                <div class=\"tc-dot\"><\/div>\n                <div class=\"tc-label\">Native API<\/div>\n                <div class=\"tc-name\">OpenAI Tool Calling<\/div>\n                <div class=\"tc-note\">Direct function calling via Azure OpenAI API. Lower latency, full control over tool schemas.<\/div>\n            <\/div>\n            <div class=\"tech-card\">\n                <div class=\"tc-dot\"><\/div>\n                <div class=\"tc-label\">Native API<\/div>\n                <div class=\"tc-name\">Claude Tool Use<\/div>\n                <div class=\"tc-note\">Anthropic&#8217;s native tool use API. Evaluated for agentic document analysis where instruction following precision matters.<\/div>\n            <\/div>\n            <div class=\"tech-card\">\n                <div class=\"tc-dot\"><\/div>\n                <div class=\"tc-label\">Runtime<\/div>\n                <div class=\"tc-name\">Ollama API<\/div>\n                <div class=\"tc-note\">Local REST API compatible with OpenAI client libraries. Enables tool-calling workflows without cloud dependency.<\/div>\n            <\/div>\n            <div class=\"tech-card\">\n                <div class=\"tc-dot\"><\/div>\n                <div class=\"tc-label\">Pattern<\/div>\n                <div class=\"tc-name\">ReAct pattern<\/div>\n                <div class=\"tc-note\">Reason &rarr; Act &rarr; Observe loop. Used for multi-step tasks where intermediate results inform next actions.<\/div>\n            <\/div>\n        <\/div>\n\n        <div class=\"callout\">\n            <strong>At ArcelorMittal Luxembourg (2024):<\/strong>\n             built a full agentic pipeline &mdash; the LLM received a new client inquiry, called a tool to retrieve matching historical orders from an internal API, reasoned over the results, and generated a personalised email offer. The entire flow ran without human intervention, achieving ~60% accuracy and significantly reducing sales team response times.\n        <\/div>\n\n        <div class=\"section-header\">\n            <h2>RAG &mdash; Retrieval-Augmented Generation<\/h2>\n            <div class=\"sh-line\"><\/div>\n            <div class=\"sh-badge\">grounding the model<\/div>\n        <\/div>\n        <p class=\"body\">LLMs hallucinate when asked about data they were not trained on &mdash; internal product catalogues, historical order data, company-specific documents. RAG solves this by retrieving relevant context at inference time and injecting it into the prompt. The model reasons over real, current data rather than its training weights.<\/p>\n\n        <div class=\"rag-diagram\">\n            <div class=\"pipeline-row\">\n                <div class=\"pipeline-col\">\n                    <div class=\"pipe-step hl\">Query<\/div>\n                    <div class=\"rag-label\">user \/ system<\/div>\n                <\/div>\n                <div class=\"pipe-arrow\">&rarr;<\/div>\n                <div class=\"pipeline-col\">\n                    <div class=\"pipe-step\">Embed query<\/div>\n                    <div class=\"rag-label\">text-embedding-3<\/div>\n                <\/div>\n                <div class=\"pipe-arrow\">&rarr;<\/div>\n                <div class=\"pipeline-col\">\n                    <div class=\"pipe-step hl\">Vector search<\/div>\n                    <div class=\"rag-label\">Chroma \/ Pinecone<\/div>\n                <\/div>\n                <div class=\"pipe-arrow\">&rarr;<\/div>\n                <div class=\"pipeline-col\">\n                    <div class=\"pipe-step\">Top-k chunks<\/div>\n                    <div class=\"rag-label\">retrieved context<\/div>\n                <\/div>\n                <div class=\"pipe-arrow\">&rarr;<\/div>\n                <div class=\"pipeline-col\">\n                    <div class=\"pipe-step hl\">Augmented prompt<\/div>\n                    <div class=\"rag-label\">context + query<\/div>\n                <\/div>\n                <div class=\"pipe-arrow\">&rarr;<\/div>\n                <div class=\"pipeline-col\">\n                    <div class=\"pipe-step\">GPT-4o \/ Claude<\/div>\n                    <div class=\"rag-label\">grounded answer<\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <div class=\"tag-cloud\">\n            <span class=\"tag primary\">RAG architecture<\/span>\n            <span class=\"tag primary\">Chunking strategies<\/span>\n            <span class=\"tag primary\">Vector embeddings<\/span>\n            <span class=\"tag primary\">Semantic search<\/span>\n            <span class=\"tag\">Chroma<\/span>\n            <span class=\"tag\">Pinecone (conceptual)<\/span>\n            <span class=\"tag\">Context window optimisation<\/span>\n            <span class=\"tag\">Retrieval evaluation<\/span>\n            <span class=\"tag\">Hybrid search (BM25 + vector)<\/span>\n            <span class=\"tag\">Re-ranking<\/span>\n        <\/div>\n\n        <div class=\"section-header\">\n            <h2>Risk classifier &mdash; ML meets LLM<\/h2>\n            <div class=\"sh-line\"><\/div>\n            <div class=\"sh-badge\">ING GKYC project<\/div>\n        <\/div>\n        <p class=\"body\">At ING, I built and maintained a risk assessment classifier used for Customer Due Diligence (CDD) &mdash; estimating organisational risk across financial security, fraud, misappropriation, and harmful entity detection. This was a traditional ML pipeline (Scikit-Learn) but required the same discipline as LLM work: careful feature engineering, iterative retraining as business rules evolved, and rigorous validation against regulatory requirements.<\/p>\n        <p class=\"body\">A critical real-world constraint emerged: the model&#8217;s statistical decisions could not be taken directly to production without business approval. Patterns that the classifier learned implicitly had to be formalised into explicit, deterministic rule sets &mdash; human-readable logic that the business could review, challenge, and sign off on. In practice, this meant working back from the model&#8217;s behaviour to codify its reasoning as manual rules, which were then implemented alongside the ML layer. This experience sharpened my understanding of the gap between model accuracy and operational trustworthiness &mdash; a lesson that directly shapes how I design LLM output validation and human-review lanes today.<\/p>\n        <p class=\"body\">This background in ML classification directly informs how I design LLM-based classification tasks today &mdash; treating prompt + model as a classifier, measuring precision\/recall, and building human-review lanes for low-confidence outputs.<\/p>\n\n        <div class=\"tag-cloud\">\n            <span class=\"tag primary\">Scikit-Learn classifiers<\/span>\n            <span class=\"tag primary\">Feature engineering<\/span>\n            <span class=\"tag primary\">ML &rarr; manual rule translation<\/span>\n            <span class=\"tag\">Business sign-off workflows<\/span>\n            <span class=\"tag\">TensorFlow \/ Keras<\/span>\n            <span class=\"tag\">PyTorch<\/span>\n            <span class=\"tag\">Precision \/ recall measurement<\/span>\n            <span class=\"tag\">Iterative retraining<\/span>\n            <span class=\"tag\">Regulatory validation<\/span>\n            <span class=\"tag\">Confidence thresholding<\/span>\n        <\/div>\n\n        <div class=\"section-header\">\n            <h2>Production deployments<\/h2>\n            <div class=\"sh-line\"><\/div>\n            <div class=\"sh-badge\">employer context<\/div>\n        <\/div>\n\n        <div class=\"employer-row\">\n            <div class=\"employer-card\">\n                <div class=\"emp-logo\">\n                    AM\n                    <br>\n                    <span style=\"font-size:8px\">LUX<\/span>\n                <\/div>\n                <div class=\"emp-body\">\n                    <div class=\"emp-name\">ArcelorMittal Luxembourg &mdash; AI Client Offer Generation, 2024<\/div>\n                    <div class=\"emp-desc\">Full agentic LLM pipeline: REST data retrieval from internal order history &rarr; GPT-4o inference with structured prompt &rarr; Pydantic output validation &rarr; personalised email generation &rarr; automated dispatch. Built on Azure OpenAI + LangChain. Achieved ~60% accuracy, significantly reducing sales team workload and response times.<\/div>\n                <\/div>\n            <\/div>\n\n            <div class=\"employer-card\">\n                <div class=\"emp-logo\" style=\"font-size:9px;letter-spacing:-.03em;\">AM<br><span style=\"font-size:7px\">POL<\/span><\/div>\n                <div class=\"emp-body\">\n                    <div class=\"emp-name\">ArcelorMittal Poland &mdash; NCBiR Deep Mining Project<\/div>\n                    <div class=\"emp-desc\">Delivered as part of a grant project for NCBiR (Narodowe Centrum Bada&#324; i Rozwoju &mdash; Poland&#8217;s National Centre for Research and Development). The project focused on Deep Mining &mdash; building an application for analysis of mining processes, token flow tracing within those processes, and comprehensive statistics dashboards. Primary objectives: process optimisation, error detection, and identification of safety weak points. Designed for dual use &mdash; operational deployment within the company as well as reporting to government stakeholders.<\/div>\n                <\/div>\n            <\/div>\n\n            <div class=\"employer-card\">\n                <div class=\"emp-logo\" style=\"font-size:9px;letter-spacing:-.03em;\">AM<br><span style=\"font-size:7px\">POL<\/span><\/div>\n                <div class=\"emp-body\">\n                    <div class=\"emp-name\">ArcelorMittal Poland &mdash; AI Knowledge Sharing, ongoing<\/div>\n                    <div class=\"emp-desc\">Internal workshops and presentations covering AI\/LLM fundamentals and applied topics for non-technical and technical colleagues alike &mdash; including practical prompt engineering, an overview of available models and runtimes, and how LLM-based automation differs from traditional scripting. Part of a broader effort to raise AI literacy across the organisation.<\/div>\n                <\/div>\n            <\/div>\n\n            <div class=\"employer-card\">\n                <div class=\"emp-logo\" style=\"font-size:9px;letter-spacing:-.03em;\">AM<br><span style=\"font-size:7px\">POL<\/span><\/div>\n                <div class=\"emp-body\">\n                    <div class=\"emp-name\">ArcelorMittal Poland &mdash; Resume Filter Kit, 2024&ndash;present &nbsp;<span class=\"status-badge eval\" style=\"vertical-align:middle;\">Proof of concept<\/span><\/div>\n                    <div class=\"emp-desc\">Embedding-based pre-screening pipeline: CV and job postings are independently embedded (text-embedding-3-small), cosine similarity filters out low-match offers before any LLM call is made. Surviving candidates are ranked and surfaced in a Streamlit dashboard with a per-offer match score and gap summary. The embedding pre-filter eliminates ~70&ndash;80% of irrelevant postings at near-zero cost, reserving expensive LLM inference only for genuinely relevant offers. Foundation for a future LLM layer that will generate targeted CV edits per offer.<\/div>\n                <\/div>\n            <\/div>\n\n            <div class=\"employer-card\">\n                <div class=\"emp-logo\">ING<\/div>\n                <div class=\"emp-body\">\n                    <div class=\"emp-name\">ING Hubs Poland (GKYC) &mdash; Risk Assessment Classifier, 2021&ndash;2023<\/div>\n                    <div class=\"emp-desc\">ML-based risk classifier for Customer Due Diligence. Built, enhanced, and adapted the classifier to reflect evolving business and regulatory requirements. Scikit-Learn core with iterative retraining cycles. A key constraint in a regulated environment: ML model decisions that could not be explained in deterministic terms required business sign-off before going live &mdash; so the classifier&#8217;s learned patterns were progressively translated into explicit, auditable rule sets that the business could review and approve. Direct precursor to LLM-based classification work.<\/div>\n                <\/div>\n            <\/div>\n\n            <div class=\"employer-card\">\n                <div class=\"emp-logo\">ING<\/div>\n                <div class=\"emp-body\">\n                    <div class=\"emp-name\">ING Hubs Poland &mdash; AI Knowledge Sharing, 2021&ndash;2023<\/div>\n                    <div class=\"emp-desc\">Ran internal workshops and presentations on AI and machine learning fundamentals for colleagues across teams &mdash; covering core concepts, practical limitations, and emerging capabilities. Topics ranged from ML basics and model evaluation to applied LLM topics as the technology matured. Focused on building shared understanding of what AI can and cannot reliably do in a regulated financial environment.<\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <div class=\"section-header\">\n            <h2>Resume Filter Kit &mdash; deep dive<\/h2>\n            <div class=\"sh-line\"><\/div>\n            <div class=\"sh-badge\">ArcelorMittal Poland &middot; PoC<\/div>\n        <\/div>\n        <p class=\"body\">\n            Job hunting at scale has the same problem as enterprise search: most of the corpus is irrelevant noise. Sending every posting through a full LLM prompt costs tokens and time. The insight behind this project is to apply a cheap embedding pre-filter first &mdash; exactly the same pattern used in RAG retrieval &mdash; and only engage the model on the small fraction of offers that pass the similarity threshold.\n        <\/p>\n\n        <div class=\"pipeline-visual\">\n            <div class=\"pipeline-row\">\n                <div class=\"pipe-step hl\">CV (text)<\/div>\n                <div class=\"pipe-arrow\">&rarr;<\/div>\n                <div class=\"pipe-step\">Embed CV<\/div>\n                <div class=\"pipe-arrow\">&darr;<\/div>\n                <div class=\"pipe-step hl\">Job postings<\/div>\n                <div class=\"pipe-arrow\">&rarr;<\/div>\n                <div class=\"pipe-step\">Embed offers<\/div>\n                <div class=\"pipe-arrow\">&rarr;<\/div>\n                <div class=\"pipe-step hl\">Cosine similarity<\/div>\n                <div class=\"pipe-arrow\">&rarr;<\/div>\n                <div class=\"pipe-step\">Threshold filter<\/div>\n                <div class=\"pipe-arrow\">&rarr;<\/div>\n                <div class=\"pipe-step hl\">Ranked shortlist<\/div>\n                <div class=\"pipe-arrow\">&rarr;<\/div>\n                <div class=\"pipe-step\">Streamlit dashboard<\/div>\n            <\/div>\n        <\/div>\n\n        <p class=\"body\">\n            The pre-filter is intentionally model-agnostic and runs in milliseconds per offer &mdash; no API round-trip, no prompt, just vector arithmetic. This makes it practical to run against hundreds of scraped postings without meaningful cost. The Streamlit output layer shows each offer ranked by similarity score alongside a short gap summary, so the human reviewer immediately sees <em>why<\/em> an offer scored high or low, not just that it did.\n        <\/p>\n\n        <div class=\"callout\">\n            <strong>Why embedding before LLM?<\/strong> A typical job search might surface 200 postings per week. Running all 200 through a GPT-4o prompt costs ~$2&ndash;4 and takes minutes. The embedding pre-filter cuts that to 20&ndash;40 genuinely relevant offers in under a second, then the LLM operates on a clean, relevant set. Cost drops by ~80%. This is the same economics that make RAG viable at enterprise scale &mdash; retrieval is cheap, generation is expensive.\n        <\/div>\n\n        <div class=\"section-header\">\n            <h2 style=\"font-size:1rem;\">Planned next layer &mdash; LLM-driven CV adaptation<\/h2>\n            <div class=\"sh-line\"><\/div>\n            <div class=\"sh-badge\">roadmap<\/div>\n        <\/div>\n        <p class=\"body\">\n            The embedding pre-filter is the foundation. The next layer will pass shortlisted offers and the current CV into an LLM prompt that identifies specific gaps (missing keywords, under-represented skills, tone mismatches) and generates targeted, per-offer suggestions for CV sections to rewrite. The output will be a ranked list of offers, each paired with a concrete, actionable edit brief &mdash; not generic advice, but diff-style suggestions tied to the specific language of that posting.\n        <\/p>\n\n        <div class=\"pipeline-visual\">\n            <div class=\"pipeline-row\">\n                <div class=\"pipe-step\">Shortlisted offers<\/div>\n                <div class=\"pipe-arrow\">&rarr;<\/div>\n                <div class=\"pipe-step hl\">LLM: gap analysis<\/div>\n                <div class=\"pipe-arrow\">&rarr;<\/div>\n                <div class=\"pipe-step\">Per-offer edit brief<\/div>\n                <div class=\"pipe-arrow\">&rarr;<\/div>\n                <div class=\"pipe-step hl\">CV section rewrites<\/div>\n                <div class=\"pipe-arrow\">&rarr;<\/div>\n                <div class=\"pipe-step\">Streamlit review UI<\/div>\n            <\/div>\n        <\/div>\n\n        <div class=\"tag-cloud\">\n            <span class=\"tag primary\">Embedding pre-filter<\/span>\n            <span class=\"tag primary\">Cosine similarity ranking<\/span>\n            <span class=\"tag primary\">text-embedding-3-small<\/span>\n            <span class=\"tag primary\">Semantic job matching<\/span>\n            <span class=\"tag primary\">Streamlit dashboard<\/span>\n            <span class=\"tag\">Token-cost optimisation<\/span>\n            <span class=\"tag\">Similarity threshold tuning<\/span>\n            <span class=\"tag\">Gap analysis (roadmap)<\/span>\n            <span class=\"tag\">CV diff generation (roadmap)<\/span>\n            <span class=\"tag\">Structured output (roadmap)<\/span>\n        <\/div>\n\n        <div class=\"section-header\">\n            <h2>Full stack<\/h2>\n            <div class=\"sh-line\"><\/div>\n            <div class=\"sh-badge\">everything I use<\/div>\n        <\/div>\n        <div class=\"tag-cloud\">\n            <span class=\"tag primary\">Azure OpenAI (GPT-4, GPT-4o)<\/span>\n            <span class=\"tag primary\">Anthropic Claude (Sonnet \/ Opus \/ Haiku)<\/span>\n            <span class=\"tag primary\">Mistral Large \/ Mixtral<\/span>\n            <span class=\"tag primary\">Ollama &mdash; Llama 3 \/ Mistral \/ Phi-3 \/ Gemma 2<\/span>\n            <span class=\"tag primary\">LangChain<\/span>\n            <span class=\"tag primary\">LangGraph<\/span>\n            <span class=\"tag primary\">Prompt engineering<\/span>\n            <span class=\"tag primary\">Tool calling \/ function calling<\/span>\n            <span class=\"tag primary\">RAG architecture<\/span>\n            <span class=\"tag primary\">Embedding pre-filter (Resume Filter Kit)<\/span>\n            <span class=\"tag primary\">Cosine similarity ranking<\/span>\n            <span class=\"tag\">Pydantic (output validation)<\/span>\n            <span class=\"tag\">Chroma<\/span>\n            <span class=\"tag\">Pinecone<\/span>\n            <span class=\"tag\">Mistral Embed<\/span>\n            <span class=\"tag\">Phi-3 (via Ollama)<\/span>\n            <span class=\"tag\">Gemma 2 (via Ollama)<\/span>\n            <span class=\"tag\">Scikit-Learn<\/span>\n            <span class=\"tag\">TensorFlow \/ Keras<\/span>\n            <span class=\"tag\">PyTorch<\/span>\n            <span class=\"tag\">Pandas (data prep)<\/span>\n            <span class=\"tag\">Azure Blob Storage<\/span>\n            <span class=\"tag\">REST API integration<\/span>\n            <span class=\"tag\">Streamlit (output layer)<\/span>\n            <span class=\"tag\">Jenkins CI\/CD<\/span>\n            <span class=\"tag\">Git<\/span>\n        <\/div>\n\n        <div class=\"footer-note\">\n            <a href=\"mailto:konrad.chmielinski@outlook.com\" style=\"color:#777;text-decoration:none;\">konrad.chmielinski@outlook.com<\/a>\n            <a href=\"https:\/\/www.linkedin.com\/in\/konrad-chmieli\u0144ski-ba568320a\/\" target=\"_blank\" rel=\"noopener noreferrer\" style=\"color:#777;text-decoration:none;\">linkedin.com\/in\/konrad-chmielinski<\/a>\n            <span>Open to remote &middot; Full-time \/ B2B<\/span>\n        <\/div>\n    <\/div>\n<\/body>\n<\/html>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>AI \/ LLM Integration &mdash; Konrad Chmielinski Engineering Blog &middot; Konrad Chmielinski Embedding large language models into production automation workflows &mdash; not as chatbots, but as transformation engines. LLM Engineering Azure OpenAI &middot; LangChain &middot; RAG GPT-4o &middot; Claude &middot; Mistral &middot; Llama &middot; Agentic Katowice, PL &middot; Remote OK There is a wide gap between &#8220;using ChatGPT&#8221; and &#8220;integrating [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":84,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-34","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-skills"],"views":37,"_links":{"self":[{"href":"https:\/\/chmielinski-konrad.info\/index.php\/wp-json\/wp\/v2\/posts\/34","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/chmielinski-konrad.info\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/chmielinski-konrad.info\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/chmielinski-konrad.info\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/chmielinski-konrad.info\/index.php\/wp-json\/wp\/v2\/comments?post=34"}],"version-history":[{"count":10,"href":"https:\/\/chmielinski-konrad.info\/index.php\/wp-json\/wp\/v2\/posts\/34\/revisions"}],"predecessor-version":[{"id":516,"href":"https:\/\/chmielinski-konrad.info\/index.php\/wp-json\/wp\/v2\/posts\/34\/revisions\/516"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/chmielinski-konrad.info\/index.php\/wp-json\/wp\/v2\/media\/84"}],"wp:attachment":[{"href":"https:\/\/chmielinski-konrad.info\/index.php\/wp-json\/wp\/v2\/media?parent=34"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/chmielinski-konrad.info\/index.php\/wp-json\/wp\/v2\/categories?post=34"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/chmielinski-konrad.info\/index.php\/wp-json\/wp\/v2\/tags?post=34"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}