HomeAbout MeBook a Call

Architecting Advanced AI Logic in Google Workspace with Chain-of-Thought

By Vo Tu Duc
May 05, 2026
Architecting Advanced AI Logic in Google Workspace with Chain-of-Thought

While we’ve automated countless individual tasks, a critical “reasoning gap” prevents our digital tools from achieving true intelligence. Bridging this gap is the key to unlocking the next level of workspace productivity.

image 0

Introduction: The Reasoning Gap in Workspace [Automated Job Creation in Real Time Jobber and Google Sheets Integration from Gmail](https://votuduc.com/Automated-Job-Creation-in-Jobber-from-Gmail-p115606)

For years, [AI Powered Cover Letter Automated Quote Generation and Delivery System for Jobber Engine](https://votuduc.com/AI-Powered-Cover-Letter-Automated Work Order Processing for UPS-Engine-p111092) has been the indispensable glue for the [Automatically create new folders in Google Drive, generate templates in new folders, fill out text automatically in new files, and save info in [Automated Web Scraping with [Multilingual Text-to-Speech Tool with SocialSheet Streamline Your Social Media Posting 123](https://votuduc.com/Multilingual-Text-to-Speech-Tool-with-Google-Workspace-p809282)](https://votuduc.com/Automated-Web-Scraping-with-Google-Sheets-p292968)](https://workspace.google.com/marketplace/app/auto_create_folder_and_files/430076014869) ecosystem. It’s the engine behind countless automations that save us from manual, repetitive work. We’ve all built them: scripts that parse form submissions into Sheets, create calendar events from emails, or generate templated Docs. These automations are powerful, but they share a common trait: they operate on rigid, deterministic logic. If the email subject contains “Invoice,” then apply the “Finance” label. For each row in this Sheet, do that specific thing.

This paradigm works beautifully until it doesn’t. It breaks down the moment a task requires nuance, context, or multi-step deduction—abilities we humans take for granted. How do you automate triaging a customer support request that is simultaneously urgent, references a past ticket, and expresses frustration about a feature that doesn’t exist yet? A mountain of if/else statements can’t capture that complexity. This is the reasoning gap: the chasm between what simple, rule-based automation can do and what truly intelligent, context-aware assistance requires. As we integrate Large Language Models (LLMs) into our workflows, we have the tools to bridge this gap, but it requires more than a simple API call. It requires a new architecture.

The Challenge with Complex Decision-Making in Apps Script

At its core, Apps Script is procedural. It executes a pre-defined set of instructions, step by step. This is its strength and its fundamental limitation when faced with ambiguity. Trying to code for every possible variation of human language or intent results in what’s known as a “combinatorial explosion” of rules. Your code becomes a brittle, unmaintainable web of nested conditions that will inevitably fail when it encounters an unexpected input.

The arrival of powerful LLMs via APIs like the Gemini API seems like the perfect solution. Can’t we just hand off the messy, ambiguous email to the model and ask it, “What should I do with this?”

You can, but the results are often a black box. A simple prompt might yield a brilliant insight one day and a completely unhelpful or wrongly formatted response the next. You’ve simply swapped brittle if/else logic for an unpredictable oracle. To build robust, reliable systems, we can’t just hope for a good output. We need to structure our interaction with the model to make its decision-making process transparent, verifiable, and, most importantly, machine-readable. We need to guide the model to not just give us the answer, but to show its work.

Introducing Chain-of-Thought Prompting as an Architectural Solution

This is where Chain-of-Thought (CoT) prompting evolves from a clever “prompting trick” into a foundational architectural pattern. CoT is a technique that instructs an LLM to break down a complex problem into a series of intermediate, sequential reasoning steps before arriving at a final answer. Instead of asking, “What category does this email belong to?”, you ask, “First, summarize the email’s core request. Second, identify the sentiment of the sender. Third, based on the request and sentiment, determine the priority level. Finally, based on all the above, choose the most appropriate category.”

Why is this an architectural solution?

  1. **Explicitness & Debuggability: It forces the LLM to externalize its reasoning process. The model’s output isn’t just a final answer (“Category: Sales”); it’s a structured narrative of how it reached that conclusion. If the agent makes a mistake, you can inspect its “thoughts” to pinpoint exactly where the logic went astray.

  2. Reliability & Control: By breaking a complex task into smaller, simpler steps, you reduce the likelihood of the model hallucinating or making a logical leap. Each step is more constrained, leading to a more predictable and reliable overall outcome.

  3. Programmability: The structured, step-by-step output of a CoT prompt is not just for human review; it’s for your Apps Script code. You can parse this chain of thought, validate each step, and use the intermediate conclusions to trigger different functions, call other APIs, or update data in a Google Sheet. The LLM becomes a predictable, logical component within your larger automation workflow, not just a creative black box.

By adopting CoT, we transform the LLM from an unpredictable consultant into a transparent and auditable reasoning engine that we can build dependable systems around.

What We Will Build: A Smarter AC2F Streamline Your Google Drive Workflow Agent

Throughout this article, we’ll move from theory to practice. We will architect and build an intelligent agent that lives within Automated Client Onboarding with Google Forms and Google Drive., powered by Apps Script and the Gemini API, using a Chain-of-Thought architecture.

This agent will go far beyond simple email filtering. It will be designed to handle a complex, multi-stage business process: triaging inbound project requests. When a new request arrives in a shared Gmail inbox, our agent will:

  1. Analyze the email content to understand the core request, identify key stakeholders, and extract any deadlines mentioned.

  2. Reason about the request’s urgency and complexity based on the language used.

  3. Consult a Google Sheet as a source of truth to identify the correct project manager based on the request type.

  4. Synthesize this information to formulate a complete action plan.

  5. Act by automatically creating a detailed event in a shared Google Calendar, inviting the correct people, and attaching a pre-filled Google Doc brief for the kickoff meeting.

Crucially, every step of its decision-making process—its “chain of thought”—will be logged, making the agent’s actions completely transparent and debuggable. Let’s get started.

Why Standard Prompts Fail at Complex Tasks

We’ve all been mesmerized by the magic of a simple, one-sentence prompt yielding a surprisingly coherent and useful result from a Large Language Model (LLM). This is the power of zero-shot prompting—asking the model to perform a task it hasn’t been explicitly trained on, simply by describing it. It’s fantastic for straightforward requests like “summarize this text” or “write a professional email.”

However, when you start architecting real-world business logic within Automated Discount Code Management System, you quickly hit a wall. The tasks are rarely simple. They involve multiple data sources, conditional logic, and a sequence of operations. Asking an LLM to handle this complexity in a single, monolithic prompt is like giving a GPS a destination, a list of 10 errands to run along the way in no particular order, and a vague instruction to “be efficient.” The chances of getting the optimal, or even a correct, result are vanishingly small. The magic fades, and you’re left with unreliable, unpredictable, and undebuggable automation.

Limitations of Zero-Shot Prompting for Multi-Step Logic

Zero-shot prompting is fundamentally a “black box” approach. You provide an input, and you get an output. For multi-step tasks, you are implicitly asking the model to perform several distinct cognitive operations without any guidance or structure. This approach is brittle for several key reasons:

  • Implicit Cognitive Load: The model has to infer the entire sequence of steps required to fulfill the request. It must search for data, extract relevant pieces, transform them, apply conditional logic, and then synthesize a final output, all while holding the entire context and intermediate results in its working memory. Any single weak link in this inferred chain can cause the entire process to fail.

  • Error Compounding: A small misinterpretation in the first implicit step (e.g., misunderstanding which emails to search for) cascades and magnifies through subsequent steps. The final output might look plausible but be based on a completely flawed foundation, making it dangerously misleading.

  • Lack of Verifiability: When a simple prompt produces a bad result, how do you debug it? You can’t. You don’t know if the model failed to find the right information, failed to extract it correctly, or failed at the logical reasoning stage. You can only tweak the prompt and hope for a better outcome, which is not a sustainable strategy for building robust applications.

  • Ambiguity Amplification: Business requests are often filled with ambiguity. A prompt that says “find the latest project update” could mean the most recent email, the latest document version, or the last chat message. A zero-shot prompt forces the model to guess, and its guess may not align with the user’s actual intent.

A Concrete Example Where a Simple Prompt Breaks Down

Let’s ground this in a common Automated Email Journey with Google Sheets and Google Analytics scenario. Imagine you want to automate a project management follow-up task.

The Goal: Find the most recent “Project Chimera” weekly summary Google Doc, identify any action items marked as “incomplete,” and draft an email to the listed owners reminding them of the task and its due date.

A seemingly straightforward zero-shot prompt might look like this:


Find the latest Google Doc titled "Project Chimera Weekly Summary". Read the document, identify all action items with the status "incomplete", and for each one, draft a reminder email to the person listed as the owner.

On the surface, this looks like a reasonable request. But let’s dissect the hidden complexity and the likely points of failure:

  1. Search & Disambiguation: How does the model define “latest”? Is it by creation date, last modified date, or a date in the title (e.g., “Project Chimera Weekly Summary - 2023-10-27”)? If multiple documents match, the model has to make an assumption, which could easily be wrong. It might pick a draft version instead of the final one.

  2. Information Extraction: The action items might be in a table, a bulleted list, or embedded in a paragraph. The format could be inconsistent from week to week. The model might fail to parse a specific row in a table, miss a bullet point, or incorrectly extract the owner’s name or due date if the phrasing is slightly different (“Owner: Bob” vs. “Assigned to: Bob”).

  3. State Management: The model has to correctly associate each specific action item with its specific owner and specific due date. With multiple incomplete items, it’s easy for the model to cross-wire the details, assigning Jane’s task to Bob in the final draft.

  4. Composition: While drafting the email is the LLM’s core strength, the principle of “garbage in, garbage out” is absolute. If it picked the wrong document or extracted incorrect information, the perfectly composed email it drafts will be actively harmful, sending incorrect information to your team and eroding trust in your automated system.

The likely result is an automation that works 70% of the time, which is 100% useless for a critical business process. The silent failures are the most dangerous, as you may not realize incorrect reminders are being sent until a deadline is missed.

The Need for Explicit Step-by-Step Reasoning

The failure of the simple prompt reveals a fundamental truth: complex problems are solved by breaking them down. We do this instinctively. We don’t just “handle follow-ups”; we first find the document, then we read it, then we make a list of action items, and then we write our emails.

To build reliable and sophisticated AI logic, we must force the model to externalize this process. We need to shift from implicit assumption to explicit reasoning. This means structuring our interaction with the LLM not as a single question-and-answer session, but as a guided dialogue where we ask the model to perform one discrete step at a time and show its work.

This approach provides three critical advantages:

  1. Decomposition: It forces both the developer and the LLM to focus on one simple, well-defined task at a time (e.g., “Find the Google Drive ID of the document matching this exact title and date format”). This dramatically reduces the cognitive load on the model and increases the success rate of each individual step.

  2. Traceability: By making the model “think out loud,” we gain a transparent audit trail of its reasoning. If the final output is wrong, we can trace the steps back to the exact point of failure. Was the search query wrong? Did the text extraction fail? This turns an undebuggable black box into a clear, maintainable workflow.

  3. Reliability: A final output assembled from a series of verified, successful intermediate steps is exponentially more reliable than one generated by a single, monolithic leap of faith. It allows for error handling, retries, and human-in-the-loop verification at critical junctures.

This need for a structured, transparent, and debuggable reasoning process is precisely what techniques like Chain-of-Thought (CoT) are designed to address. It’s the key to moving beyond simple AI “tricks” and toward architecting robust, enterprise-grade AI-powered solutions.

Deconstructing the Chain-of-Thought (CoT) Pattern

At its core, Chain-of-Thought (CoT) is a prompting technique designed to transform a Large Language Model (LLM) from a simple answer generator into a more robust reasoning engine. Instead of asking the model to jump directly from a complex question to a final answer, CoT compels it to first generate the intermediate, sequential steps of reasoning that a human would take to solve the same problem. This seemingly simple shift has profound implications for the accuracy, reliability, and transparency of AI-driven workflows, especially within the complex, interconnected environment of Automated Google Slides Generation with Text Replacement.

Core Principles: Forcing the LLM to ‘Think Aloud’

The foundational principle of CoT is to make the model’s implicit reasoning process explicit. Think of it as the difference between a student who just writes down “42” as the answer to a complex word problem and a student who shows their work, step-by-step. The latter process is not only more likely to be correct, but it’s also auditable.

This works for several key reasons:

  1. Reduces Cognitive Load: Complex tasks often require holding multiple constraints and pieces of information in context simultaneously. By breaking the problem down, the model can focus its computational resources on a single, smaller logical step at a time. This sequential processing mitigates the risk of the model “forgetting” a crucial detail or making an erroneous logical leap.

  2. Improves Accuracy and Robustness: For any task involving arithmetic, spatial reasoning, multi-step instructions, or causal inference, CoT dramatically improves performance. Each step in the chain builds upon the validated conclusion of the previous one, creating a logical scaffold that guides the model toward a more accurate final output. It’s less about a single, high-stakes prediction and more about a series of lower-stakes, interconnected inferences.

  3. **Enables Debuggability and Error Analysis: This is arguably the most critical benefit for architects and developers. When a direct prompt fails, the output is simply a black-box failure. You know it’s wrong, but you don’t know why. With CoT, the generated “thought process” is a detailed log of the model’s reasoning. You can inspect the chain and pinpoint exactly where the logic went astray. Did it misinterpret a date? Did it fail to identify a key stakeholder from an email? This transparency is invaluable for iterating on and hardening your AI logic.

It’s important to understand that the LLM isn’t actually “thinking” in the human sense. Rather, it’s generating a text sequence that mimics a reasoning process. By doing so, it constrains its own subsequent token generation to be logically consistent with the steps it has already written, statistically increasing the probability of arriving at the correct final answer.

The Anatomy of a CoT System Prompt

A well-structured CoT prompt is more than just adding “think step-by-step” to your query. It’s a carefully crafted set of instructions that defines the task, the reasoning process, and the output format.

Let’s break down the essential components for a Automated Order Processing Wordpress to Gmail to Google Sheets to Jobber task, like summarizing a meeting request from a Gmail thread and creating a structured object for an Apps Script function.

A Standard (Non-CoT) Prompt:


From the email below, extract the meeting topic, attendees, and proposed time.

[Email content here...]

An Advanced CoT Prompt:


You are an intelligent assistant integrated into [Automated Payment Transaction Ledger with Google Sheets and PayPal](https://votuduc.com/Automated-Payment-Transaction-Ledger-with-Google-Sheets-and-PayPal-p291971). Your task is to parse an email thread to identify the key details for a meeting and format them as a JSON object.

Before you provide the final JSON, you must reason through the problem step-by-step inside a <thinking> block.

1.  **Identify the Core Intent:** First, determine if the email is actually proposing a meeting.

2.  **Extract the Topic:** Look for the subject line and keywords like "discuss," "meeting about," "sync on" to determine the meeting's purpose.

3.  **List the Attendees:** Parse the 'To' and 'Cc' fields. Also, scan the email body for any explicitly mentioned names.

4.  **Find the Proposed Time:** Search for specific dates, days of the week, and times (including timezone information if available).

5.  **Construct the Final JSON:** Once all information is gathered, assemble the final JSON object.

Only after the <thinking> block, provide the final output inside a <final_answer> block.

Email Thread:

"""

From: [email protected]

To: [email protected]

Cc: [email protected]

Subject: Sync on Q3 Marketing Launch

Hi Team,

Can we set up a 30-minute meeting to go over the final launch plan for Project Stardust? I'm free tomorrow, Oct 26th, at 2:00 PM EST. Let me know if that works.

Thanks,

Aisha

"""

Anatomy Breakdown:

  1. Role & Goal Definition: You are an intelligent assistant... Your task is to parse an email thread... and format them as a JSON object. This sets the context and the final objective.

  2. The CoT Imperative: Before you provide the final JSON, you must reason through the problem step-by-step... This is the explicit instruction that triggers the CoT behavior.

  3. Prescribed Reasoning Steps: The numbered list provides a clear, repeatable heuristic for the model to follow. This structures its “thinking” and ensures it doesn’t miss a step, making the process more reliable.

  4. Structured Output Delimiters: Using tags like <thinking> and <final_answer> is crucial for automation. Your Genesis Engine AI Powered Content to Video Production Pipeline can now easily parse the model’s output, using the content of <final_answer> for its logic while optionally logging the <thinking> block for debugging purposes.

CoT vs. Few-Shot Prompting: Key Differences and Use Cases

While often used together, Chain-of-Thought and Few-Shot Prompting are distinct techniques that solve different problems. Understanding their differences is key to architecting effective prompts.

Few-Shot Prompting is a technique where you provide the model with several examples (the “shots”) of input-output pairs before giving it the actual query.

  • Mechanism: In-context learning. The model identifies the pattern from your examples and applies that pattern to the new input.

  • **Primary Goal: To guide the format, style, and structure of the output.

  • When to Use:

  • Strict Formatting: When you need a consistently formatted output, like converting natural language into JSON, XML, or a specific Markdown table structure.

  • Classification: Guiding the model to classify text into a predefined set of categories (e.g., “Urgent,” “Spam,” “Inquiry”).

  • Style Mimicry: Teaching the model to respond in a specific tone or voice.

Chain-of-Thought (CoT) Prompting is about instructing the model to generate the reasoning process itself.

  • Mechanism: Eliciting an explicit reasoning path.

  • **Primary Goal: To improve the accuracy and logical soundness of the answer for complex, multi-step problems.

  • When to Use:

  • Multi-Step Logic: Solving word problems, interpreting complex legal clauses, or planning a sequence of actions.

  • Information Synthesis: When a task requires extracting multiple pieces of information from a source document (like a Google Doc) and synthesizing them into a summary or conclusion.

  • **Debugging and Reliability: Any automated workflow where understanding why the AI made a decision is as important as the decision itself.

| Feature | Few-Shot Prompting | Chain-of-Thought (CoT) Prompting |

| --------------------- | ------------------------------------------------------- | --------------------------------------------------------- |

| Core Purpose | Demonstrating the desired output format. | Eliciting the intermediate reasoning steps. |

| Solves For | Consistency, Style, Formatting. | Accuracy, Logic, Transparency. |

| Example Use Case | “Here are 3 emails and their JSON outputs. Now do this one.” | “Analyze this email by thinking step-by-step, then give me the JSON.” |

| Best For | Tasks requiring pattern recognition. | Tasks requiring multi-step reasoning. |

The Ultimate Synergy: Few-Shot CoT

The most powerful approach often involves combining these two techniques. In Few-Shot CoT, the examples you provide to the model don’t just show the final answer; they include the entire chain of thought. This teaches the model not just what to produce, but how to think about the problem to produce it. This hybrid approach is the gold standard for building complex, reliable, and auditable AI logic within your Google Docs to Web automations.

Implementing CoT with Apps Script and the Gemini API

With the theory established, let’s bridge the gap to execution. This is where we roll up our sleeves and translate the Chain-of-Thought concept into a functional solution within the SocialSheet Streamline Your Social Media Posting ecosystem. We’ll use [Architecting Multi Tenant AI Workflows in Building Modular Agentic Apps Script with Gemini Function Calling](https://votuduc.com/architecting-multi-tenant-ai-workflows-in-google-apps-script-p-20260321290501) as our orchestration layer, connecting services like Sheets or Docs to the powerful reasoning capabilities of the Gemini API, hosted on Google Cloud’s Building Self Correcting Agentic Workflows with Vertex AI platform.

Prerequisites: Setting Up Your Google Cloud Project and Gemini API

Before writing a single line of Apps Script, we need to configure the underlying cloud infrastructure. This ensures our script has the authorization and access required to communicate with the Gemini model.

  1. Associate a Google Cloud Project: Your Apps Script project needs to be linked to a standard Google Cloud Platform (GCP) project.
  • Open your Apps Script editor.

  • Click on the Project Settings gear icon (⚙️) on the left sidebar.

  • Under “Google Cloud Platform (GCP) Project,” click “Change project” and enter the project number of an existing GCP project, or follow the link to create a new one. This project will handle billing and API management.

  1. Enable the Vertex AI API: This is the service that hosts and serves the Gemini models.
  • Navigate to the Google Cloud Console.

  • Ensure you have the correct project selected.

  • In the search bar, type “Vertex AI API” and select it.

  • Click the “Enable” button. If it’s already enabled, you’re all set.

  1. Configure OAuth Scopes in Apps Script: To call a Google Cloud API from Apps Script securely, we use the built-in OAuth 2.0 flow. We must explicitly declare the permissions our script needs in its manifest file.
  • In the Apps Script editor, click the App Manifest icon (appsscript.json) on the left sidebar. If it’s not visible, select View > Show manifest file.

  • Add the following scope to the oauthScopes list. This scope grants permission to interact with cloud services associated with the linked GCP project.


{

"timeZone": "America/New_York",

"dependencies": {},

"exceptionLogging": "STACKDRIVER",

"runtimeVersion": "V8",

"oauthScopes": [

"https://www.googleapis.com/auth/script.external_request",

"https://www.googleapis.com/auth/cloud-platform"

]

}

  • Save the manifest file. The first time a user runs the script, they will be prompted to authorize these permissions for their account.

With these prerequisites in place, your Apps Script environment is now primed to make authenticated calls to the Gemini API.

Designing the System Prompt: Injecting the CoT Framework

The prompt is the most critical component of this architecture. A simple query like “Summarize this text” yields a simple answer. A Chain-of-Thought prompt, however, is an explicit set of instructions that guides the model’s reasoning process and, just as importantly, structures its output.

Our goal is to create a prompt that forces the model to perform several analytical steps before delivering the final result, and to package that result in a machine-readable format like JSON.

Let’s consider a practical Workspace scenario: analyzing customer feedback submitted via a Google Form, which populates a Google Sheet.

A Simple, Non-CoT Prompt:

“Analyze this feedback: ‘The new dashboard is really slow to load, and the export button keeps throwing an error. It’s making my reporting impossible.‘”

This might produce a decent summary, but it’s unpredictable and difficult to parse programmatically.

A Superior, CoT-Infused Prompt:


You are an expert support ticket analyst. Your task is to process a piece of user feedback and deconstruct it into a structured JSON object.

Follow these reasoning steps precisely:

1.  **Identify the core components:** Read the feedback and identify distinct issues or topics being discussed.

2.  **Categorize each component:** For each issue, assign a category from the following list: ["Performance", "Bug", "UI/UX", "Feature Request", "General Inquiry"].

3.  **Determine overall sentiment:** Based on the language used, classify the overall sentiment as "Positive", "Negative", or "Neutral".

4.  **Suggest a priority level:** Assign a priority level of "High", "Medium", or "Low" based on the severity and impact described.

5.  **Synthesize a summary:** Write a concise, one-sentence summary of the user's feedback.

6.  **Construct the final output:** Assemble all your findings into a single, valid JSON object. Do not add any commentary, greetings, or text outside of the JSON structure itself.

Feedback to analyze:

"{FEEDBACK_TEXT}"

Your response MUST be only the JSON object.

This prompt is powerful because it:

  • Assigns a Role: “You are an expert support ticket analyst.”

  • Mandates a Step-by-Step Process: It explicitly lists the cognitive steps for the model to follow.

  • Constrains the Output: It provides a fixed list for categories and priority, reducing ambiguity.

  • Demands a Specific Format: It requires a JSON object as the sole output, which is essential for parsing in our code.

Code Walkthrough: Building the Apps Script Function to Call the API

Now, let’s write the Apps Script code to send our CoT prompt and the user’s feedback to the Gemini API.


/**

* Analyzes text using the Gemini API with a Chain-of-Thought prompt.

*

* @param {string} feedbackText The user feedback text to analyze.

* @return {string} The raw JSON string response from the API, or null on error.

*/

function analyzeFeedbackWithCoT(feedbackText) {

// 1. Configuration

const GCP_PROJECT_ID = "your-gcp-project-id"; // <-- Replace with your Project ID

const GCP_LOCATION = "us-central1"; // Or another supported region

const MODEL_ID = "gemini-1.0-pro";

const API_ENDPOINT = `https://${GCP_LOCATION}-aiplatform.googleapis.com/v1/projects/${GCP_PROJECT_ID}/locations/${GCP_LOCATION}/publishers/google/models/${MODEL_ID}:generateContent`;

// 2. Build the CoT Prompt

const prompt = `

You are an expert support ticket analyst. Your task is to process a piece of user feedback and deconstruct it into a structured JSON object.

Follow these reasoning steps precisely:

1.  Identify the core components: Read the feedback and identify distinct issues or topics being discussed.

2.  Categorize each component: For each issue, assign a category from the following list: ["Performance", "Bug", "UI/UX", "Feature Request", "General Inquiry"].

3.  Determine overall sentiment: Based on the language used, classify the overall sentiment as "Positive", "Negative", or "Neutral".

4.  Suggest a priority level: Assign a priority level of "High", "Medium", or "Low" based on the severity and impact described.

5.  Synthesize a summary: Write a concise, one-sentence summary of the user's feedback.

6.  Construct the final output: Assemble all your findings into a single, valid JSON object. Do not add any commentary, greetings, or text outside of the JSON structure itself.

Feedback to analyze:

"${feedbackText}"

Your response MUST be only the JSON object.

`;

// 3. Construct the API Payload

const payload = {

"contents": [

{

"parts": [

{ "text": prompt }

]

}

],

"generationConfig": {

"temperature": 0.2,

"maxOutputTokens": 1024,

}

};

// 4. Set up the API Request Options

const options = {

'method': 'post',

'contentType': 'application/json',

'muteHttpExceptions': true, // Important for custom error handling

'headers': {

'Authorization': `Bearer ${ScriptApp.getOAuthToken()}`

},

'payload': JSON.stringify(payload)

};

// 5. Execute the API Call and Handle Response

try {

const response = UrlFetchApp.fetch(API_ENDPOINT, options);

const responseCode = response.getResponseCode();

const responseBody = response.getContentText();

if (responseCode === 200) {

const candidates = JSON.parse(responseBody).candidates;

if (candidates && candidates.length > 0) {

// Extract the text content, which should be our JSON string

return candidates[0].content.parts[0].text;

} else {

Logger.log("API response was successful but contained no candidates.");

return null;

}

} else {

Logger.log(`API Error: ${responseCode} - ${responseBody}`);

return null;

}

} catch (e) {

Logger.log(`Exception during API call: ${e.toString()}`);

return null;

}

}

Parsing the Structured Output from the LLM’s Reasoning

The final, and most satisfying, step is consuming the model’s structured output. Because we meticulously instructed the model to return only a JSON object, this step becomes trivial and reliable.

If the analyzeFeedbackWithCoT function returns a valid string, we can simply parse it to get a JavaScript object that we can use to update our Google Sheet, create a Trello card, send a Slack notification, or trigger any other workflow.

Here’s how you would orchestrate the call and parse the result, for example, within a Google Sheet context.


/**

* A sample function to be called from a Google Sheet.

* It reads feedback from one cell, calls the Gemini API,

* and writes the parsed results to adjacent cells.

*/

function processActiveCellFeedback() {

const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();

const cell = sheet.getActiveCell();

const feedbackText = cell.getValue();

if (!feedbackText) {

SpreadsheetApp.getUi().alert("Active cell is empty.");

return;

}

// Call our main function to get the raw JSON string from the LLM

const rawJsonResponse = analyzeFeedbackWithCoT(feedbackText);

if (!rawJsonResponse) {

SpreadsheetApp.getUi().alert("Failed to get a response from the AI model. Check logs.");

return;

}

// Use a try...catch block as a safeguard against malformed JSON from the LLM

try {

// Clean the response in case the LLM includes markdown backticks

const cleanedJson = rawJsonResponse.replace(/```json/g, '').replace(/```/g, '').trim();

const parsedData = JSON.parse(cleanedJson);

// Now, use the structured data to update the spreadsheet

// Assumes the columns are: Feedback | Category | Sentiment | Priority | Summary

cell.offset(0, 1).setValue(parsedData.categories.join(', ')); // Example if categories is an array

cell.offset(0, 2).setValue(parsedData.sentiment);

cell.offset(0, 3).setValue(parsedData.priority);

cell.offset(0, 4).setValue(parsedData.summary);

} catch (e) {

Logger.log(`Failed to parse JSON response: ${e.toString()}`);

Logger.log(`Raw Response was: ${rawJsonResponse}`);

SpreadsheetApp.getUi().alert("Error parsing the AI response. It might not be valid JSON.");

}

}

By enforcing a structured, step-by-step reasoning process via the prompt, we’ve successfully transformed the LLM from an unpredictable text generator into a reliable, programmatic data processing engine directly within Speech-to-Text Transcription Tool with Google Workspace.

Use Case: Building an Advanced Email Triage Agent

Theory is great, but let’s get our hands dirty. The quintessential use case for advanced logic in a workspace is managing the relentless flood of email. Simple filters based on keywords or senders are brittle and lack the nuance to understand intent, urgency, and context. A message from a key client with a neutral subject line might be more urgent than an internal email peppered with “URGENT!!!” emojis. This is where a Chain-of-Thought (CoT) powered agent becomes a game-changer.

We’ll build an agent that doesn’t just filter, but reasons about incoming email to categorize and act upon it with a level of sophistication that mimics a human assistant.

Defining the Complex Logic for Email Categorization and Routing

Before we write a single line of code or a single prompt, we must define the operational logic. A common mistake is to jump straight to the AI with a vague goal. Garbage in, garbage out. Let’s define a clear, multi-faceted rule set for our agent, which will act as the “brain” for a busy project manager.

Our goal is to sort emails into one of four categories, each with a corresponding set of actions:

  1. Urgent & Important:
  • Criteria: These are fire-drill emails. They often come from key clients or senior leadership, mention critical issues (e.g., “outage,” “critical bug,” “blocker”), and carry a negative or demanding sentiment. The subject line might contain explicit markers like “Urgent” or “Action Required.”

  • Actions:

  • Apply the [URGENT] label in Gmail.

  • Star the message.

  • Forward a summary to a designated Google Chat space for immediate team visibility.

  1. Important, Not Urgent:
  • Criteria: This is the bulk of productive work. These emails represent tasks that require attention but aren’t immediate emergencies. Examples include requests for status updates, meeting agendas to review, or non-critical feedback from stakeholders. The intent is informational or action-oriented, but without the high-pressure indicators.

  • Actions:

  • Apply the [Follow-Up] label.

  • Move the email out of the inbox and into a specific project folder (e.g., label it Project-Alpha).

  1. Low Priority / FYI:
  • Criteria: These are informational emails that don’t require a direct response. Think company-wide announcements, automated system notifications (e.g., “Jira ticket updated”), or newsletters. They are for awareness, not action.

  • Actions:

  • Immediately archive the message to keep the inbox clean.

  • Apply a [Processed/FYI] label for future searchability.

  1. Spam / Unsolicited:
  • Criteria: Unsolicited marketing pitches, phishing attempts, or clear junk mail that slipped past Gmail’s primary filters. The agent should identify sender patterns, suspicious links, and generic, non-personalized content.

  • Actions:

  • Mark the message as Spam.

  • Move it to the trash.

This detailed logic model is the foundation. It transforms a vague request—“sort my email”—into a concrete specification that we can now translate into a powerful CoT prompt.

Applying the CoT Prompt to Analyze Email Content and Headers

This is where the magic happens. We’ll craft a prompt that instructs the LLM to follow our defined logic step-by-step. A simple prompt like “Categorize this email” would be unreliable. Instead, we force the model to show its work, dramatically improving accuracy and consistency.

The key is to provide the model with structured data and a clear reasoning framework. The input for our LLM will consist of the email’s key headers and its plain-text body.

Here’s what our CoT prompt looks like:


You are an expert email triage assistant for a busy project manager. Your task is to analyze the following email and determine its category and the required actions based on a predefined logic set.

Follow these steps precisely:

Step 1: Analyze the Sender.

- Who is the sender (From header)?

- Is this an internal stakeholder, a known client, a team member, or an unknown external address? Assess their importance.

Step 2: Analyze the Subject Line.

- What is the primary topic?

- Does it contain keywords that indicate urgency (e.g., 'Urgent', 'Action Required', 'Issue') or low priority (e.g., 'FYI', 'Update', 'Newsletter')?

Step 3: Analyze the Email Body's Intent and Sentiment.

- Summarize the core message in one sentence.

- What is the sender asking for? Is there a clear call to action?

- What is the sentiment? Is it positive, neutral, negative, demanding, or panicked?

Step 4: Synthesize and Reason.

- Based on your analysis from steps 1-3, explain your reasoning for the final categorization. Connect the sender's importance, the subject's topic, and the body's intent to make a final judgment.

Step 5: Provide Final Output.

- Output a single, valid JSON object with no additional text before or after it.

- The JSON object must contain three keys: "reasoning" (your detailed synthesis from Step 4), "category" (one of: "Urgent & Important", "Important, Not Urgent", "Low Priority / FYI", "Spam / Unsolicited"), and "suggested_action" (a brief description of the action to take).

EMAIL DATA:

From: "David Chen <[email protected]>"

Subject: "Urgent: Blocker on the Staging Environment Deployment"

Body:

"Hi team,

We've hit a major snag trying to deploy the latest build to staging. The authentication service is failing completely and this is blocking our entire QA cycle for the upcoming release.

We need your immediate attention on this. Can someone from the engineering team please investigate and provide an update ASAP? This is a critical blocker for us.

Thanks,

David"

Expected LLM Output:

The beauty of this approach is the structured, predictable output, perfect for automation.


{

"reasoning": "The sender is identified as a 'critical-client'. The subject line explicitly uses the words 'Urgent' and 'Blocker'. The email body's intent is a direct request for immediate technical investigation, and the sentiment is demanding and panicked, referencing a 'major snag' and 'critical blocker'. This combination clearly indicates the highest level of priority.",

"category": "Urgent & Important",

"suggested_action": "Apply '[URGENT]' label, Star message, and notify team in Google Chat."

}

The reasoning field is invaluable. It’s not just for our benefit; it allows us to debug the AI’s decision-making process. If the agent miscategorizes an email, we can look at the reasoning to understand why and refine the prompt accordingly.

Integrating the Agent with GmailApp for Automated Actions

With the AI’s decision-making codified, the final step is to wire it into Google Workspace using Google Apps Script. This script will act as the orchestrator, fetching emails, calling the LLM, and executing the actions based on the returned JSON.

Here’s the high-level workflow for our processInbox() function:

  1. Trigger: The script is set up with a time-based trigger to run every 5-10 minutes.

  2. Fetch Threads: It uses GmailApp.search('is:inbox is:unread -label:ai-processed') to find new emails that haven’t been touched by our agent yet.

  3. Iterate and Prepare Data: For each thread, it extracts the most recent message’s sender, subject, and plain-text body (message.getPlainBody()).

  4. Call LLM API: It constructs the CoT prompt with the email data and uses UrlFetchApp.fetch() to make a POST request to our chosen LLM’s API endpoint (e.g., Google’s Gemini API via Vertex AI or AI Platform).

  5. Parse and Act: It parses the JSON response from the LLM. A try...catch block is essential here to handle potential API errors or malformed JSON.

  6. Execute Gmail Actions: A switch statement executes the appropriate GmailApp methods based on the category from the JSON.

Here are some illustrative code snippets:


// Inside a function that iterates through Gmail threads

function processThread(thread) {

const message = thread.getMessages()[thread.getMessageCount() - 1]; // Get the latest message

const emailData = {

from: message.getFrom(),

subject: message.getSubject(),

body: message.getPlainBody()

};

// 1. Construct the full CoT prompt (as defined above)

const prompt = buildCoTPrompt(emailData);

// 2. Call the LLM API

const llmResponse = callLlmApi(prompt); // This is a helper function using UrlFetchApp

try {

// 3. Parse the response

const analysis = JSON.parse(llmResponse.getContentText());

// 4. Execute actions based on the category

switch (analysis.category) {

case 'Urgent & Important':

thread.addLabel(GmailApp.getUserLabelByName('[URGENT]'));

message.star();

// Optional: send notification to Google Chat

postToChat('URGENT EMAIL: ' + message.getSubject());

break;

case 'Important, Not Urgent':

thread.addLabel(GmailApp.getUserLabelByName('[Follow-Up]'));

thread.addLabel(GmailApp.getUserLabelByName('Project-Alpha')); // Example project label

thread.moveToArchive();

break;

case 'Low Priority / FYI':

thread.addLabel(GmailApp.getUserLabelByName('[Processed/FYI]'));

thread.moveToArchive();

break;

case 'Spam / Unsolicited':

thread.moveToSpam();

break;

}

// 5. Mark as processed to avoid running again

thread.addLabel(GmailApp.getUserLabelByName('ai-processed'));

Logger.log(`Processed email: "${emailData.subject}" as ${analysis.category}`);

} catch (e) {

Logger.log(`Error processing email: ${emailData.subject}. Error: ${e.toString()}`);

// Optional: Apply an '[AI-Error]' label for manual review

}

}

This integration closes the loop. We’ve moved from a high-level logical definition to a fully automated agent within Google Workspace that uses sophisticated reasoning to manage a user’s inbox far more effectively than any set of manual filters ever could.

Advanced Considerations and Best Practices

Moving beyond the basics of Chain-of-Thought, building production-ready AI systems within Google Workspace requires a rigorous focus on resilience, efficiency, and advanced prompting architectures. A simple CoT prompt might work for a proof-of-concept, but it will inevitably falter when faced with the ambiguity and variability of real-world data. This section covers the critical strategies for hardening your AI logic.

Error Handling and Validating the LLM’s Logical Chain

The core vulnerability of any LLM-based system is its potential for hallucination or logical failure. Even with CoT, the model can produce a reasoning chain that is plausible but incorrect. Simply trusting the final output is a recipe for disaster. Instead, you must treat the LLM’s reasoning as a hypothesis to be verified.

1. Programmatic Chain Validation

The most robust method is to not just consume the final answer, but to programmatically parse and validate the intermediate steps of the CoT output. Your Apps Script code should act as a skeptical supervisor.

  • Extract Key Entities: Design your prompt to output the reasoning chain in a structured format (like numbered steps or even a JSON object). Use regular expressions or JSON parsing in your script to extract the specific pieces of data the LLM identified.

  • Offload Calculations: LLMs are notoriously bad at precise arithmetic. Use CoT to have the model identify and extract the numbers, but perform the actual calculations within your Apps Script code.

Example Scenario: Summing invoice amounts from a Gmail thread.

Bad Practice: Prompting, “Read this email and tell me the total amount.”

Good Practice:

  1. Prompt: “Review this email thread. For each invoice mentioned, create a step listing the invoice number and the amount. Finally, state the total.

*Step 1: Found invoice INV-001 for $152.50.

*Step 2: Found invoice INV-002 for $85.00.

*Final Answer: The total is $237.50.”

  1. Apps Script Logic:

function calculateTotalFromLlmResponse(responseText) {

const regex = /invoice.*?\$(\d+\.?\d*)/gi;

let match;

let total = 0;

// Don't trust the LLM's math. Do it yourself.

while ((match = regex.exec(responseText)) !== null) {

total += parseFloat(match[1]);

}

if (total === 0) {

// The LLM failed to extract any valid amounts.

throw new Error("Could not validate invoice amounts in the reasoning chain.");

}

return total;

}

2. Implementing Self-Correction Prompts

For highly complex tasks, you can build a “review” step directly into your prompt sequence. After the LLM generates its initial CoT and answer, you make a second call (or add a final instruction) asking it to critique its own work.

Prompt Snippet for Self-Correction:

“…

Step 4: Final Answer. Based on the steps above, the key decision is X.

Step 5: Sanity Check. Review the reasoning from Step 1 to Step 3. Is the logic sound? Does it directly address the original request? Are there any contradictions or assumptions made? If an error is found, please state the error and provide a corrected Final Answer.”

This meta-cognitive loop adds latency and cost but can dramatically reduce logical fallacies in mission-critical workflows, like contract analysis in Google Docs or complex scheduling in Calendar.

Optimizing for Performance: Token Count and Latency

Chain-of-Thought is inherently verbose, which directly translates to higher token counts and increased latency. In the interactive context of a Google Workspace add-on, a slow response can ruin the user experience.

  • Strategic Model Selection: Not every task requires your most powerful (and expensive) model. Architect a multi-model system. Use a fast, cheaper model like Gemini 1.5 Flash for simple, high-frequency tasks (e.g., classifying an email). Reserve the more powerful Gemini 1.5 Pro for the complex, CoT-heavy analysis that follows.

  • Context Pruning and Caching: The biggest performance killer is feeding unnecessary context to the model.

  • Pruning: Before calling the LLM, use Apps Script to pre-process your data. Instead of sending an entire 50-page Google Doc, extract only the relevant sections based on user selection or keywords. For a Gmail thread, send the last 3 messages, not all 30.

  • Caching: Use Apps Script’s CacheService to store the results of expensive operations. If a user is working on a document, you can generate and cache a summary or key entity map of the document once. Subsequent requests can use the cached summary instead of re-processing the entire text, dramatically reducing token usage for follow-up questions.

  • **Streaming for Perceived Performance: For user-facing interfaces like a sidebar in Google Sheets or a chatbot in Google Chat, total latency is less important than time-to-first-token. Use a model that supports streaming responses. This allows you to display the CoT reasoning to the user as it’s being generated. The user sees the AI “thinking,” which feels much faster and more engaging than staring at a loading spinner for 10 seconds.

Combining CoT with Other Prompting Patterns for Enhanced Reliability

CoT is a powerful tool, but it’s not a silver bullet. Its true potential is unlocked when you combine it with other established prompting patterns.

  • Few-Shot Prompting + CoT: This is the foundational pattern for reliable CoT. Never assume the model knows what a “good” reasoning chain looks like for your specific use case. Provide 2-3 high-quality examples in your prompt that demonstrate the exact structure, level of detail, and output format you expect. This is the single most effective way to control the model’s behavior.

  • ReAct (Reason and Act): This pattern transforms your LLM from a simple text processor into an active agent that can use tools. This is a paradigm shift for [Architecting a Architecting a Source of Truth Agent for Google Docs and Sheets Syncing Google Docs to Master Sheets](https://votuduc.com/architecting-source-of-truth-agent-syncing-google-docs-to-master-sheets-p-20260321770646). The “chain” now includes not just Thoughts but also Actions (which your Apps Script code executes) and Observations (the results you feed back to the model).

Example: A ReAct flow for finding a contact’s company and scheduling a meeting.

  1. User Request: “Find out what company Jane Doe works for and schedule a 30-min intro call with her for next week.”

  2. LLM Output 1:


{

"thought": "I need to find Jane Doe's contact information first to identify her company. I will use the Contacts tool.",

"action": "ContactsApp.searchContacts",

"action_input": "Jane Doe"

}

  1. Your Apps Script Code: Executes ContactsApp.searchContacts('Jane Doe'), finds the contact, and gets the company name “InnovateCorp”.

  2. Input to LLM (Second Turn):

Observation: "Contact found: Jane Doe, Company: InnovateCorp, Email: [email protected]"

  1. LLM Output 2:

{

"thought": "I have the contact's company and email. Now I need to find an available 30-minute slot on the user's calendar for next week.",

"action": "CalendarApp.findAvailableTimes",

"action_input": "{ duration: 30, week: 'next' }"

}

  1. Your Apps Script Code: Executes a function to find calendar availability and feeds the results back. This continues until the final event is created.
  • Graph-of-Thoughts (GoT) - A Glimpse into the Future: For the most complex, multi-faceted problems (e.g., “Analyze this financial report, cross-reference sales figures with our CRM data in Sheets, and draft three potential marketing strategies in a new Doc”), a single linear chain is too brittle. GoT is an advanced concept where the LLM explores multiple reasoning paths in parallel. It can evaluate the promise of each path, prune dead ends, and merge insights from different chains. Implementing a true GoT system is complex, requiring a sophisticated orchestration layer, but it points to the future of building truly robust and fault-tolerant AI reasoning engines.

Conclusion: Elevating Your Workspace Automations

We’ve journeyed beyond simple, one-shot API calls and into the realm of structured AI reasoning. By architecting solutions with Chain-of-Thought, we fundamentally change the nature of automation within Google Workspace. We move from brittle, often unpredictable scripts to resilient, auditable cognitive workflows. The core transformation is the shift from asking an LLM what the answer is, to instructing it on how to find the answer.

Recap: The Transformative Impact of Structured Reasoning

Before implementing Chain-of-Thought, our automations were powerful but limited. A complex request, like “summarize the key action items from the ‘Project Phoenix’ email thread and its attached documents,” would often fail or hallucinate, as it required multiple cognitive steps. The process was an opaque black box.

By deconstructing this task into a logical chain—1) Find relevant emails, 2) Extract text and attachments, 3) Summarize each document individually, 4) Synthesize a final summary with action items—we achieve several critical breakthroughs:

  • Robustness: Each step is simpler and more focused, dramatically reducing the chance of error. If one step fails, it can be isolated and retried without jeopardizing the entire workflow.

  • Traceability: We gain a clear, step-by-step log of the AI’s “thinking.” This is invaluable for debugging, auditing, and building trust in the system. We can see exactly which document a specific action item was derived from.

  • Complexity Handling: This layered approach allows us to tackle multi-faceted problems that were previously impossible, orchestrating actions across Gmail, Drive, Docs, and Sheets in a single, coherent process.

In essence, we’ve taught our automations not just to act, but to reason. This is the bedrock of building truly intelligent systems.

The Future of Autonomous Agents in Google Workspace

Chain-of-Thought is a foundational step towards the next frontier: truly autonomous agents operating within your Google Workspace environment. While our current CoT implementation follows a pre-defined plan, the next evolution involves agents that can dynamically create, modify, and execute their own plans based on a high-level goal.

Imagine an agent tasked with: “Organize a Q4 planning offsite for the engineering leads.”

Today, we would need to script the entire CoT chain. Tomorrow, the agent itself will reason:

  1. “I need to identify the engineering leads. I’ll query the Google Directory group.”

  2. “I need to check their calendars for mutual availability. I’ll use the Calendar API.”

  3. “I need to propose a venue. I’ll search for ‘corporate offsite venues’ and check reviews.”

  4. “I need to create a budget. I’ll draft a preliminary budget in a Google Sheet based on headcount and venue costs.”

  5. “I need to get approval. I’ll draft an email in Gmail, attach the Sheet, and send it to the department head for review.”

This isn’t science fiction. It’s the logical extension of the principles we’ve discussed. By combining LLMs with tool-use (granting them access to Workspace APIs) and a structured reasoning framework, we are building the precursors to digital colleagues who can manage complex, multi-step projects with minimal human oversight. Your role shifts from being the script-writer to the strategist, defining the goals and guardrails for these powerful new collaborators.

Next Steps: Register for the AI Transformation & Automation Workshop

Reading about these concepts is one thing; implementing them is another. If you’re ready to move from theory to tangible, production-grade solutions, our upcoming workshop is your definitive next step.

The AI Transformation & Automation Workshop is an intensive, hands-on session designed to equip you with the skills to build the sophisticated agents we’ve envisioned. We will go deeper than this article, covering:

  • Advanced CoT Patterns: Explore ReAct (Reasoning and Acting), self-correction loops, and dynamic tool selection.

  • Production-Ready Architecture: Learn how to manage state, handle authentication securely with Service Accounts, and build robust error-handling and logging in Google Apps Script and Cloud Functions.

  • Building Your First Agent: In a live-coding session, you will build and deploy a functional agent that integrates Gmail, Calendar, and Sheets to solve a real-world business problem.

  • Cost & Performance Optimization: Master techniques for [Prompt Engineering for Reliable Autonomous Workspace Agents for Reliable Autonomous Workspace Agents](https://votuduc.com/prompt-engineering-for-reliable-autonomous-workspace-agents-p-20260319404106) and model selection to ensure your solutions are both powerful and cost-effective.

Don’t just automate tasks—build intelligent systems that transform how your organization works. Seats are limited to ensure a high-quality, interactive experience.

Click Here to Reserve Your Spot in the Workshop and Start Building the Future of Work


Tags

Google WorkspaceAIChain-of-ThoughtGoogle Apps ScriptAutomationLLMPrompt Engineering

Share


Previous Article
Architecting Human in the Loop AI Approvals with Google Sheets
Vo Tu Duc

Vo Tu Duc

A Google Developer Expert, Google Cloud Innovator

Stop Doing Manual Work. Scale with AI.

Hi, I'm Vo Tu Duc (Danny), a recognised Google Developer Expert (GDE). I architect custom AI agents and Google Workspace solutions that help businesses eliminate chaos and save thousands of hours.

Want to turn these blog concepts into production-ready reality for your team?
Book a Discovery Call

Table Of Contents

1
Introduction: The Reasoning Gap in Workspace [Automated Job Creation in Real Time Jobber and Google Sheets Integration from Gmail](https://votuduc.com/Automated-Job-Creation-in-Jobber-from-Gmail-p115606)
2
Why Standard Prompts Fail at Complex Tasks
3
Deconstructing the Chain-of-Thought (CoT) Pattern
4
Implementing CoT with Apps Script and the Gemini API
5
Use Case: Building an Advanced Email Triage Agent
6
Advanced Considerations and Best Practices
7
Conclusion: Elevating Your Workspace Automations

Portfolios

AI Agentic Workflows
Cloud Engineering
AppSheet Solutions
Change Management
Strategy Playbooks
Product Showcase
Uncategorized
Workspace Automation

Related Posts

Automate Site Defect Punch Lists with Gemini and Google Chat
May 22, 2026
© 2026, All Rights Reserved.
Powered By

Quick Links

Book a CallAbout MeVolunteer Legacy

Social Media