Blogs

How to Make Large Language Models Suggest Correct Developer Kernel Code

Large language models can be genuinely helpful when writing code. With specialized libraries such as the DK, however, they hallucinate so much that relying on them quickly becomes pointless. The remedy is to give the model dedicated, LLM-friendly indexes and make it use them.

With version 118 we are releasing exactly that. Because our documentation generator is an in-house tool, we were able to produce a structured JSON file (a "sidecar") for every documented item, containing full inheritance information, parameters, a summary of what it does, and example calls. Building JSONL indexes that LLMs understand from these sidecars was then straightforward. We have published these indexes, along with llms.txt files, on our documentation site, so AI tools that crawl the web (such as Google's) should pick them up soon.

You can also pass an index to the LLM directly during a session. From then on hallucinations drop to a minimum and the AI becomes a useful assistant. Full instructions are available at: docs.tatukgis.com/DK11/doc:llmusage

JSONL indexes have one drawback: at several megabytes each, they burn through tokens fast. A better approach is an MCP (Model Context Protocol) server, which returns only the narrowly targeted results for each query. We have published a public MCP server at: https://docs.tatukgis.com/DK/api/mcp (it cannot be opened in a web browser; only MCP clients are supported).

Not every AI tool supports MCP. Claude lets you add MCP servers as "Connectors", while KAI for Embarcadero RAD Studio refers to them directly as MCP.

DK in Claude

Claude Desktop on Mac

Sample conversation with Claude:

Create a procedure to add any layer to the viewer in simplest way.

A generic procedure for Delphi (VCL or FMX). The driver is picked automatically from the path or URL, so it works with any registered format: SHP, TIFF, DXF, GeoPackage, WMS/WMTS URLs, .ttkls, and so on.

uses
  GisTypes, GisLayer, GisRegistredLayers,
  VCL.GisViewerWnd;   // or FMX.GisViewerWnd

function AddLayer( const _gis  : TGIS_ViewerWnd ;
                   const _path : String ;
                   const _name : String = '' ;
                   const _zoom : Boolean = True
                 ) : TGIS_Layer ;
begin
  Result := GisCreateLayer( _name, _path ) ;
  if not Assigned( Result ) then
    raise Exception.CreateFmt( 'Unsupported layer: %s', [ _path ] ) ;
  try
    Result.Open ;
    _gis.Add( Result ) ;
  except
    FreeAndNil( Result ) ;
    raise ;
  end ;

  if _zoom then
    _gis.FullExtent
  else
    _gis.InvalidateWholeMap ;
end ;

Usage:

AddLayer( GIS, 'C:\data\rivers.shp', 'rivers' ) ;
AddLayer( GIS, 'C:\data\ortho.tif' ) ;
if dlgOpen.Execute then AddLayer( GIS, dlgOpen.FileName ) ;
  • GisCreateLayer returns nil when no registered driver recognizes the path.
  • After a successful Add, the viewer owns the layer, so don't free it yourself. The except block frees it only when Open or Add fails.
  • An empty _name makes the path become the layer name.
  • To show a single file and replace everything in the viewer, GIS.Open( path ) is even simpler, but it closes the current project first.
I need it in C#

Works in both WinForms and WPF because it takes the shared IGIS_Viewer interface. InvalidateWholeMap is confirmed in the .NET docs.

using System;
using TatukGIS.NDK;

public static class GisHelper
{
    public static TGIS_Layer AddLayer(
        IGIS_Viewer gis,
        string path,
        string name = "",
        bool zoom = true)
    {
        TGIS_Layer layer = TGIS_Utils.GisCreateLayer(name, path);
        if (layer == null)
            throw new NotSupportedException($"Unsupported layer: {path}");

        try
        {
            layer.Open();
            gis.Add(layer);
        }
        catch
        {
            layer.Dispose();
            throw;
        }

        if (zoom)
            gis.FullExtent();
        else
            gis.InvalidateWholeMap();

        return layer;
    }
}

Usage:

GisHelper.AddLayer(GIS, @"C:\data\rivers.shp", "rivers");
GisHelper.AddLayer(GIS, @"C:\data\ortho.tif");

var dlg = new OpenFileDialog();
if (dlg.ShowDialog() == DialogResult.OK)   // WPF: == true
    GisHelper.AddLayer(GIS, dlg.FileName);
  • After a successful Add, the viewer owns the layer. The catch block disposes it only when Open or Add fails.
  • An empty name gives the layer its default name.
  • For a concrete viewer type, use TatukGIS.NDK.WinForms.TGIS_ViewerWnd or TatukGIS.NDK.WPF.TGIS_ViewerWnd.
What is the difference between SaveAll and SaveData

SaveData saves only the data: shape geometry and attribute values. SaveAll saves the data plus the layer's settings (configuration and transformation). This holds on both the layer and the viewer.

Layer (TGIS_Layer)

  Config file Active transformation Geometry + attributes
SaveData() – – ✔ (then releases mirrored/cached copies)
SaveAll() ✔ if pending ✔ ✔ calls SaveData() when MustSave is true or the layer isn't exportable

Viewer (TGIS_ViewerWnd / IGIS_Viewer)

Method What it saves
GIS.SaveData() Data changes in all layers
GIS.SaveAll() All layers: parameters and data
GIS.SaveProject() Project file only; layer config goes into project or config files. Data is not saved.
// after editing shapes: persist edits only
if (layer.MustSave())
    layer.SaveData();

// before closing: edits + styling/config
GIS.SaveAll();

// full session save: layers + project file
GIS.SaveAll();
GIS.SaveProject();

SaveProject() alone won't write your edits.

Posted: September 28, 2026
Filed under: AI, ChatGPT, Claude, Developer, DK, Gemini, Grok, Kernel, TatukGIS