Writing LookML for Agents and Conversational Analytics

At Google Cloud Next '26, Google hosted a "Agentic analytics for Looker developers" birds of a feather discussion. There I met a ton of developers who were very interested in how conversational analytics improved with differing LookML writing. We learned that longer descriptions and tags helped guide the agent to the right fields and made conversational analytics agents more effective. For this Q&A, I want to open the discussion to identify as a community best practices for writing LookML for agents. Please, join the conversation. Let us know what works and what doesn’t!

Let’s make this the longest thread on the community, because I know a lot of people care about this topic!

Thanks for starting the conversation Chrissie! Our team has found that generating longer, detailed descriptions for our measures and dimensions has really improved our conversational analytics experience. The additional context of detailed descriptions seems to really improve how conversational analytics can understand the prompter’s intent and tie it back to the appropriate fields.

Do you follow a set formula for writing descriptions? And how long / detailed do you make your descriptions? Currently, we inject the descriptions that are used in our data dictionary into our LookML view files (using a Python script), but I wouldn’t say they are detailed. Ours are 1 sentence long for standard fields. For custom fields like calculations, they are 2-3 sentences long, and explain the logic.

For example, here is a typical description for a standard field:

Postal Code = The postal code of the user’s billing address.

I’d be really interested to hear what format works for you when writing descriptions.

I’d also be interested to hear other people’s experience of using synonyms. From our initial testing (and we’re still at an early stage of testing it internally in the data team), we didn’t find that they made a big difference i.e. the agents were able to find the right fields using their own semantic mapping process when we didn’t define synonyms in the LookML. We do have rigorous naming conventions for field names and labels, plus descriptions for about 70% of our fields, so I don’t know if this means synonyms are less important.

I’d love to see examples of a long detailed description. Let me see if I can dig one up from one of our Next talks. I know one of the speakers at Next had really good success with this.

Ruth, your point regarding semantic mapping is spot on. In my own semantic layer builds, I’ve run into those exact same zero-shot limitations all the time. While rigorous naming conventions and labels are table stakes, relying solely on the LLM’s default semantic mapping often breaks down at scale.

Instead of bloating the description parameter (and eating up the agent’s context window), my go-to approach has been to heavily leverage the tags parameter.

I’ve had massive success using the tags array as a dual-purpose routing engine:

  1. As Weighted Synonyms: Injecting highly specific vernacular that our users type in natural language, which might not belong in a clean corporate data dictionary.

  2. For Business Line Context: Scoping dimensions and measures to specific LoBs (Lines of Business).

But the real game-changer during my implementations has been establishing a direct correlation between Looker user_attributes and LookML tags.

Here’s a sanitized example of how I recommend to structure a measure:

measure: total_net_revenue {
    type: sum
    sql: ${TABLE}.gross_revenue - ${TABLE}.refunds ;;
    label: "Total Net Revenue"
    description: "Aggregates the gross revenue minus processed refunds. Used for official GAAP financial reporting. Excludes promotional credits."
    tags: ["topline", "cash_in", "enterprise_sales_b2b", "qbr_metric"]
  }

By passing these tags as metadata, the agent’s semantic routing becomes highly deterministic based on who is asking. If a user with the Looker user_attribute of department: enterprise_sales_b2b prompts the agent with “Show me the topline cash in for Q3”, the agent correlates their user attribute directly to the corresponding tags. It dynamically narrows the semantic search space to fields relevant to their LoB.

This allows us to keep descriptions purely focused on the underlying SQL and math validation, while offloading the synonym mapping and user-specific routing entirely to the tags array.

Has anyone else been correlating user attributes with tags to personalize the agent’s conversational routing?

Thanks for your reply Jose. That sounds like a really good approach.

However, this is not mentioned in the documentation:

  • The page on synonyms specifically says its for use by LLMs, whereas the page on tags says that tags are used for “providing arbitrary metadata about a field to an outside application”.
  • The section on LookML best practices for Conversational Analytics does not mention tags, only labels, descriptions, and synonyms.

What should we use the tag field for when writing LookML for Conversational Analytics? What should go in the tags parameter vs the synonyms parameter?

We are in the process of setting up a pilot, with UAT scheduled to start in mid-July. I am currently writing best practice guides for our Developers, in terms of how to optimise LookML for natural language queries, and how to write agent instructions. I am writing in-house documentation because the official documentation is so scant (see above). I have previously had to take this approach with the Chart Config Editor, which is also chronically undocumented.

The information on agent instructions is particularly scant, and I’ve spent a lot of time researching this independently to find what works. Whilst I understand that Google is devoting its resources right now to developing and iterating releases of conversation analytics as quickly as possible, it has been available for over a year now, and part of the core product for over 6 months. I’m sure I’m not the only customer who is spending hours of my time plugging these knowledge gaps (and potentially missing key pieces of information - like tags). This happens at the expense of onboarding business users and guiding them through what is essentially a paradigm shift in how they get data, and therefore a big change management project.

