应用场景
用于文档的整理。主要是针对医疗方面的文档整理。病人在打官司或者办理其他业务时,需要把很多文档整理成册并添加目录、编写概要(Summary)。这些文档有电子版本的,有纸质的扫描件,还有拍照(一般是事故或者车祸现场)等等。一些复杂的病人,一个病人有超过7万8千页的文档。现在每年有超过2.1亿页业务量进行处理。目前主要是靠人工处理。为了提高效率、降低成本,引入了GPT进行自动编写目录、生成概要。
设计
主要由3个服务组成
- JobPoster
- JobAI
- JobGPT
JobPoster: 把PDF、Json、TCF等文件提交到系统中,将业务数据保存到数据库中,并将GIF、PDF、XML等文件存储到云存储(这部分在2020年上线,承载着目前的也业务)。 现在对这个服务进行了扩展。根据WorkFlow的设置,将一部分病人的数据分配到JobAI上。
JobAI: 新开发的服务,用于对文档内容进行OCR,并根据病人的类型、WorkFlow的设置,形成一系列的提问(Prompt),然后把内容和提问 发送给JobGPT。
JobGPT: 调用GPT,对每页的内容进行分类,并生成概要。
实现
JobAI部分
这一部分主要的功能就两个:
- 对每一页的文档内容进行OCR,
- 针对设置形成每一页内容的提问。
OCR部分通过配置可以选择三种不同的识别引擎:Tesseract、Azure、PaddleOCR
分类提问(Prompt)是多级的(Tree)、不同类型的病人的设置也是不一样的。
分类提问(Prompt)
分类提问一般先给出分类目录 ,例如下面这个提问:
category list:
1 Injury Reports
2 Job Description/Job Analy
3 Application for Benefits
4 Accident/Police Reports
5 Phones
6 Damage Estimates
7 Recorded Statements
8 Prior IME Reports
9 Legal Documents
10 Surveillance
11 Social Media
12 HCFA Billing Summary
13 Records
14 Billing
15 Miscellaneous
16 Illegible documents
17 Removed
18 Unused Images
Your task is to find the category of the document given below:
9/1/2023 1:52 PM EDT
。。。。。(文档内容)
GPT会返回这样的结果:
Category: Records
再根据分类的结果进行数据提问
数据提问(Prompt)
field list:
Date
Facility
Type of Document
Default Text
Type of Test
Your task is to find the field value of the document given below:
9/1/2023 1:52 PM EDT
。。。。。(文档内容)
JobGPT部分
这部分主要是调用GPT,将提问(Prompt)和每一页的内容发送给GPT,根据GPT返回的结果进行编写目录和生成概要。使用了Azure Key和GPT进行通讯。
public static string CallAI( string deploymentName, string inputToAI, string uri, string AzureKey)
{
OpenAIClient client = GetOpenAIClient(uri, AzureKey);
ChatCompletionsOptions chatcompletionOptions = new ChatCompletionsOptions
{
MaxTokens = 1300,
Temperature = 0.0f,
FrequencyPenalty = 0,
PresencePenalty = 0,
};
chatcompletionOptions.Messages.Add(new ChatMessage(ChatRole.System, inputToAI));
Task<Response<ChatCompletions>> task= client.GetChatCompletionsAsync(deploymentName, chatcompletionOptions);
task.Wait();
Response<ChatCompletions> completionsResponse = task.Result;
ChatMessage completion = completionsResponse.Value.Choices[0].Message;
return completion.Content;
}
public static OpenAIClient GetOpenAIClient(string uri, string AzureKey)
{
OpenAIClient client = new OpenAIClient (new System.Uri(uri),new AzureKeyCredential(AzureKey));
return client;
}
namespace JobGPT
{
public class JobAIInfoPage
{
public string PageNum = "";
public string Text = "";
public List<string> Classify = new List<string>();
public Dictionary<string, string> Field = new Dictionary<string, string>();
}
public class ClassifyInfo
{
public string TOC = "";
public List<string> SegmentTag = new List<string>();
public List<ClassifyInfo> Nodes = new List<ClassifyInfo>();
}
public class JobAIInfo
{
public string JobNo = "";
public List<ClassifyInfo> ClassifyTOC = new List<ClassifyInfo>();
public List<JobAIInfoPage> Pages = new List<JobAIInfoPage>();
public string Medsum = "";
public bool GPTResult = false;
}
}