> For the complete documentation index, see [llms.txt](https://karini-ai.gitbook.io/karini-ai-documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://karini-ai.gitbook.io/karini-ai-documentation/agentic-ai-workshops/code-optimization-agent.md).

# Code Optimization Agent

This use case demonstrates an automated workflow that reviews and optimizes SAS scripts based on execution logs. It retrieves code and logs, analyzes them to improve performance and maintainability, and then commits the optimized version to a GitLab repository. The workflow showcases how AI can autonomously enhance code efficiency, ensure version control, and streamline data processing tasks.

## Use Case

Build an intelligent SAS Code Optimization assistant that reviews SAS scripts and their execution logs, generates optimized versions of the code, and commits the changes to a GitLab repository for governed, auditable deployment.

## Prerequisites <a href="#prerequisites" id="prerequisites"></a>

* Access to a GitLab repository containing sample SAS scripts and permissions to create branches/commits.
* Access to the mock SAS command-line wrapper REST API (or equivalent simulated logs and code endpoints).
* Basic familiarity with SAS syntax, Git workflows, and the platform interface.
* Basic familiarity with the platform interface.

## Step 1: Create SAS Reviewer Agent Prompt

1. Navigate to **Prompt Playground** on the left side.
2. Click on **Add new** in top corner on the right side.
3. Click on **Prompt templates** on the right side.
4. Select the **SAS Scripts Retrieval and Reviewer Agent** template.
5. Increase the **Max State Updates from 3 to 20** for complex reasoning.
6. Scroll down to **Agent input box** to add the following test query : "Job id 10002"
7. Ensure that you scroll up to rename your prompt before saving.
8. You will be directed to the **Prompt Playground** and select your prompt:

\[Hint: Please Save your Changes before you navigate away while adding new tools ]

* Click on the Tools tab to configure the following tools:
  1. **Rest API Tool**
     * Click on **Add new** in tools.
     * Enter name as “**Gitlab API tool**”.
     * Enter the **Description** as “Retrieves details from SAS (Statistical Analysis System) files, including content information. Input requires a valid SAS file path. Returns comprehensive file information. Useful for data analysis and SAS file inspection tasks."
     * Select Type: **Rest API**.
     * Add this input schema:

```
    {
    "$schema": "http://json-schema.org/schema#",
    "type": "object",
    "description": "Root configuration object for API requests",
    "properties": {
        "headers": {
            "type": "object",
            "description": "HTTP headers for the request",
            "properties": {
                "PRIVATE-TOKEN": {
                    "type": "string",
                    "description": "Authentication token for API authorization"
                }
            },
            "required": [
                "PRIVATE-TOKEN"
            ]
        },
        "endpoint": {
            "type": "string",
            "description": "Target URL or path for the API request"
        }
    },
    "required": [
        "endpoint",
        "headers"
    ]
}

```

* Enter the required **credentials** provided separately.
* Save the tool.

2. **Rest Api Tool**
   * Click **Add new** in tools.
   * Enter name as “**Job API Tool**”.
   * Enter the **Description** as “Retrieves detailed information about a specific job using its unique job ID. Input requires a valid job identifier. Returns comprehensive job details including status, file URL, and related metadata. Useful for tracking and monitoring job progress or accessing job information.”
   * Select Type: **Rest API**.
   * Add this input schema:

```
   {
    "$schema": "http://json-schema.org/schema#",
    "type": "object",
    "description": "Root object containing API request parameters",
    "properties": {
        "query_params": {
            "type": "object",
            "description": "Container for query parameters used in the request",
            "properties": {
                "job_id": {
                    "type": "string",
                    "description": "Unique identifier for the job being queried"
                }
            },
            "required": [
                "job_id"
            ]
        }
    },
    "required": [
        "query_params"
    ]
}

```

* Enter the required **credentials** provided separately.
* Save the tool.

### Test & Compare :

1. Click on T**est and compare** tab.
2. Select different models \[Hint: Compare **Claude Sonnet 4.5, Claude 3.5 Sonnet V2**, **Claude Haiku 4.5].**
3. Click on **Test** right below.
4. Compare the output of the selected Models.
5. Click on Select as best answer to select the best-performing model as the **Primary Model**.
6. Optionally Select as best answer to assign a **Fallback Model**.
7. Click **Save prompt run** in the right corner.
8. **Save** and **publish** the prompt.

## Step 2: Create SAS Optimizer Agent Prompt

1. Navigate to **Prompt Playground** on the left side.
2. Click on **Add new** in top corner on the right side.
3. Click on **Prompt templates** on the right side.
4. Select the **SAS Script Optimizer** Agent template.
5. Increase the **Max State Updates from 3 to 20** for complex reasoning.
6. Scroll down to **Agent input box** to add the following test query.

```
"{ "job_id": "10002", "file_content": "/\n===============================================================================\nDEMO SAS SCRIPT - DATA PROCESSING\n===============================================================================\nScript: data_processing.sas\nPurpose: Process customer data and generate summaries\nAuthor: Demo Team\nDate: 2024-11-10\n\nINTENTIONAL PERFORMANCE ISSUES:\n- Inefficient loops over datasets\n- Repeated sorts\n- Hardcoded filtering\n- Redundant calculations\n===============================================================================\n/\n\noptions fullstimer pageno=1 linesize=120;\n\n/* Inefficient data read /\ndata work.customer_data;\n set raw.customers;\n if country = \"USA\"; / Hardcoded filter /\nrun;\n\n/ Nested loop example /\ndata work.customer_summary;\n set work.customer_data;\n do i = 1 to 1000; / Dummy loop to simulate inefficiency */\n total\n", "issues": [ { "description": "Inefficient data filtering: The script uses a hardcoded filter (country = \"USA\") in the data step instead of using WHERE clause during initial data read, causing unnecessary I/O", "log_reference": "NOTE: Table WORK.CUSTOMER_DATA created with 1000000 observations." }, { "description": "Performance bottleneck: Multiple index statements detected which may impact performance", "log_reference": "WARNING: Multiple INDEX statements found. Performance may be impacted." }, { "description": "Memory management issue: Hash join implementation without proper memory allocation", "log_reference": "WARNING: Hash join used without proper memory allocation." }, { "description": "Critical join error: Cartesian product in join operation, which could result in exponential data growth", "log_reference": "ERROR: Potential cartesian product detected in join operation." }, { "description": "Resource intensive processing: The SQL procedure took over 15 seconds of real time", "log_reference": "NOTE: PROCEDURE SQL used (Total process time): real time 15.23 seconds cpu time 12.45 seconds" }, { "description": "Inefficient loop structure: The script contains a dummy loop (1000 iterations) that serves no practical purpose and degrades performance", "log_reference": "Script contains 'do i = 1 to 1000;' which is an unnecessary iteration" }, { "description": "NOTE: Script content appears to be truncated in the GitLab response, full review may be incomplete", "log_reference": "Script content ends abruptly at 'total'" } ] }"
```

7. Ensure that you scroll up to rename your prompt before saving.
8. You will be directed to the **Prompt Playground** and select your prompt:

\[Hint: Please Save your Changes before you navigate away while adding new tools ]

* Click on the Tools tab to configure the following tools:
  1. **Rest Api Tool**
     * Click on **Add new** in tools.
     * Enter name as “**JOB Commit Tool**”.
     * Enter the **Description** as “Creates and adds a new commit to a GitLab repository. Requires optimized SAS file content and commit message. Returns commit status and ID upon successful execution. Used for version control when saving changes to GitLab-hosted code repositories.”
     * Select Type: **Rest Api**.
     * Add this input schema:

```
{
    "$schema": "http://json-schema.org/schema#",
    "type": "object",
    "properties": {
        "query_params": {
            "type": "string",
            "description": "URL query parameters for the request"
        },
        "json_data": {
            "type": "object",
            "description": "Container for JSON payload data",
            "properties": {
                "content": {
                    "type": "string",
                    "description": "The main content or body of the data to be processed"
                },
                "commit_message": {
                    "type": "string",
                    "description": "Message describing the purpose or nature of the commit"
                }
            },
            "required": [
                "commit_message",
                "content"
            ]
        }
    },
    "required": [
        "json_data",
        "query_params"
    ]
}

```

* Enter the required **credentials** provided separately.
* &#x20;Save the tool.

### Test & Compare :

1. Click on T**est and compare** tab.
2. Select different models \[Hint: Compare **Claude Sonnet 4.5, Claude 3.5 Sonnet V2**, **Claude Haiku 4.5].**
3. Click on **Test** right below.
4. Compare the output of the selected Models.
5. Click on Select as best answer to select the best-performing model as the **Primary Model**.
6. Optionally Select as best answer to assign a **Fallback Model**.
7. Click **Save prompt run** in the right corner.
8. **Save** and **publish** the prompt.

## Step 3: Create an Agent 2.0 Recipe

1. Navigate to the **Recipes** section.
2. Click **Add New** in the top-right corner to create a new recipe.
3. Configure recipe details:
   1. **Name**: SAS Automation
   2. **Type**: Agent 2.0
4. Set up the workflow :
   1. Drag and drop **Webhook** node
      * From the right-side panel, copy the **Webhook URL** and **Webhook Token** to your notepad for later API use.
      * Select the **Query Method as POST**.
   2. Drag and drop **Start** node:
      * Connect the **Webhook** node to the **Start** node.
   3. Drag and drop **Agent** node:
      1. Label the agent node as **SAS Scripts Retrieval and Reviewer Agent.**
      2. Select your created **SAS Scripts Retrieval and Reviewer Agent prompt** at Step 1.
      3. Scroll down and Set the **Messages** dropdown to **Last Messages**.
      4. Connect the Start node to the **SAS Scripts Retrieval and Reviewer Agent** node.
   4. Again drag and drop Agent node:
      1. Label the agent node as **SAS Script Optimize.**
      2. From the agents dropdown, select your **SAS Script Optimizer** Agent created in Step 2.
      3. Connect the **SAS Scripts Retrieval and Reviewer Agent** node to the **SAS Script Optimizer** Agent node.
      4. Click on **SAS Script Optimize the agent node.**
      5. Scroll down and set the State settings:
         * Messages: Enable Messages
         * Message Context: Node Message
           * Variable: Enter "**question**" as variable.
           * Node: Select SAS Scripts Retrieval and Reviewer Agent.
           * Message: Select Last Message from the dropdown.
   5. Drag and drop **End** node:
      1. Connect the **SAS Script Optimize** Agent node to the **End** node.
5. On the right side, set the **Number of state updates** to a higher value such as 75.
6. Click on the canvas, then select **Save**.
7. Select your recipe from the recipe table.
8. Ensure you click on **Publish** the recipe.
9. By default, the V1 version is deployed once it is published.
10. For subsequent versions, use the Actions button and select Deploy to deploy the new version. \[Hint: Use Actions Button to select Deploy dropdown].

The recipe is shown below

<figure><img src="/files/6RLCrjP8POVrJAapLAn1" alt=""><figcaption></figcaption></figure>

## Step 4: Trigger Workflow via API

1. Open the Linux terminal in your computer.&#x20;
2. Use the following curl command to initiate document processing

&#x20;\[Hint: Ensure CURL command input payload is valid JSON].&#x20;

```
curl -X POST "<Webhook URL from the Webhook Tile>" \
-H "Content-Type: application/json" \
-H "x-api-token: <YOUR API TOKEN>" \
-d '{
    "files": [],
    "input_message": "<job_id>",
    "metadata": {}
}'
```

## Step 5: Monitor and Verify Results

* Navigate to the recipe icon on the LHS toolbar.
* Click on the **Actions** button on the **SAS Automation r**ecipe.
* Select **Webhook History.** Here, you can review the history of all webhook requests along with their inputs, response, status, tokens and detailed traces.
* Review JSON output.

\ <br>

\ <br>

\ <br>

<br>

<br>

\ <br>

<br>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://karini-ai.gitbook.io/karini-ai-documentation/agentic-ai-workshops/code-optimization-agent.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
