首次提交by MimoCode
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
import base64
|
||||
import json
|
||||
from openai import AsyncOpenAI
|
||||
|
||||
from app.ai.base import VisionProvider, TextProvider, VisionResult, DateResult, LeafletResult
|
||||
from app.config import settings
|
||||
|
||||
|
||||
class OpenAIVisionProvider(VisionProvider):
|
||||
def __init__(self):
|
||||
self.client = AsyncOpenAI(api_key=settings.OPENAI_API_KEY)
|
||||
self.model = settings.OPENAI_MODEL
|
||||
|
||||
async def recognize_medicine(self, image_bytes: bytes) -> VisionResult:
|
||||
base64_image = base64.b64encode(image_bytes).decode('utf-8')
|
||||
|
||||
response = await self.client.chat.completions.create(
|
||||
model=self.model,
|
||||
messages=[
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": """请识别这张药品包装图片中的信息,返回JSON格式:
|
||||
{
|
||||
"generic_name": "通用名称",
|
||||
"brand_name": "商品名称",
|
||||
"manufacturer": "生产厂家",
|
||||
"specification": "规格"
|
||||
}
|
||||
只提取图片中真实出现的内容,不要猜测。"""
|
||||
},
|
||||
{
|
||||
"type": "image_url",
|
||||
"image_url": {
|
||||
"url": f"data:image/jpeg;base64,{base64_image}"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
response_format={"type": "json_object"}
|
||||
)
|
||||
|
||||
result = json.loads(response.choices[0].message.content)
|
||||
return VisionResult(**result)
|
||||
|
||||
async def recognize_dates(self, image_bytes: bytes) -> DateResult:
|
||||
base64_image = base64.b64encode(image_bytes).decode('utf-8')
|
||||
|
||||
response = await self.client.chat.completions.create(
|
||||
model=self.model,
|
||||
messages=[
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": """请识别这张图片中的日期信息,返回JSON格式:
|
||||
{
|
||||
"production_date": "生产日期(YYYY-MM-DD格式,如果无法识别则为null)",
|
||||
"expiry_date": "有效期/过期日期(YYYY-MM-DD格式,如果无法识别则为null)"
|
||||
}
|
||||
只提取图片中真实出现的日期,不要猜测或推理。"""
|
||||
},
|
||||
{
|
||||
"type": "image_url",
|
||||
"image_url": {
|
||||
"url": f"data:image/jpeg;base64,{base64_image}"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
response_format={"type": "json_object"}
|
||||
)
|
||||
|
||||
result = json.loads(response.choices[0].message.content)
|
||||
return DateResult(**result)
|
||||
|
||||
|
||||
class OpenAITextProvider(TextProvider):
|
||||
def __init__(self):
|
||||
self.client = AsyncOpenAI(api_key=settings.OPENAI_API_KEY)
|
||||
self.model = "gpt-4"
|
||||
|
||||
async def summarize_leaflet(self, text: str) -> LeafletResult:
|
||||
response = await self.client.chat.completions.create(
|
||||
model=self.model,
|
||||
messages=[
|
||||
{
|
||||
"role": "system",
|
||||
"content": "你是一个医疗信息提取助手。请从药品说明书中提取关键信息。"
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": f"""请从以下药品说明书中提取关键信息,返回JSON格式:
|
||||
{{
|
||||
"indications": "适应症",
|
||||
"adult_dose": "成人用法用量",
|
||||
"child_dose": "儿童用法用量(如果没有则为null)",
|
||||
"contraindications": "禁忌",
|
||||
"notes": "注意事项(如果有)"
|
||||
}}
|
||||
|
||||
说明书内容:
|
||||
{text}"""
|
||||
}
|
||||
],
|
||||
response_format={"type": "json_object"}
|
||||
)
|
||||
|
||||
result = json.loads(response.choices[0].message.content)
|
||||
return LeafletResult(**result)
|
||||
|
||||
async def natural_language_search(self, query: str, medicines: list) -> list:
|
||||
medicines_text = "\n".join([
|
||||
f"- {m['name']}: {m.get('indications', '')}"
|
||||
for m in medicines
|
||||
])
|
||||
|
||||
response = await self.client.chat.completions.create(
|
||||
model=self.model,
|
||||
messages=[
|
||||
{
|
||||
"role": "system",
|
||||
"content": "你是一个药品搜索助手。根据用户描述的症状,从药品列表中找出可能适用的药品。"
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": f"""用户描述:{query}
|
||||
|
||||
可用药品列表:
|
||||
{medicines_text}
|
||||
|
||||
请返回JSON格式的搜索结果:
|
||||
{{
|
||||
"results": [
|
||||
{{
|
||||
"medicine_id": 药品ID,
|
||||
"name": "药品名称",
|
||||
"reason": "匹配原因"
|
||||
}}
|
||||
]
|
||||
}}"""
|
||||
}
|
||||
],
|
||||
response_format={"type": "json_object"}
|
||||
)
|
||||
|
||||
result = json.loads(response.choices[0].message.content)
|
||||
return result.get('results', [])
|
||||
Reference in New Issue
Block a user