Like Google, Developers / Admins also have limited resources, and it seems very inefficient that there isn’t proper, centralised documentation. For me, it’s not a technical barrier (data analysts are smart, curious people - we can figure it out), but it’s a time barrier. And this will ultimately effect uptake, no matter how good the technology is (and I must say, data agents since April 2026 are blinking brilliant).

First and foremost—thank you for your candor. You are absolutely right to call this out, the velocity of product evolution in the AI space (especially with the significant leaps we made in the April 2026 Data Agent updates) has unfortunately outpaced our centralized documentation. You also caught a very valid collision point between my previous comment and the official documentation regarding synonyms vs. tags. Let me clarify exactly what I meant by using tags as “Weighted Synonyms,” and why I rely on them over the native parameter.

The crux of it comes down to Probabilistic vs. Deterministic semantic mapping.

1. The synonyms parameter (Probabilistic)

The official documentation is correct: Looker introduced the synonyms parameter as the native, out-of-the-box way to feed alternate vocabulary to the LLM.

  • How it works: This is the LLM’s suggestion box. When you put terms here, the underlying embedding model uses them to gently steer the semantic search. It is probabilistic. The model still weighs those synonyms against its entire pre-trained knowledge base.

  • The Limitation: Sometimes, highly specific internal company jargon gets “lost in the noise” because the LLM doesn’t weigh your native synonym heavily enough against standard global terminology.

2. The tags parameter (Deterministic / “Weighted Synonyms”)

This is where my “Weighted Synonyms” hack comes in. Sometimes, fuzzy matching isn’t good enough—you need a hard, algorithmic rule.

  • How it works: The docs mention tags are for “arbitrary metadata.” In an AI architecture, you can pair tags with explicit Agent Instructions to force the model’s behavior. By writing an instruction like:

    “When mapping user input to fields, heavily prioritize any LookML field where the user’s exact phrasing matches a string in the tags array.”

  • The Result: You have just bypassed the LLM’s probabilistic guessing game. You elevate that tag into a Weighted Synonym, forcing a deterministic exact-match for your most critical, non-negotiable internal jargon.

A Quick Framework for your UAT Developer Guide:

To optimize your semantic layer and prevent AI hallucinations, here is how I recommend your developers partition the metadata:

  • label: The canonical, business-friendly name.

  • synonyms: General, standard vocabulary variations (e.g., mapping revenue to sales). Let the LLM handle these natively out-of-the-box.

  • tags (The Control Engine): Use this for Weighted Synonyms (high-priority, internally specific jargon that MUST map correctly) AND for Business Line Context (scoping fields to specific LoBs via user attributes).

  • description: Keep this strictly focused on underlying mathematical logic, exact definitions, and strict boundaries (e.g., “Excludes promotional credits. Used for official GAAP reporting.”). Do not put synonyms here; use it to anchor the LLM’s analytical reasoning.

Regarding Agent Instructions, you are spot on that it is an under-documented art. Since you are pioneering this internally, I highly recommend leveraging Negative Constraints. LLMs respond beautifully to explicit boundaries. Instructing the agent on what not to do (e.g., “Never aggregate the net_margin dimension using a SUM” or “If the user asks for ‘sales’ but doesn’t specify gross or net, always default to total_net_revenue”) is often more effective than only providing positive instructions.

I am thrilled to hear the agents are performing brilliantly for your team overall, and I commend your rigorous approach to internal governance. That is exactly what makes these rollouts succeed. Best of luck with your UAT in July, and if you hit any roadblocks with your Agent Instructions, please don’t hesitate to reach out!

Hello Jose,

I am posting this here. I believe we are only starting our conversational analytics journey compared to others. At the moment, we are still building up the infrastructure, and there are a few elements I require assistance with.

First of all, a bit of context:

We are using the ADK as a base. Through the ADK, we are able to invoke one of our Looker agents. We initially started using the CA API, using Looker as a source.

The idea behind this is that we would maintain a set of agents that could be used by our users in the Looker UI and through the main agent (ADK).

Challenges I am facing:

Additional question: Is there a way to add some custom parameters to the semantic layer (Explore, View, Dimension, Measure)? I am trying to embed more governance elements (ownership, for example) into the LookML semantic layer.

Hello Alexandre,

Welcome to the conversational analytics journey! It is great to see you building on the Agent Development Kit (ADK) and the Conversational Analytics (CA) API. Moving beyond out-of-the-box UI implementations into an API-first, headless approach is exactly how you unlock enterprise-scale AI. However, you are absolutely right that moving to a programmatic architecture introduces some unique infrastructure and state-management challenges.

Let’s tackle your roadblocks one by one. I’ll actually start with your final question, as it ties perfectly into the semantic routing strategy I was just discussing with Ruth above.

1. Adding Custom Governance Parameters to LookML

This is a brilliant question. LookML is a strictly typed, validated language. If you try to invent arbitrary parameter keys at the root level (e.g., owner: "data_engineering" or data_tier: "gold"), the LookML compiler will throw a syntax error and refuse to save.

