
Künstliche Intelligenz ist überall – und jetzt auch im Report Designer. Mit der einfachen Designerfunktion AI$() kannst du die Power von OpenAI oder anderen LLMs direkt in deine List & Label-Berichte einbetten. Klingt gut? Dann schauen wir uns an, wie das funktioniert – und warum es eines deiner neuen Lieblingsfeatures werden könnte.
Lerne das neue AI$-Designerfeature in unserem YouTube-Video kennen oder lies den folgenden Blogartikel:
Eine kleine Designer-Erweiterungsfunktion für einen großen Schritt
Traditionell erlauben es dir die Funktionen von List & Label, Zeichenfolgen zu formatieren, Zahlen zu berechnen oder das Layout zu steuern. Mit der AI$()-Funktion betreten wir ein neues Terrain: Die Idee ist simpel – du übergibst dem KI-Modell einen Prompt und verwendest das Ergebnis direkt im Bericht.
Ob du eine Zusammenfassung, eine Übersetzung oder eine elegantere Formulierung möchtest – AI$() erledigt den Job. Im Hintergrund verbindet sich die Funktion über das Semantic Kernel SDK von Microsoft mit dem OpenAI-Dienst (oder einem anderen unterstützten LLM).
Legen wir mit dem Kerncode los.
So funktioniert es intern
Hier ist die Methode, die den eigentlichen KI-Aufruf durchführt. Die Builder- und Kernel-Objekte könnten hier natürlich zwischengespeichert werden. Du musst nur das Semantic Kernel-Paket zu deiner Anwendung hinzufügen und eine neue Designerfunktion zu deiner ListLabel-Instanz ergänzen.
private async Task<string> GetOpenAIResultAsync(string prompt) { var builder = Kernel.CreateBuilder(); var apiKey = ""; builder.AddOpenAIChatCompletion( modelId: "o4-mini", apiKey: apiKey ); var kernel = builder.Build(); var chatFunction = kernel.CreateFunctionFromPrompt(prompt); var result = await kernel.InvokeAsync(chatFunction); return result.ToString(); }
Da die Funktion asynchron ist, die Auswertung eines Berichts jedoch synchron erfolgen muss (da die Render-Engine das vollständige Ergebnis vor dem Rendern benötigt), brauchen wir eine pseudo-synchrone Umgehungslösung:
private void aiFunction_EvaluateFunction(object sender, EvaluateFunctionEventArgs e) { e.ResultValue = Task.Run(() => GetOpenAIResultAsync(e.Parameter1.ToString())).Result; e.ResultType = LlParamType.String; }
Das funktioniert – aber wiederholte Aufrufe mit demselben Prompt kosten unnötig Zeit und Tokens. Das lässt sich verbessern.
Caching für Geschwindigkeit und Übersicht
Ein einfacher In-Memory-Cache mit einem Dictionary<string, string>
verbessert die Performance erheblich:
private Dictionary<string, string> _llmResults = new(); private void aiFunction_EvaluateFunction(object sender, EvaluateFunctionEventArgs e) { string prompt = e.Parameter1.ToString(); e.ResultType = LlParamType.String; if (_llmResults.TryGetValue(prompt, out var result)) { e.ResultValue = result; return; } string aiResult = Task.Run(() => GetOpenAIResultAsync(prompt)).Result; _llmResults[prompt] = aiResult; e.ResultValue = aiResult; }
Warum nicht asynchron?
Die Berichtserstellung ist ein zeitkritischer Prozess. Jeder Funktionsaufruf muss sofort ein Ergebnis liefern, nicht „irgendwann später“. Auch wenn .NET asynchronen Code zulässt, muss die Auswertelogik von List & Label synchron bleiben, um Dinge wie Zellhöhe oder Seitenumbrüche im Voraus zu bestimmen.
Das macht den Task.Run(...).Result
notwendig – auch wenn er nicht ganz elegant ist. Es ist der Preis, den wir zahlen, um LLMs mit einer für Vorhersagbarkeit konzipierten Render-Engine zu kombinieren.
Was kannst du mit AI$()
tun?
Ein paar praktische Ideen:
- Produktbeschreibungen übersetzen:
AI$("Translate 'Kaffeemaschine mit Thermoskanne' to English")
- Lange Texte zusammenfassen:
AI$("Summarize this: ...")
- Prägnante Titel erzeugen:
AI$("Write a headline for this product: ...")
- Inhalte höflicher formulieren:
AI$("Rephrase: 'Return at your own cost' in a friendlier tone")
- Code-Snippets erzeugen:
AI$("Write a C# code snippet that calculates factorial")
Die Anwendungsmöglichkeiten sind nur durch deine Kreativität – und die Tokenlimits von OpenAI – begrenzt. Hier siehst du, was passiert, wenn ich diesen Blogbeitrag im Designer auf Französisch zusammenfassen lasse:
Fazit
Das Einbetten von KI in List & Label über die AI$()
-Funktion eröffnet neue Horizonte für dynamisches, intelligentes Reporting. Mit dem Semantic Kernel steht dir eine leistungsstarke Abstraktionsschicht zur Verfügung, die sich leicht an neue LLMs, Modelle oder Prompt-Vorlagen anpassen lässt. Dein Copilot im Report Design – nur einen Funktionsaufruf entfernt.
Probiere es aus. Und sag uns, welcher Prompt dich am meisten überrascht oder begeistert hat!