LLM task(s) for generating question descriptions | (ns metabase-enterprise.llm.tasks.describe-question (:require [clojure.set :refer [rename-keys]] [metabase-enterprise.llm.client :as llm-client] [metabase.query-processor.compile :as qp.compile] [metabase.util :as u] [metabase.util.json :as json])) |
Create a data-oriented summary of a question as input to an LLM for summarization. | (defn- question->prompt-data
[{:keys [display visualization_settings dataset_query result_metadata]}]
(let [visualization_settings (u/remove-nils visualization_settings)
{:keys [query]} (qp.compile/compile-with-inline-parameters dataset_query)]
(cond->
{:sql_query query
:display_type display
:column_descriptions (zipmap
(map (some-fn :display_name :name) result_metadata)
(map (some-fn :semantic_type :effective_type) result_metadata))}
(seq visualization_settings)
(assoc :visualization_settings visualization_settings)))) |
Create a human-friendly summary of a card. Returns a map of the form: {:title "Some inferred title" :description "Some inferred description"} | (defn describe-question
[question]
(let [{:keys [visualization_settings] :as description} (question->prompt-data question)
summary-with-prompts (merge description
{:friendly_title "%%FILL_THIS_TITLE_IN%%"
:friendly_summary "%%FILL_THIS_SUMMARY_IN%%"})
json-str (json/encode summary-with-prompts)
client (-> (llm-client/create-chat-completion)
(llm-client/wrap-parse-json
(fn [rsp] (rename-keys rsp {:friendly_title :title
:friendly_summary :description}))))]
(client
{:messages
[{:role "system"
:content
"You are a helpful assistant that fills in the missing \"friendly_title\" and
\"friendly_summary\" keys in a json fragment.
Your summary and title should:
- be concise
- be informative
- be easy to understand by a non-technical audience from a variety of backgrounds
- be discoverable by search engines
- include caveats and limitations from filters (the query clauses) if applicable
- not have caveats stated as fact but rather as suggestions
- not explicitly talk about the visualization type
- not provide any conclusions about the data
You like to occasionally use emojis to express yourself but are otherwise very serious and professional."}
{:role "assistant"
:content (cond-> "The \"display\" key is how I intend to present the final data."
(seq visualization_settings)
(str " The \"visualization_settings\" key has chart settings."))}
{:role "assistant"
:content "The parts you replace are \"%%FILL_THIS_TITLE_IN%%\" and \"%%FILL_THIS_SUMMARY_IN%%\"."}
{:role "assistant"
:content "Return only a json object with the \"friendly_title\" and \"friendly_summary\" fields and nothing else."}
{:role "assistant"
:content "The \"friendly_title\" must be no more than 64 characters long."}
{:role "user"
:content json-str}]}))) |