However, this brings us right back to the superpower of the tags parameter.

Because the tags parameter accepts an array of arbitrary strings, it is the perfect native vessel for injecting governance metadata without breaking validation. My go-to strategy here is to implement a strict Key:Value String Convention within the tags array at the Explore, View, or Measure level:

LookML
explore: enterprise_revenue {
  label: "Enterprise Revenue"
  
  # Injecting custom governance metadata via Key:Value tags
  tags: [
    "gov_owner:alexandre_mgn", 
    "gov_domain:finance", 
    "gov_tier:certified_gold", 
    "pii:false"
  ]
}

measure: total_net_revenue {
    type: sum
    sql: ${gross_revenue} - ${refunds} ;;
    tags: ["gov_owner:finance_analytics", "dq_score:high"]
}

Why this is so powerful for your ADK setup: When your ADK middleware requests the LookML semantic layer via the API, those tags are exposed in the JSON metadata payload. You can write a lightweight parsing function in your orchestration layer to read the tags array, split the strings by the colon (:), and instantly reconstruct a JSON object containing your custom governance rules. You can then use this to render a “Data Owner” or “Gold Certified” badge in your custom frontend UI, or restrict API routing based on the gov_tier—all while keeping LookML as your single source of truth.

2. Setting up Golden Queries via the API

In a UI-first paradigm, Golden Queries are managed via Looker’s interface. In an API-first architecture, you don’t save them to a UI config panel; you pass them dynamically as a structured JSON payload directly to the CA API.

Here is the pattern to execute this programmatically:

  • The Extraction: Build your perfect “golden” query in the Looker UI. Grab the “share slug” from the URL, and use your ADK to make a GET /queries/slug/{slug} request to the Looker API. This returns the exact, deterministic query metadata (model, explore, fields, filters, etc.).

  • The Payload Schema: You then construct a Golden Query object that pairs a natural_language_questions array (the user prompts) with that looker_query metadata.

  • The Execution: When you invoke the CA API to start a conversation or ask a question, compile your list of Golden Query objects under the looker_golden_queries key in your context payload.

  • Architectural Tip: Don’t pass your entire library of 50 golden queries on every API call (it wastes tokens). Have your ADK perform a quick semantic search to detect the user’s intent, and dynamically inject only the 3-5 most relevant golden queries into the payload.

3. Accessing Conversations made by a Service Account

This is a classic state-management hurdle in headless BI setups. When your ADK uses a Service Account (SA) to authenticate with the Looker API, Looker’s backend binds the resulting conversation_id and history exclusively to that SA’s user_id.

  • For Retrieval / Auditing: You can retrieve the history natively by hitting the /conversations endpoint authenticated as that specific Service Account. Alternatively, you can query Looker’s internal System Activity explores (filtering for the SA’s user ID) to monitor token usage and generated queries.

  • The Architectural Best Practice: Because the SA acts as a monolithic proxy, Looker natively loses the context of which actual end-user in your ADK is asking the question. In a headless setup, I strongly recommend decoupling conversation state management from Looker. Use your ADK middleware to log the user’s prompt, their real internal ID, the conversation_id, and Looker’s API response into your own application database (like BigQuery or Postgresql). This gives you complete control over conversational memory, auditability, and telemetry without fighting proxy-authentication limitations.

You are building exactly the kind of next-generation data architecture we love to see. Keep pushing the envelope. LMK if you need any clarification on parsing those namespaced tags in your ADK!

Ruth, here is the talk I mentioned, but it looks like the descriptions of some of the files they used got cut off of the end. I’m sharing anyway just in case it’s at all helpful.

I will definitely pass this feedback back to our documentation team! Thank you for offering it up.

Thank you for that. I see what you mean about how we can “hack” something like a custom dictionary. I understand the concept, but I feel having a “custom_meta” dictionary as a parameter would be slightly cleaner.
I will definitely see how far I can go with the Tags.

2. Setting up Golden Queries via the API

You are mentioning “Golden Queries are managed via Looker’s interface.” I must have missed something, but it seems I can only pass them as an instruction. I am getting confused because the update agent (Looker API) has golden_query_ids. “golden_query_ids”: “”.`

I can see a POST /golden_queries. I would have imagined I could create a golden query and link it to the Looker Agent. However, I am struggling to make the golden_queries API call.

Regarding your Architectural Tip, I am using the Looker agent (available in the UI) as a tool. I thought the agent defined in Looker has the list of golden queries already defined. Considering this agent will be used both by a user in the UI and by the API, I am not too sure how we can implement that.

We initially built on the CA API, where we have been dynamically injecting the most relevant golden query. But I want to move away from this method by calling a predefined agent in Looker; the idea is to allow users to chat with those agents in Looker. This way, we only have one version of the agent to maintain.

thats very nice

Sameer_ali, welcome to the chat. What did you find nice about the topic? Are you using any of these tools yourself?

Thank you for the detailed information. This is gold :fire: