发布新帖

查找

讨论
· 七月 7, 2023

SAX XML Parser Error during SOAP request serialization (ERROR #6301: SAX XML Parser Error: <MAXSTRING>xeWrite+7)

Hi everyone,

This one had me breaking a sweat 😅

When a SOAP request has a %Stream.GlobalBinary property, it fails to serialize to base64 when stream is larger than ~43MB with 

ERROR #6301: SAX XML Parser Error: <MAXSTRING>xeWrite+7^%occXMLInternal

Unless you enable the following parameters :  

Parameter BASE64LINEBREAKS = 1;
Parameter USEPPGHANDLER = 1;
ObjectScript
ObjectScript

The first one instructs %SOAP.WebBase to insert line breaks in the XML text, and the second one to use globals rather than local array memory during serialization (to avoid <STORE> error, depending on your available $zstorage)

Enabling both in my SOAP client (created by the SOAP Wizard), solved my problem : the IRIS business operation using the client can now process requests holding very large streams (in my particular case, a whopping 221MB !)

讨论 (0)1
登录或注册以继续
文章
· 七月 7, 2023 阅读大约需 6 分钟

Using LLMs without Burning Dollars - Different Database Query Strategies

 

The continuing convergence of AI technologies and healthcare systems has brought forward many compelling advancements. Let's set the scene. If you have interacted with dynamic models like ChatGPT, you might have, like many of us, begun to envision its application using your unique datasets. Suppose in the healthcare sector you wish to link this technology with Electronic Health Records (EHR) or Electronic Medical Records (EMR), or perhaps you aim for heightened interoperability using FHIR's resources.  It all boils down to how we transfer/receive contextual-data to/from LLMs available in the market.

More accurate techniques include fine-tuning, training LLMs exclusively with the context datasets. Except, it costs millions of dollars to accomplish this today. The other way is to feed context to LLMs via one-shot or few-shot queries and getting an answer. Some ways in which this can be achieved are - generating SQL queries, generating code to query/parse, making calls with information from API specifications and so on. But, there is a problem of high token consumption and some of these answers may not be accurate always.

There’s no one solution fits all magic here, but understanding the pros and cons of these techniques can be helpful in devising your own strategy. Also, leveraging good engineering practices (like caches, secondary storage) and focussing on problem solving can help find a balance between the available methods. This post is an attempt at sharing some strategies and drawing comparison between them under different metrics.

Generating SQL queries

Firstly, we have the more conventional method - loading and parsing the SQL database structure and sample content through LangChain and executing GPT queries. This method has a track record of facilitating efficient and dynamic communication with our healthcare systems, marking itself as a tried-and-true technique in our industry.

There are solutions that pass just the database structure (table schema for example) and others that pass some redacted data to help the LLM generate accurate queries. The former solution has the advantage of fixed token usage and predictable costs but takes a hit on accuracy due to not being completely context-aware. The latter solution might be more token intensive and needs special care with anonymization techniques.  These solutions might be perfect for some use-cases, but could there exist a more optimal strategy?

Using LLMs to Generate code to navigate APIs and Database queries

Another sophisticated technique is to let the LLMs generate code to break down a question into multiple queries or API calls. This is a very natural way of solving complicated questions and unleashes the power of combining natural-language and underlying code.

This solution requires good prompt engineering and fine-tuning the template prompts to work well for all corner cases. Fitting this solution into an enterprise context can be challenging with the uncertainties in token usage, secure code generation and controlling the boundaries of what is and is not accessible by the generated code. But in it’s entirety the power of this technique to act autonomously to solve complex problems is fascinating and further advances in this area are something to look forward to.

Loading OpenAPI specs as context to LLMs

Our team wanted to try a different approach to control token usage but also leverage available context to get accurate results. How about employing LangChain to load and parse FHIR’s OpenAPI specifications? OpenAPI presents itself as an impactful alternative, furnished with adaptive and standardized procedures, validating the importance of FHIR's comprehensive API standards. Its distinct advantage lies in promoting effortless data exchange between diverse systems. The control here lies in being able to modify the specifications itself and not the prompts or generated outputs from the LLM.

Imagine the scenario: a POST API performs all required validating checks before data is added to the database. Now, envision leveraging that same POST API, but using a natural language method. It still carries out the same rigorous checks, ensuring consistency and reliability. This nature of OpenAPI doesn't just simplify interactions with healthcare services and applications, but also enhances API comprehensibility, making them easy to understand and predictable.

We understand this solution doesn’t hold the same power as autonomously breaking down tasks or generating code, but this is an aim at arriving at a more practical solution that can be adapted for most use-cases quickly.

Comparison

While all these techniques demonstrate unique benefits and the potential to serve different purposes, let us evaluate their performance against some metrics.

1. Reliability - Prioritizing reliability considering our alliance with AI, OpenAPI has an edge due to its utilization of standardized APIs. This ensures restricted unauthorized access and precise user authentication to specific data, providing enhanced data security as compared to passing AI-generated SQL for DB access - a method that could potentially raise reliability concerns.

2. Cost - The efficiency of the API’s filtering capabilities defined by FHIR plays a role in cost reduction. This permits only necessary data, streamlined through intense prompt engineering, to be transacted, unlike traditional DBs that may return more records than needed, leading to unnecessary cost surges.

3. Performance - The structured, and standardized presentation of data by OpenAPI specifications often contribute to superior output results from GPT-4 models, enhancing performance. However, SQL DBs can return results more swiftly for direct queries. It is important to account for Open API's potential for over-informing due to the definition of more parameters than might be needed for a query.

4. Interoperability - OpenAPI specifications shine when it comes to interoperability. Being platform-independent, they align perfectly with FHIR's mission to boost interoperability in healthcare, fostering a collaborative environment for seamless synchronization with other systems.

5. Implementation & Maintenance - Although it may be comparatively easier to spin off a DB and provide the context to the AI for querying makes the SQL database loading method with its lean control layer may seem easier to implement, the OpenAPI specifications, once mastered, offer benefits like standardization and easier maintenance that outweigh the initial learning and execution curve.

6. Scalability and Flexibility - SQL databases demand a rigid schema that may not comfortably allow for scalability and flexibility. Unlike SQL, OpenAPI offers a more adaptive and scalable solution, making it a future-friendly alternative.

7. Ethics and Concerns - An important, yet complex factor to consider given the rapid growth of AI. Would you be comfortable providing direct DB access to customers, even with filters and auth? Reflect on the importance of data de-identifiers in ensuring privacy within the healthcare space. Even though both OpenAPI and SQL databases have mechanisms to address these concerns, the inherent standardization provided by OpenAPI adds an additional layer of security.

While this discussion offers insights into some of the key factors to consider, it's essential to recognize that the choice between SQL, code generation and OpenAPI is multifaceted and subject to the specific requirements of your projects and organizations.

Please feel free to share your thoughts and perspectives on this topic - perhaps you have additional points to suggest or you'd like to share some examples that have worked best for your use-case.

Vote for our app in the Grand Prix contest if you find it promising!

1 Comment
讨论 (1)2
登录或注册以继续
问题
· 七月 6, 2023

REST Documentation Confusion

I had attempted to create a REST Operation before but did not have success. As I am going through the Tutorials and Documentation everything references REST services, but I have a case where I want to create a REST Operation that makes Epic API calls against Interconnect. I have done SOAP operations before and we currently have one in our Production Namespace, but from what I understand SOAP has the wsdl which defines al the structures and etc, where REST does not. 

So how does one go about creating a REST Operation if Learning Tutorials and Documentation always talks about REST services? How does one make the Response JSON generic enough as Epic API's return lists of categories?

Does anyone have any good examples of a REST Operation, that they take the JSON response and do something with it instead of just putting the JSON into a structure class? Is there something dynamically that can handle the JSON response and parse it apart for a user?

What I am looking to do is make it as easy as possible from a Function to make the API call and return the response to the users for them to use instead of us relying on querying a MS SQL database which is populated by data from Epic anyway. I would like us to move towards getting the data from the source as much as possible.

Maybe I am making this more complicated that it needs to be, or maybe I am getting overwhelm trying to find the correct way to do things, but could use any suggestions.

Thanks

1 Comment
讨论 (1)2
登录或注册以继续
文章
· 七月 6, 2023 阅读大约需 4 分钟

GPT meets FHIR: Leveraging the power of Open API specs

 

FHIR has revolutionized the healthcare industry by providing a standardized data model for building healthcare applications and promoting data exchange between different healthcare systems. As the FHIR standard is based on modern API-driven approaches, making it more accessible to mobile and web developers. However, interacting with FHIR APIs can still be challenging especially when it comes to querying data using natural language.

Introducing the FHIR - AI and OpenAPI Chain application, a solution that allows users to interact with FHIR APIs using natural language queries. Built with OpenAI, LangChain, and Streamlit, this application simplifies the process of querying FHIR APIs and makes it more user-friendly.

 

What are FHIR OpenAPI Specifications?

OpenAPI Specifications (formerly known as Swagger and currently part of OpenAPI Initiative) have become an essential tool in the world of software development, enabling developers to design, document, and interact with APIs more efficiently. OpenAPI Specifications define a standard, machine-readable format for describing RESTful APIs, providing a clear and consistent way to understand their capabilities and use them effectively.

In the healthcare domain, FHIR emerged as a leading standard for data exchange and interoperability. To enhance the interoperability capabilities of FHIR, HL7 has officially documented the FHIR OpenAPI Specifications, which enable developers to seamlessly integrate FHIR resources and operations into their software solutions.

 

Benefits of FHIR OpenAPI Specifications:

  1. Standardized API Description: OpenAPI Specifications provide a comprehensive and standardized description of FHIR resources, operations, and interactions. Developers can easily understand the structure and capabilities of FHIR-based APIs, making it easier to build integrations and interact with healthcare systems.
  2. Promotion of Interoperability: Foster collaboration among developers, driving the adoption of FHIR standards and best practices. The specifications provide a common language and framework for discussing FHIR-based integrations and implementations, fostering collaboration among developers.
  3. Enhanced Documentation and Testing: Interactive documentation and test suites for better understanding and validation. Developers can create detailed API documentation, making it easier for other developers to understand and utilize the FHIR-based APIs. Test suites based on the specifications enable comprehensive testing and validation of API integrations, ensuring the reliability and accuracy of healthcare data exchange.
  4. Improved Developer Experience: Automatic generation of client libraries and SDKs for seamless integration. This simplifies the integration process and reduces the time and effort required to incorporate FHIR functionality into their applications

 

How do FHIR, OpenAI, and OpenAPI Chain work together?

The FHIR - AI and OpenAPI Chain application leverages LangChain to load and parse the OpenAPI specifications (OpenAPI Chain). After which, based on these specifications, the chain of prompts given through OpenAI aims to understand natural language queries and convert them into appropriate FHIR API requests. Users can ask questions in plain language, and the application will interact with the chosen FHIR API to retrieve the relevant information.

For example, a user might ask, "What is the latest blood pressure reading for patient, John Doe (ID 111)?" The application will then translate this query into an FHIR API request, fetch the required data, and present it to the user in an easily understandable format.

 

 

Benefits of FHIR - AI and OpenAPI Chain

  1. User-friendly interactions: By allowing users to interact with FHIR APIs using natural language queries, the application makes it easier for non-technical users to access and analyze healthcare data.
  2. Improved efficiency: The application streamlines the process of querying FHIR APIs, reducing the time and effort required to obtain relevant information. Also, it has the potential in reducing the number of clicks (time spent) to find any particular information from the application.
  3. Customizable: The FHIR Standards simplify the retrieval of consistent data from any FHIR server, allowing for easy customization. It can be effortlessly configured to seamlessly integrate with any FHIR API, providing a flexible and adaptable solution for diverse healthcare data requirements.

 

Getting Started with FHIR - AI and OpenAPI Chain

To start using the FHIR - AI and OpenAPI Chain application, follow these steps:

  1. Obtain an OpenAI API key from the OpenAI Platform.
  2. Get an FHIR Server API endpoint. You can either use your own sample FHIR server (unauthenticated access needed) or create a temporary sample server by following the instructions given in the InterSystems IRIS FHIR Learning platform.
  3. Try the application online or set it up locally using the provided instructions.

 

By integrating AI and natural language processing capabilities, the FHIR - AI and OpenAPI Chain application offers a more intuitive way to interact with FHIR APIs, making healthcare data more accessible and easier to analyze for users of all technical backgrounds.

Vote for our app in the Grand Prix contest if you find it promising!

If you can think of any potential applications using this implementation, please feel free to share them in the discussion thread.

4 Comments
讨论 (4)0
登录或注册以继续
文章
· 七月 5, 2023 阅读大约需 7 分钟

Doctor-Patient Conversations: AI-Powered Transcription and Summarization

 

Previous postUsing AI to Simplify Clinical Documents Storage, Retrieval and Search

This post explores the potential of OpenAI's advanced language models to revolutionize healthcare through AI-powered transcription and summarization. We will delve into the process of leveraging OpenAI's cutting-edge APIs to convert audio recordings into written transcripts and employ natural language processing algorithms to extract crucial insights for generating concise summaries.

While existing solutions like Amazon Medical Transcribe and MedVoice offer similar capabilities, the focus of this post will be on implementing these powerful features using OpenAI technology within Intersystems FHIR.

Recording audio on Vue.js

The voice recorder on the Vue.js app if fully native and written using the Mediarecorder interface in javascript. This was done to keep the application light-weight and also get full control over the recording options. Below are snippets to start and stop recording audio input.

// Start recording method that stores audio stream as chunks
async startRecording() {
      try {
        const stream = await navigator.mediaDevices.getUserMedia({
          audio: true,
        });
        this.mediaRecorder = new MediaRecorder(stream);
        this.mediaRecorder.start();

        this.mediaRecorder.ondataavailable = (event) => {
          this.chunks.push(event.data);
        };
        this.isRecording = true;
      } catch (error) {
        console.error("Error starting recording:", error);
      }
}

// Stop recording method that creates a blob after stop (and calls the transcription method)
stopRecording() {
      if (this.mediaRecorder) {
        this.isLoading = true;
        this.mediaRecorder.stop();
        this.mediaRecorder.onstop = async () => {
          const blob = new Blob(this.chunks, {
            type: "audio/webm;codecs=opus",
          });
          await this.sendAudioToWhisper(
            new File([blob], `file${Date.now()}.m4a`)
          );

          this.getSummary(this.transcription);
        };
      }
}
JavaScript
JavaScript

Transcription Component

Transcription of audio data using OpenAI's Whisper model involves several essential components. The following code snippet demonstrates the steps involved in the transcription process.

const apiKey = process.env.OPENAI_API_KEY;

const formData = new FormData();
formData.append("file", blob);
formData.append("model", "whisper-1");
formData.append("response_format", "json");
formData.append("temperature", "0");
formData.append("language", "en");

try {
  const response = await fetch(
    "https://api.openai.com/v1/audio/transcriptions",
    {
      method: "POST",
      headers: {
        Accept: "application/json",
        Authorization: `Bearer ${apiKey}`,
      },
      body: formData,
      redirect: "follow",
    }
  );

  const data = await response.json();
  if (data.text) {
    this.transcription = data.text;
  }
} catch (error) {
  console.error("Error sending audio to Whisper API:", error);
}

return this.transcription;
JavaScript
JavaScript
  1. API Key - The OPENAI_API_KEY is a required authentication token for accessing OpenAI APIs.
  2. Form Data - The audio file to be transcribed is appended to a FormData object. Additional parameters like the chosen model whisper-1, the response format (json), temperature (0), and language (en) are also included.
  3. API Request - The fetch method is used to send a POST request to the OpenAI API endpoint https://api.openai.com/v1/audio/transcriptions with the specified headers and body containing the form data.
  4. Response Handling - The response from the API is captured, and the transcribed text is extracted from the data object. The transcription can be assigned to a variable this.transcription for further processing or usage.

Summarization Component

The following code snippet demonstrates the core components involved in the text summarization process using OpenAI's text-davinci-003 model.

response = openai.Completion.create(
    model="text-davinci-003",
    prompt="Summarize the following text and give title and summary in json format. \
            Sample output - {\"title\": \"some-title\", \"summary\": \"some-summary\"}.\
            Input - "
    + text,
    temperature=1,
    max_tokens=300,
    top_p=1,
    frequency_penalty=0,
    presence_penalty=1
)

return response["choices"][0]["text"].replace('\n', '')
JavaScript
JavaScript
  1. Model Selection - The model parameter is set to text-davinci-003, indicating the use of OpenAI's text completion model for summarization.
  2. Prompt - The prompt provided to the model specifies the desired outcome, which is to summarize the input text and return the title and summary in JSON format. The input text is concatenated to the prompt for processing. It’s interesting how we can handle response transformation through OpenAI. Only validation at the receiving end is enough and we might almost never need converters in the future.
  3. Generation Parameters - Parameters such as temperature, max_tokens, top_p, frequency_penalty, and presence_penalty are set to control the behaviour and quality of the generated summary.
  4. API Request and Response Handling - The openai.Completion.create() method is called to make the API request. The response is captured, and the generated summary text is extracted from the response object. Any newline characters (\n) in the summary text are removed before returning the final result.

Document Reference in FHIR

In the context of implementing doctor-patient conversation transcription and summarization using OpenAI technologies, an important consideration is the storage of clinical notes within the FHIR standard. FHIR provides a structured and standardized approach for exchanging healthcare information, including clinical notes, among different healthcare systems and applications. The Document Reference resource in FHIR serves as a dedicated section for storing clinical notes and related documents.

When integrating transcription and summarization capabilities into the doctor-patient conversation workflow, the resulting transcriptions and summaries can be stored as clinical notes within the FHIR Documents resource. This allows for easy access, retrieval, and sharing of the generated insights among healthcare providers and other authorized entities.

{
    "resourceType": "Bundle",
    "id": "1a3a6eac-182e-11ee-9901-0242ac170002",
    "type": "searchset",
    "timestamp": "2023-07-01T16:34:36Z",
    "total": 1,
    "link": [
        {
            "relation": "self",
            "url": "http://localhost:52773/fhir/r4/Patient/1/DocumentReference"
        }
    ],
    "entry": [
        {
            "fullUrl": "http://localhost:52773/fhir/r4/DocumentReference/1921",
            "resource": {
                "resourceType": "DocumentReference",
                "author": [
                    {
                        "reference": "Practitioner/3"
                    }
                ],
                "subject": {
                    "reference": "Patient/1"
                },
                "status": "current",
                "content": [
                    {
                        "attachment": {
                            "contentType": "application/json",
                            "data": "<base64-payload>"
                        }
                    }
                ],
                "id": "1921",
                "meta": {
                    "lastUpdated": "2023-07-01T16:34:33Z",
                    "versionId": "1"
                }
            },
            "search": {
                "mode": "match"
            }
        }
    ]
}
JSON
JSON

Try it out

  1. Clone the Project - Clone the project repository from the following GitHub link: https://github.com/ikram-shah/iris-fhir-transcribe-summarize-export.
  2. Setup Locally - Follow the provided instructions to set up the project locally on your machine. Let us know if you face any issues during set up.
  3. Select a Patient - Choose a patient from the provided sample list within the project. This patient will be associated with the doctor-patient conversation for transcription and summarization.
  4. Interactions Page -Once the patient is selected, navigate to the interactions page within the project. On this page, locate and click on the "Take Notes" option to initiate the transcription process for the doctor-patient conversation.
  5. View and Edit Transcription - After the transcription process is completed, an option will be presented to view the generated transcription. You can also edit the title and summary associated with the transcription for better organization and clarity.
  6. Saving to FHIR Document Reference - Upon finalizing the title and summary, saving the changes will automatically store them within the FHIR document reference. This ensures that the relevant clinical notes are captured and associated with the respective patient's record. Currently, the project does not save the entire transcription text. However, it can be modified to include the storage of the complete transcription as well.

Demo

Watch a demo of the overall application here - https://youtu.be/3Th6bR4rw0w

Future Directions

Expanding the application of AI-powered transcription and summarization to telehealth communication holds immense potential. Integrating these capabilities with popular meeting platforms like Zoom, Teams, and Google Meet can streamline remote doctor-patient interactions. Automatic transcription and summarization of telehealth sessions offer benefits such as accurate documentation and enhanced analysis. However, data privacy remains a crucial challenge. To address this, implementing measures to filter or anonymize personally identifiable information (PII) before transmitting data to external servers is essential.

Future directions include exploring on-device AI models for local processing, improved support for multilingual communication, and advancements in privacy-preserving techniques.

If you find this implementation useful, consider voting for this app at Grand Prix 2023.

2 Comments
讨论 (2)1
登录或注册以继续