feat: 提交审批单的时候通过AI核验报销是否符合报销规范
This commit is contained in:
@@ -6,6 +6,7 @@ from langgraph.graph import StateGraph
|
|||||||
from app.model.ApproveModel import ApproveService, ApproveModel
|
from app.model.ApproveModel import ApproveService, ApproveModel
|
||||||
from app.model.ReimburseModel import ReimburseService, ReimburseModel
|
from app.model.ReimburseModel import ReimburseService, ReimburseModel
|
||||||
from app.utils.db_utils import AsyncSessionDep
|
from app.utils.db_utils import AsyncSessionDep
|
||||||
|
from app.utils.llm_approve_utils import get_llm_approve_result
|
||||||
from app.utils.postgres_checkpointer import AsyncPostgresSaverDep
|
from app.utils.postgres_checkpointer import AsyncPostgresSaverDep
|
||||||
from app.workflow.approve import create_approve_graph, ApproveGraphSchema
|
from app.workflow.approve import create_approve_graph, ApproveGraphSchema
|
||||||
|
|
||||||
@@ -36,6 +37,7 @@ def add_reimburse_route(app: FastAPI):
|
|||||||
if reimburse_cls.approve.status == 'approved':
|
if reimburse_cls.approve.status == 'approved':
|
||||||
return {"message": "报销单已通过审批,请勿重复提交!"}
|
return {"message": "报销单已通过审批,请勿重复提交!"}
|
||||||
|
|
||||||
|
llm_response_dict = await get_llm_approve_result(session, reimburse_cls)
|
||||||
# 1,4,5 的情况下新建审批单
|
# 1,4,5 的情况下新建审批单
|
||||||
# 创建审批单,使用新的审批单走审批流程
|
# 创建审批单,使用新的审批单走审批流程
|
||||||
|
|
||||||
@@ -49,6 +51,7 @@ def add_reimburse_route(app: FastAPI):
|
|||||||
"apply_user_id": reimburse_cls.user_id,
|
"apply_user_id": reimburse_cls.user_id,
|
||||||
"proj_id": reimburse_cls.proj_id,
|
"proj_id": reimburse_cls.proj_id,
|
||||||
"approve_from": "reimburse",
|
"approve_from": "reimburse",
|
||||||
|
**llm_response_dict,
|
||||||
}
|
}
|
||||||
insert_approve_cls: ApproveModel = await ApproveService.item_insert(session=session, row_dict=new_approve_dict)
|
insert_approve_cls: ApproveModel = await ApproveService.item_insert(session=session, row_dict=new_approve_dict)
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ class ApproveModel(PublicApproveModel, table=True):
|
|||||||
__tablename__ = "pl_approve"
|
__tablename__ = "pl_approve"
|
||||||
__table_args__ = {'extend_existing': True}
|
__table_args__ = {'extend_existing': True}
|
||||||
|
|
||||||
|
llm_flag: Optional[bool] = Field(default=None, description="LLM审核是否通过表示")
|
||||||
|
llm_reason: Optional[str] = Field(default=None, description="LLM审核不通过原因")
|
||||||
|
|
||||||
# /*---------------------------------------project-------------------------------------------*/
|
# /*---------------------------------------project-------------------------------------------*/
|
||||||
|
|
||||||
proj_id: str = Field(
|
proj_id: str = Field(
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
from langchain_core.output_parsers import StrOutputParser
|
||||||
|
from langchain_core.prompts import ChatPromptTemplate
|
||||||
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
|
from app.model.KnowledgeDoc import KnowledgeDocServiceWithCreator, KnowledgeDocModel
|
||||||
|
from app.model.ReimburseModel import ReimburseModel
|
||||||
|
from app.utils.db_utils import AsyncSessionDep
|
||||||
|
from app.utils.llm_utils import create_llm
|
||||||
|
|
||||||
|
|
||||||
|
class LlmApproveResult(BaseModel):
|
||||||
|
llm_flag: bool = Field(..., description='AI审核是否通过')
|
||||||
|
llm_reason: str | None = Field(default=None, description="审核不通过时的原因")
|
||||||
|
|
||||||
|
|
||||||
|
async def get_llm_approve_result(session: AsyncSessionDep, reimburse_cls: ReimburseModel):
|
||||||
|
try:
|
||||||
|
reimburse_document: KnowledgeDocModel = await KnowledgeDocServiceWithCreator.query_item(session, {"code": "REIMBURSE"})
|
||||||
|
except Exception as e:
|
||||||
|
raise Exception(f"获取报销规范文档失败: {e}")
|
||||||
|
|
||||||
|
chain = ChatPromptTemplate.from_template("""
|
||||||
|
你是一名专业的报销单审核专家,你需要根据报销规范文档审核报销单信息,报销规范如<document/>标签中的内容所示:
|
||||||
|
<document>
|
||||||
|
{document_content}
|
||||||
|
</document>
|
||||||
|
报销单信息如下<reimburse/>标签中的内容所示:
|
||||||
|
<reimburse>
|
||||||
|
{reimburse_content}
|
||||||
|
</reimburse>
|
||||||
|
你需要返回一个json对象,类型为:{response_description},其中llm_flag表示审核是否通过,为布尔值;llm_reason为审核不通过的原因,审核通过reason为空;
|
||||||
|
""") | create_llm() | StrOutputParser()
|
||||||
|
|
||||||
|
print(":::::::::::::::报销规则:::::::::::::::::::")
|
||||||
|
print(reimburse_document.content)
|
||||||
|
|
||||||
|
print(":::::::::::::::报销单描述::::::::::::::::::::::::")
|
||||||
|
reimburse_description = get_reimburse_description(reimburse_cls)
|
||||||
|
print(reimburse_description)
|
||||||
|
|
||||||
|
llm_response_content = await chain.ainvoke({
|
||||||
|
"document_content": reimburse_document.content,
|
||||||
|
"reimburse_content": reimburse_description,
|
||||||
|
"response_description": '{"llm_flag":true, "llm_reason":""}'
|
||||||
|
})
|
||||||
|
|
||||||
|
print("::::::::::::::LLM审核结果:::::::::::::::::::::::")
|
||||||
|
print(llm_response_content)
|
||||||
|
|
||||||
|
llm_response_dict = json.loads(llm_response_content)
|
||||||
|
return llm_response_dict
|
||||||
|
|
||||||
|
|
||||||
|
def get_reimburse_description(reimrbuse_cls: ReimburseModel):
|
||||||
|
if not reimrbuse_cls.project:
|
||||||
|
raise Exception("报销单关联项目不存在")
|
||||||
|
|
||||||
|
reimbruse_content = f"""
|
||||||
|
报销申请人:{reimrbuse_cls.user.full_name}
|
||||||
|
报销单标题:{str(reimrbuse_cls.title)}
|
||||||
|
报销单金额:{str(reimrbuse_cls.amount)}
|
||||||
|
报销单备注信息:{str(reimrbuse_cls.remarks)}
|
||||||
|
报销项目:{str(reimrbuse_cls.project.name)}
|
||||||
|
"""
|
||||||
|
|
||||||
|
for index, travel_item in enumerate(reimrbuse_cls.travel_list):
|
||||||
|
reimbruse_content += f"""
|
||||||
|
|
||||||
|
第{index + 1}条差旅费用信息:
|
||||||
|
差旅费用名称:{travel_item.title}
|
||||||
|
差旅费用类型:{travel_item.type}
|
||||||
|
差旅出发时间:{travel_item.depart_time}
|
||||||
|
差旅出发地点:{travel_item.depart_city}
|
||||||
|
差旅到达时间:{travel_item.arrive_time}
|
||||||
|
差旅到达地点:{travel_item.arrive_city}
|
||||||
|
差旅报销金额:{travel_item.amount}
|
||||||
|
"""
|
||||||
|
|
||||||
|
for index, other_item in enumerate(reimrbuse_cls.other_list):
|
||||||
|
reimbruse_content += f"""
|
||||||
|
|
||||||
|
第{index + 1}条费用信息:
|
||||||
|
费用名称:{other_item.title}
|
||||||
|
费用类型:{other_item.type}
|
||||||
|
报销金额:{other_item.amount}
|
||||||
|
票据类型:{other_item.recipe_type}
|
||||||
|
"""
|
||||||
|
return reimbruse_content
|
||||||
Reference in New Issue
Block a user