{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "oofwDwjhdSAg"
      },
      "outputs": [],
      "source": [
        "# Copyright 2024 Google LLC\n",
        "#\n",
        "# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "#     https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "5D6p2h6hc-GM"
      },
      "source": [
        "# ReAct (Reasoning + Acting) + Custom tool for Healthcare NL API + Gemini 2.0 + LangChain"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "hTjlKBVjdXSu"
      },
      "source": [
        "<table align=\"left\">\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/generative-ai/blob/main/gemini/use-cases/healthcare/react_gemini_healthcare_api.ipynb\">\n",
        "      <img width=\"32px\" src=\"https://www.gstatic.com/pantheon/images/bigquery/welcome_page/colab-logo.svg\" alt=\"Google Colaboratory logo\"><br> Run in Colab\n",
        "    </a>\n",
        "  </td>\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://console.cloud.google.com/vertex-ai/colab/import/https:%2F%2Fraw.githubusercontent.com%2FGoogleCloudPlatform%2Fgenerative-ai%2Fmain%2Fgemini%2Fuse-cases%2Fhealthcare%2Freact_gemini_healthcare_api.ipynb\">\n",
        "      <img width=\"32px\" src=\"https://lh3.googleusercontent.com/JmcxdQi-qOpctIvWKgPtrzZdJJK-J3sWE1RsfjZNwshCFgE_9fULcNpuXYTilIR2hjwN\" alt=\"Google Cloud Colab Enterprise logo\"><br> Run in Colab Enterprise\n",
        "    </a>\n",
        "  </td>\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/generative-ai/main/gemini/use-cases/healthcare/react_gemini_healthcare_api.ipynb\">\n",
        "      <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\"><br> Open in Vertex AI Workbench\n",
        "    </a>\n",
        "  </td>\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/use-cases/healthcare/react_gemini_healthcare_api.ipynb\">\n",
        "      <img width=\"32px\" src=\"https://raw.githubusercontent.com/primer/octicons/refs/heads/main/icons/mark-github-24.svg\" alt=\"GitHub logo\"><br> View on GitHub\n",
        "    </a>\n",
        "  </td>\n",
        "</table>\n",
        "\n",
        "<div style=\"clear: both;\"></div>\n",
        "\n",
        "<b>Share to:</b>\n",
        "\n",
        "<a href=\"https://www.linkedin.com/sharing/share-offsite/?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/use-cases/healthcare/react_gemini_healthcare_api.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/8/81/LinkedIn_icon.svg\" alt=\"LinkedIn logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://bsky.app/intent/compose?text=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/use-cases/healthcare/react_gemini_healthcare_api.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/7/7a/Bluesky_Logo.svg\" alt=\"Bluesky logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://twitter.com/intent/tweet?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/use-cases/healthcare/react_gemini_healthcare_api.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/5a/X_icon_2.svg\" alt=\"X logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://reddit.com/submit?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/use-cases/healthcare/react_gemini_healthcare_api.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://redditinc.com/hubfs/Reddit%20Inc/Brand/Reddit_Logo.png\" alt=\"Reddit logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://www.facebook.com/sharer/sharer.php?u=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/use-cases/healthcare/react_gemini_healthcare_api.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg\" alt=\"Facebook logo\">\n",
        "</a>            "
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_t3GIIHmdajp"
      },
      "source": [
        "| | |\n",
        "|-|-|\n",
        "|Author(s) | [Shade EL-Hadik](https://github.com/elhadik) |\n",
        "|Last updated | 29 Jul 2024 |"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "uYjDcU6kaMCO"
      },
      "source": [
        "## Overview\n",
        "\n",
        "Medical coding errors are common and can lead to denied claims, delayed payments, and even patient safety issues. Gen AI can help address these issues by suggesting accurate medical codes, automating tasks, and improving standardization. With a human-in-the-loop approach, this can lead to faster claims processing, better reimbursement, and reduced coder burnout.\n",
        "\n",
        "Google's large language models (LLMs) have the potential to significantly automate the medical coding process, improving both efficiency and accuracy. By first preprocessing medical records using Healthcare APIs to identify and extract relevant terms, patterns, and relationships, we can then leverage LLMs to suggest appropriate codes for diagnoses and procedures based on physician notes and reports. This will not only save coders time and effort but also reduce errors and inconsistencies, leading to improved reimbursement rates and better financial management for healthcare providers.\n",
        "\n",
        "**It is always recommended to have a human-in-the-loop when dealing with medical applications. This Colab is meant to accelerate the medical coding processing and not to fully replace a human coder.**"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Ubh0oZviaMCO"
      },
      "source": [
        "### Intro to Medical Codes\n",
        "\n",
        "Medical coding is the transformation of healthcare diagnoses, procedures, medical services, and equipment into standardized alphanumeric codes. These codes represent specific clinical information in a standardized format, facilitating communication between healthcare providers, payers, and researchers. Medical codes provide data points about diagnoses, procedures, and resource utilization.\n",
        "\n",
        "<iframe width=\"560\" height=\"315\" src=\"https://www.youtube-nocookie.com/embed/fqNBNE_YSro?si=JKaKOWfzdxeFFADe\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>\n",
        "\n",
        "*   **ICD-10 Codes**: International Classification of Diseases, 10th Revision. These are Diagnosis Codes for Conditions Such as Diabetes or Pneumonia.  They Are Also the Codes for Symptoms Such as Headache or Chest Pain.\n",
        "\n",
        "*   **CPT Codes**:  Current Procedural Terminology. These are Procedures Codes that Describe What is Done by the Healthcare Provider, Hospital, etc., such as MRI, Gall Bladder Surgery or Complete Blood Count Lab Test.  CPT Codes are Also Used for Doctor's Office Visits... These CPT Codes are Referred to as E/M Codes for Evaluation and Management Codes.\n",
        "\n",
        "*   **DRG Codes**: Diagnosis Related Groups. DRG Codes are Used for Inpatient Medical Services.  A Hospitalized Patient May Have Multiple ICD-10 Diagnosis Codes and Multiple CPT Codes and these will be 'Rolled Into' One DRG Diagnosis Related Group for that Hospital Stay.\n",
        "\n",
        "*   **HCPCS Codes**: Healthcare Common Procedure Coding System. HCPCS Codes are Also Procedures Codes, but They Are for Procedures that Are Not a Part of the CPT Coding System.  Many Special Medications that are Administered in the Hospital are Coded with a HCPCS Code Because a CPT Code for Them Does Not Exist."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "iKErD909aMCO"
      },
      "source": [
        "### Architecture Diagram\n",
        "\n",
        "![screenshot-2024-01-15-at-12136-pm.png](https://storage.googleapis.com/github-repo/generative-ai/gemini/use-cases/healthcare/react_gemini_healthcare_api/screenshot-2024-01-15-at-12136-pm.png)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "56ZazrrbeFat"
      },
      "source": [
        "## Getting Started"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "4LpzkDU5aMCR"
      },
      "source": [
        "### Install libraries"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "Y39xzdr9a1iG"
      },
      "outputs": [],
      "source": [
        "# Tested with these package versions.\n",
        "%pip install --upgrade google-cloud-aiplatform langchain==0.1.16 langchain-google-vertexai"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "WbdhJW4xaMCR"
      },
      "source": [
        "### Restart current runtime\n",
        "\n",
        "To use the newly installed packages in this Jupyter runtime, you must restart the runtime. You can do this by running the cell below, which will restart the current kernel."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "8-JPNQEYaMCR"
      },
      "outputs": [],
      "source": [
        "# Restart kernel after installs so that your environment can access the new packages\n",
        "import IPython\n",
        "\n",
        "app = IPython.Application.instance()\n",
        "app.kernel.do_shutdown(True)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "C_x9Me45aMCR"
      },
      "source": [
        "<div class=\"alert alert-block alert-warning\">\n",
        "<b>⚠️ The kernel is going to restart. Please wait until it is finished before continuing to the next step. ⚠️</b>\n",
        "</div>\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HJRzS-N7aMCS"
      },
      "source": [
        "### Define Google Cloud project information"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "OPQc9VAXaOpc"
      },
      "outputs": [],
      "source": [
        "PROJECT_ID = \"YOUR_PROJECT_ID\"  # @param {type:\"string\"}\n",
        "LOCATION = \"us-central1\"  # @param {type:\"string\"}"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "O_omzG97c-Ed"
      },
      "source": [
        "### Enable APIs in Google Cloud project"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "lN2xA2OZc7ZC"
      },
      "outputs": [],
      "source": [
        "!gcloud services enable aiplatform.googleapis.com healthcare.googleapis.com --project $PROJECT_ID"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "lN2xA2OZc7ZC"
      },
      "outputs": [],
      "source": [
        "!gcloud config set healthcare/location $LOCATION"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "fzSnVXbEaMCS"
      },
      "source": [
        "### Authenticate your notebook environment (Colab only)\n",
        "\n",
        "If you are running this notebook on Google Colab, run the following cell to authenticate your environment. This step is not required if you are using [Vertex AI Workbench](https://cloud.google.com/vertex-ai-workbench).\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "Ej9TaRzUZ8W8"
      },
      "outputs": [],
      "source": [
        "import sys\n",
        "\n",
        "# Additional authentication is required for Google Colab\n",
        "if \"google.colab\" in sys.modules:\n",
        "    from google.colab import auth\n",
        "\n",
        "    # Authenticate user to Google Cloud\n",
        "    auth.authenticate_user()\n",
        "\n",
        "import vertexai\n",
        "\n",
        "# Initialize Vertex AI\n",
        "vertexai.init(project=PROJECT_ID, location=LOCATION)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "x5LAR1M0aMCS"
      },
      "source": [
        "### Import libraries\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "F948zwebNJbR"
      },
      "outputs": [],
      "source": [
        "import json\n",
        "\n",
        "import google.auth\n",
        "import google.auth.transport.requests\n",
        "from langchain.agents import AgentType, initialize_agent\n",
        "from langchain.tools import StructuredTool\n",
        "from langchain_google_vertexai import VertexAI\n",
        "import matplotlib.pyplot as plt\n",
        "import networkx as nx\n",
        "import pandas as pd\n",
        "import requests\n",
        "\n",
        "# get access token\n",
        "\n",
        "creds, project = google.auth.default()\n",
        "auth_req = google.auth.transport.requests.Request()\n",
        "creds.refresh(auth_req)\n",
        "creds.token"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "rFW_j3wbefsR"
      },
      "source": [
        "## Configure and call Healthcare API\n",
        "\n",
        "*   The [Cloud Healthcare API](https://cloud.google.com/healthcare-api?hl=en) provides industry-standard protocols and formats for ingesting, storing, analyzing, and integrating healthcare data with cloud-based applications. In the section below, we call the Google Healthcare API to preprocess medical records, in this case, a discharge report. Medical records can be unstructured text and are usually hard to read. The Healthcare API can help with this problem by extracting all medical terms from the unstructured text, identifying patterns, and establishing medical relationships."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "Oe3xzsvzc_ZD"
      },
      "outputs": [],
      "source": [
        "# @title Enter the Discharge Report Summary\n",
        "\n",
        "TEXT = \"Most Responsible Diagnosis: COPD Exacerbation  Active Issues Managed in Hospital: Pulmonary edema Microcytic anemia Gout Purpuric rash NYD  Course in Hospital:  Mr. Johnson arrived in the ER from nursing home with a three-day history of worsening shortness of breath, yellow-green sputum, and increased sputum production. He was subsequently diagnosed with a COPD exacerbation and was satting at 84% on 4L O2 by nasal prongs. He was stepped up to BiPAP for 24 hours and prednisone, ciprofloxacin, and around the clock puffers were initiated. By day 2 of admission he was stepped down to oxygen by nasal prongs and QID puffers.  In terms of respiratory complications, Mr. Johnson had a sudden hypoxic resp failure on day 3 of admission. CCOT was involved, but ICU was avoided. He was found to be in pulmonary edema that responded to diuresis. Last documented echo was completed 15 years ago and a repeat echo was ordered to be completed as an outpatient.    Unfortunately on day 4 of admission Mr. Johnson also developed gout in the left MTP. This limited his mobility and contributed to deconditioning for which PT was involved. Also, by day 6 of admission a purpuric rash was noted on the upper and lower extremities, cause was unknown and punch biopsy was performed. The results are still pending. Lastly, upon admission Mr. Johnson was found to have a microcytic anemia. On history Mr. Johnson states he no longer eats much red meat or leafy greens, preferring tea and toast for most of his meals. There was no history of bleeding and previous FOBT testing was normal. Further testing revealed iron deficiency anemia and therapy with ferrous fumarate was initiated.   On day of discharge, Ms. Johnson was on room air but continued to be on Lasix.  Continued Home Medications: Albuterol 2 puffs q 4-6 hours daily Atrovent 2 puffs q 6h ASA 325 mg daily Metoprolol 25 mg BID Atorvastatin 40 mg daily Ramipril 10 mg daily Amlodipine 5 mg daily Metformin 1000 mg BID Terazosin 5 mg qhs Tylenol 325 mg qhs Lactulose 15cc qhs prn Citalopram 20 mg daily Multivitamin  Medications Changes: Ramipril was STOPPED Lasix was STARTED at 20mg PO BID Amlodipine was INCREASED to 10mg daily Ferrous fumarate 325 mg QHS was STARTED  Important Test Results:  CXR completed April 20th 2019 revealed pulmonary edema and enlarged cardiac silhouette Sputum culture collected April 18th 2019 was positive for pseudomonas aeruginosa  Pending Tests or Results: Echo ordered as outpatient Skin biopsy results pending  Follow-up Plans:  We asked the patient to make an appointment with their family MD next week. The patient will follow up in urgent resp clinic in 2-4 weeks time. Since moving to London the patient is not currently followed by a respirologist and since this is the third exacerbation this year a goals of care discussion may be warranted. The patient was also seen by our COPD Navigator Team and arrangements have been made to be seen as an outpatient.\"  # @param{type:\"string\"}"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "INDqdyV_yM-g"
      },
      "source": [
        "![screenshot-2024-01-11-at-14805-pm.png](https://storage.googleapis.com/github-repo/generative-ai/gemini/use-cases/healthcare/react_gemini_healthcare_api/screenshot-2024-01-11-at-14805-pm.png)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "GxQapQpKzfPV"
      },
      "source": [
        "In the below section, we use [`networkx`](https://networkx.org/), a Python Knowledge Graph libary, to visualize the relationships among medical terms that were captured by the Healthcare API. This is to illustrate the relationships that Healthcare API draws among the different medical terms, such as the relation between a medication and the recommend dose frequency, or the relation between a diagnosis and its severity"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "KatMEh0Mdq4n"
      },
      "outputs": [],
      "source": [
        "# @title Visualize Healthcare NLP\n",
        "\n",
        "\n",
        "def healthcare_nl(text: str) -> str:\n",
        "    \"\"\"Sends a REST request to the Healthcare Natural Language API\"\"\"\n",
        "    # Set the API endpoint\n",
        "    url = f\"https://healthcare.googleapis.com/v1/projects/{PROJECT_ID}/locations/{LOCATION}/services/nlp:analyzeEntities\"\n",
        "\n",
        "    # Set the request headers\n",
        "    headers = {\n",
        "        \"Authorization\": f\"Bearer {creds.token}\",\n",
        "        \"X-Goog-User-Project\": PROJECT_ID,\n",
        "        \"Content-Type\": \"application/json\",\n",
        "        \"Accept\": \"application/json\",\n",
        "    }\n",
        "\n",
        "    # Set the request data\n",
        "    data = {\"documentContent\": text, \"licensedVocabularies\": [\"SNOMEDCT_US\", \"ICD10CM\"]}\n",
        "\n",
        "    # Make the API request\n",
        "    response = requests.post(url, headers=headers, data=json.dumps(data))\n",
        "\n",
        "    return response.json()\n",
        "\n",
        "\n",
        "response_json = healthcare_nl(TEXT)\n",
        "\n",
        "# Create DataFrame for entities\n",
        "df = pd.DataFrame.from_records(\n",
        "    [\n",
        "        {\n",
        "            \"ID\": entity[\"mentionId\"],\n",
        "            \"Desc\": f\"{entity['type']} : {entity['text']['content']}\",\n",
        "            \"Type\": entity[\"type\"],\n",
        "            \"Content\": entity[\"text\"][\"content\"],\n",
        "        }\n",
        "        for entity in response_json[\"entityMentions\"]\n",
        "    ]\n",
        ")\n",
        "\n",
        "\n",
        "# Create DataFrame for knowledge graph\n",
        "kg_df = pd.DataFrame.from_records(\n",
        "    [\n",
        "        {\n",
        "            \"source\": df.loc[df[\"ID\"] == relation[\"subjectId\"], \"Desc\"].values[0],\n",
        "            \"target\": df.loc[df[\"ID\"] == relation[\"objectId\"], \"Content\"].values[0],\n",
        "            \"edge\": df.loc[df[\"ID\"] == relation[\"objectId\"], \"Type\"].values[0],\n",
        "        }\n",
        "        for relation in response_json[\"relationships\"]\n",
        "    ]\n",
        ")\n",
        "\n",
        "\n",
        "# Create a directed graph from the DataFrame\n",
        "G = nx.from_pandas_edgelist(\n",
        "    kg_df, \"source\", \"target\", edge_attr=True, create_using=nx.MultiDiGraph()\n",
        ")\n",
        "\n",
        "plt.figure(figsize=(15, 15))\n",
        "\n",
        "\n",
        "# draw the graph\n",
        "nx.draw(\n",
        "    G,\n",
        "    with_labels=True,\n",
        "    pos=nx.kamada_kawai_layout(G),\n",
        "    edge_color=\"silver\",\n",
        "    node_color=\"silver\",\n",
        ")\n",
        "nx.draw_networkx_edge_labels(G, pos=nx.kamada_kawai_layout(G))\n",
        "\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "fq0EID9v93YI"
      },
      "source": [
        "## Use ReAct agent and LangChain custom tools  \n",
        "\n",
        "The section below uses LangChain [ReAct agent](https://python.langchain.com/docs/modules/agents/agent_types/react) (reasoning + actions), which combines chain of thought and tool usage together to reason through comlex tasks by interacting with external systems, in this case external system is the Healthcare API.\n",
        "\n",
        "ReAct-style prompting is currently (Fall 2023) the state-of-the-art for most prompt-driven LLM tasks. When you use plugins or extensions, where an LLM or LLM-based chatbot or system interacts with an external system, you are using a ReAct-style system. In general, any LLM system that reflects up-to-date knowledge is invisibly using ReAct-style functionality under-the-hood.\n",
        "\n",
        "ReAct chains typically have three interleaved parts:\n",
        "\n",
        "- **Thoughts**: Like in chain of thought, these are waypoints, plans, reasoning, etc. generated by the LLM as it makes progress towards the final output.\n",
        "- **Actions**: LLM-generated commands, calls, or instructions to access an external system. The external system may be a tool that provides information, but can also be more general (i.e., the action observes or changes the state of an external system).\n",
        "- **Observations**: A response, feedback, result, etc. from the external system, inserted into an LLM call to generate the next thought.\n",
        "\n",
        "These three steps are repeated until the LLM completes its task.\n",
        "\n",
        "**We are using LangChain ReAct as a quick means for prototyping, but you may also consider other prompting techniques like chain of thought or calling the LLM directly**"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "12s8PGCJ2Sad"
      },
      "outputs": [],
      "source": [
        "# @title Define the prompt\n",
        "\n",
        "prompt = \"\"\"\n",
        "\n",
        "pretend that you are a professional medical coder\n",
        "First:  Pass on the entire text to the list_of_medical_terms tool to find the correct medical terms in the discharge report\n",
        "Second: Find the associated medical codes and their short explanation, for these medical terms that you just retrieved,  and use only the below codes:\n",
        "  1- ICD-10 : International Classification of Diseases, 10th Revision,\n",
        "  2- CPT Codes:  Current Procedural Terminology,\n",
        "  3- DRG Codes: Diagnosis Related Groups.\n",
        "  4- HCPCS Codes: Healthcare Common Procedure Coding System.\n",
        "Third:  Format the output as a JSON object with the following keys:\n",
        "        Code_Type\n",
        "        Code_Value\n",
        "        Code_Explanation\n",
        "\n",
        "\n",
        "\n",
        "\n",
        "   {discharge_report}\n",
        "\n",
        "\n",
        "\n",
        "\n",
        "\n",
        "\n",
        "\n",
        "use the below as an example of the output:\n",
        "\n",
        "  {example}\n",
        "\n",
        "\n",
        "\"\"\"\n",
        "\n",
        "example_output = \"\"\"\n",
        "\n",
        "{'medical_terms': [{'Code_Type': 'ICD-10',\n",
        "   'Code_Value': 'J44.9',\n",
        "   'Code_Explanation': 'COPD with exacerbation'},\n",
        "  {'Code_Type': 'ICD-10',\n",
        "   'Code_Value': 'J96.91',\n",
        "   'Code_Explanation': 'Respiratory failure, unspecified'},\n",
        "  {'Code_Type': 'ICD-10',\n",
        "   'Code_Value': 'J81.0',\n",
        "   'Code_Explanation': 'Pulmonary edema'},\n",
        "  {'Code_Type': 'ICD-10',\n",
        "   'Code_Value': 'D63.81',\n",
        "   'Code_Explanation': 'Microcytic anemia'},\n",
        "  {'Code_Type': 'ICD-10',\n",
        "   'Code_Value': 'M10.9',\n",
        "   'Code_Explanation': 'Gout unspecified'},\n",
        "  {'Code_Type': 'ICD-10',\n",
        "   'Code_Value': 'L98.9',\n",
        "   'Code_Explanation': 'Purpura, unspecified'},\n",
        "  {'Code_Type': 'ICD-10',\n",
        "   'Code_Value': 'B01.2',\n",
        "   'Code_Explanation': 'Pseudomonas aeruginosa infection'},\n",
        "  {'Code_Type': 'ICD-10',\n",
        "   'Code_Value': 'J44.1',\n",
        "   'Code_Explanation': 'Chronic obstructive pulmonary disease'},\n",
        "  {'Code_Type': 'CPT',\n",
        "   'Code_Value': '0005T',\n",
        "   'Code_Explanation': 'Chest radiography, single view, frontal'},\n",
        "  {'Code_Type': 'CPT',\n",
        "   'Code_Value': '95025',\n",
        "   'Code_Explanation': 'Echocardiography, transthoracic'},\n",
        "  {'Code_Type': 'CPT',\n",
        "   'Code_Value': '87650',\n",
        "   'Code_Explanation': 'Skin biopsy, punch'},\n",
        "  {'Code_Type': 'CPT',\n",
        "   'Code_Value': '87209',\n",
        "   'Code_Explanation': 'Sputum culture, routine'},\n",
        "  {'Code_Type': 'CPT',\n",
        "   'Code_Value': '99223-99238',\n",
        "   'Code_Explanation': 'Office or other outpatient visit for the evaluation and management of an established patient...'},\n",
        "  {'Code_Type': 'DRG',\n",
        "   'Code_Value': '896',\n",
        "   'Code_Explanation': 'Cardiac dysrhythmias'},\n",
        "  {'Code_Type': 'DRG', 'Code_Value': '483', 'Code_Explanation': 'Pneumonia'},\n",
        "  {'Code_Type': 'DRG',\n",
        "   'Code_Value': '963',\n",
        "   'Code_Explanation': 'COPD and related conditions'},\n",
        "  {'Code_Type': 'HCPCS',\n",
        "   'Code_Value': 'J7310',\n",
        "   'Code_Explanation': 'Albuterol sulfate inhalation solution'},\n",
        "  {'Code_Type': 'HCPCS',\n",
        "   'Code_Value': 'J3301',\n",
        "   'Code_Explanation': 'Ipratropium bromide inhalation solution'},\n",
        "  {'Code_Type': 'HCPCS',\n",
        "   'Code_Value': 'Q4016',\n",
        "   'Code_Explanation': 'Metformin hydrochloride tablet'},\n",
        "  {'Code_Type': 'HCPCS',\n",
        "   'Code_Value': 'J1800',\n",
        "   'Code_Explanation': 'Metoprolol tartrate tablet'},\n",
        "  {'Code_Type': 'HCPCS',\n",
        "   'Code_Value': 'J0630',\n",
        "   'Code_Explanation': 'Amlodipine besylate tablet'},\n",
        "  {'Code_Type': 'HCPCS',\n",
        "   'Code_Value': 'J1349',\n",
        "   'Code_Explanation': 'Atorvastatin calcium tablet'},\n",
        "  {'Code_Type': 'HCPCS',\n",
        "   'Code_Value': 'J7750',\n",
        "   'Code_Explanation': 'Ramipril tablet'},\n",
        "  {'Code_Type': 'HCPCS',\n",
        "   'Code_Value': 'J3105',\n",
        "   'Code_Explanation': 'ASA enteric coated tablet'},\n",
        "  {'Code_Type': 'HCPCS',\n",
        "   'Code_Value': 'J0305',\n",
        "   'Code_Explanation': 'Citalopram hydrobromide tablet'},\n",
        "  {'Code_Type': 'HCPCS',\n",
        "   'Code_Value': 'J9165',\n",
        "   'Code_Explanation': 'Terazosin hydrochloride tablet'},\n",
        "  {'Code_Type': 'HCPCS',\n",
        "   'Code_Value': 'Q6315',\n",
        "   'Code_Explanation': 'Ferrous fumarate tablet'}]}\n",
        "   \"\"\"\n",
        "\n",
        "prompt = prompt.format(discharge_report=TEXT, example=example_output)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "_JBv1kCs-Syb"
      },
      "outputs": [],
      "source": [
        "# @title Call the LLM and pass on the Healthcare API as a custom tool and show reasoning steps\n",
        "\n",
        "\n",
        "def list_of_medical_terms(text: str) -> list[str]:\n",
        "    \"\"\"Sends a REST request to the given Healthcare API to retrieve medical terms for diagnosis, procedures, medicines, and lab data\"\"\"\n",
        "    # Extract the entities from the response\n",
        "    response_json = healthcare_nl(text)\n",
        "\n",
        "    type_categories = {\n",
        "        \"PROBLEM\",\n",
        "        \"MEDICINE\",\n",
        "        \"MEDICAL_DEVICE\",\n",
        "        \"PROCEDURE\",\n",
        "        \"LABORATORY_DATA\",\n",
        "    }\n",
        "\n",
        "    # Remove duplicates\n",
        "    return list(\n",
        "        {\n",
        "            entity[\"text\"][\"content\"]\n",
        "            for entity in response_json[\"entityMentions\"]\n",
        "            if entity[\"type\"] in type_categories\n",
        "        }\n",
        "    )\n",
        "\n",
        "\n",
        "# Create the custom tool that will call the external system to extract the medical terms from the patient records\n",
        "tools = [StructuredTool.from_function(list_of_medical_terms)]\n",
        "\n",
        "# Create the LLM.\n",
        "# This is the langchain connection to Vertex AI.\n",
        "# Note this depends on vertexai.init\n",
        "llm = VertexAI(model_name=\"gemini-2.0-flash\", max_output_tokens=8042, temperature=0)\n",
        "\n",
        "# Create the ReAct agent.\n",
        "agent = initialize_agent(\n",
        "    tools,\n",
        "    llm,\n",
        "    verbose=True,\n",
        "    max_execution_time=1000,\n",
        "    max_iterations=3,\n",
        "    handle_parsing_errors=True,\n",
        "    agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,\n",
        ")\n",
        "\n",
        "# call the LLM\n",
        "agent.run(prompt)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "phSMh0tf-8mH"
      },
      "outputs": [],
      "source": [
        "# @title Call the LLM and pass on the Healthcare API as a custom tool and DO NOT show reasoning steps\n",
        "\n",
        "agent = initialize_agent(\n",
        "    tools,\n",
        "    llm,\n",
        "    verbose=False,  # Hides reasoning steps\n",
        "    max_execution_time=1000,\n",
        "    max_iterations=3,\n",
        "    handle_parsing_errors=True,\n",
        "    agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "YOgVz321BeBn"
      },
      "source": [
        "*   Repeatedly querying a model with the same prompt and selecting the majority response as the final answer, a technique known as ***self-consistency***, demonstrably improves performance on arithmetic, common sense reasoning, and symbolic tasks."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "-wg2hJ1fgNHj"
      },
      "outputs": [],
      "source": [
        "outputs = []\n",
        "vote = 0\n",
        "final_output: str\n",
        "num_of_attempts = 10\n",
        "\n",
        "# call the LLM\n",
        "for _ in range(num_of_attempts):\n",
        "    tmp = agent.run(prompt)\n",
        "    outputs.append(tmp)\n",
        "    temp_vote = outputs.count(tmp)\n",
        "    if temp_vote > vote:\n",
        "        vote = temp_vote\n",
        "        final_output = tmp\n",
        "\n",
        "print(f\"vote count: {vote}\")\n",
        "print(f\"final_output: {final_output}\")"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "name": "react_gemini_healthcare_api.ipynb",
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
