Compare commits
20 Commits
main
...
7023b54246
| Author | SHA1 | Date | |
|---|---|---|---|
| 7023b54246 | |||
| aee6aa3c04 | |||
| 680e24c516 | |||
| 6663ee8976 | |||
| 0a5f335981 | |||
| 2901bd9eaf | |||
| 453b3ca55c | |||
| 03c4eb1af1 | |||
| 480a1f7fdc | |||
| cdc9d84a1e | |||
| 50f35bb0c9 | |||
| 4a8c79e83d | |||
| f0afd1a4bb | |||
| de34c3938c | |||
| eb572eff27 | |||
| 2706cf9d5a | |||
| 5fa4752d6e | |||
| aff1793c4e | |||
| 3ee1ba529f | |||
| 576a2ae737 |
@@ -1,3 +1,8 @@
|
||||
JIEBA_DATA=./nltk_data
|
||||
NLTK_DATA=./nltk_data
|
||||
SQLITE_DATABASE_URL=sqlite:///./source.db
|
||||
DATA_SOURCE_CACHE=./restapi
|
||||
|
||||
# The Llama Cloud API key.
|
||||
# LLAMA_CLOUD_API_KEY=
|
||||
SQL_DATABASE_URL=mysql+pymysql://zjinfo1:Dy2Bcr53Hm5xRkba@110.42.234.166:3306/zjinfo1
|
||||
@@ -80,3 +85,4 @@ SYSTEM_PROMPT="You are a weather forecast agent. You help users to get the weath
|
||||
- You can install any pip package (if it exists) by running a cell with pip install.
|
||||
"
|
||||
|
||||
PROJECT_TITLE = "您好,我是博微工程理解小助手,您可以问我有关[线路工程]工程数据的相关问题!"
|
||||
@@ -1,3 +1,8 @@
|
||||
JIEBA_DATA=./nltk_data
|
||||
NLTK_DATA=./nltk_data
|
||||
SQLITE_DATABASE_URL=sqlite:///./source.db
|
||||
DATA_SOURCE_CACHE=./restapi
|
||||
|
||||
# The Llama Cloud API key.
|
||||
# LLAMA_CLOUD_API_KEY=
|
||||
SQL_DATABASE_URL=mysql+pymysql://zjinfo1:Dy2Bcr53Hm5xRkba@110.42.234.166:3306/zjinfo1
|
||||
@@ -111,3 +116,4 @@ SYSTEM_PROMPT="You are a weather forecast agent. You help users to get the weath
|
||||
- You can install any pip package (if it exists) by running a cell with pip install.
|
||||
"
|
||||
|
||||
PROJECT_TITLE = "您好,我是博微工程理解小助手,您可以问我有关[线路工程]工程数据的相关问题!"
|
||||
+232
-229
@@ -3,6 +3,7 @@ import json
|
||||
import logging
|
||||
import time
|
||||
from typing import Dict, List, Any, Optional, AsyncGenerator
|
||||
from collections import deque
|
||||
|
||||
from aiostream import stream
|
||||
from fastapi import APIRouter, Request
|
||||
@@ -13,7 +14,8 @@ from llama_index.core.callbacks import CBEventType
|
||||
from llama_index.core.chat_engine.types import StreamingAgentChatResponse
|
||||
from llama_index.core.tools import ToolOutput
|
||||
from pydantic import BaseModel
|
||||
from app.api.routers.request.base import userMng, conversations,message,parameter
|
||||
from app.api.routers.request.base import userMng, conversations,message,parameter,feedback
|
||||
from app.api.routers.request.baseConfig import *
|
||||
from app.api.routers.request.models import ChatRequestData,ChatFileUploadRequest
|
||||
from app.engine import get_chat_engine
|
||||
import uuid
|
||||
@@ -24,78 +26,138 @@ api_router = r = APIRouter()
|
||||
v1_router = v = APIRouter()
|
||||
|
||||
class ChatCallbackEvent(BaseModel):
|
||||
event_type: CBEventType
|
||||
event_type: ChatEventType
|
||||
payload: Optional[Dict[str, Any]] = None
|
||||
event_id: str = ""
|
||||
|
||||
def get_retrieval_message(self) -> dict | None:
|
||||
if self.payload:
|
||||
nodes = self.payload.get("nodes")
|
||||
if nodes:
|
||||
msg = f"根据查询检索到 {len(nodes)} 源文件"
|
||||
else:
|
||||
msg = f"查询检索中: '{self.payload.get('query_str')}'"
|
||||
def get_common_param(self)-> dict:
|
||||
return {
|
||||
"type": "events",
|
||||
"data": {"title": msg},
|
||||
}
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_tool_message(self) -> dict | None:
|
||||
func_call_args = self.payload.get("function_call")
|
||||
if func_call_args is not None and "tool" in self.payload:
|
||||
tool = self.payload.get("tool")
|
||||
return {
|
||||
"type": "events",
|
||||
"data": {
|
||||
"title": f"调用工具 {tool.name} ,参数: {func_call_args}",
|
||||
},
|
||||
'event': self.event_type.name,
|
||||
'conversation_id':self.payload.get("conversation_id"),
|
||||
'message_id': self.payload.get("message_id"),
|
||||
'created_at': int(time.time()),
|
||||
'task_id': self.payload.get("task_id")
|
||||
}
|
||||
|
||||
def _is_output_serializable(self, output: Any) -> bool:
|
||||
try:
|
||||
json.dumps(output)
|
||||
return True
|
||||
except TypeError:
|
||||
return False
|
||||
|
||||
def get_agent_tool_response(self) -> dict | None:
|
||||
response = self.payload.get("response")
|
||||
if response is not None:
|
||||
sources = response.sources
|
||||
for source in sources:
|
||||
# Return the tool response here to include the toolCall information
|
||||
if isinstance(source, ToolOutput):
|
||||
if self._is_output_serializable(source.raw_output):
|
||||
output = source.raw_output
|
||||
else:
|
||||
output = source.content
|
||||
|
||||
return {
|
||||
"type": "tools",
|
||||
"data": {
|
||||
"toolOutput": {
|
||||
"output": output,
|
||||
"isError": source.is_error,
|
||||
},
|
||||
"toolCall": {
|
||||
"id": None, # There is no tool id in the ToolOutput
|
||||
"name": source.tool_name,
|
||||
"input": source.raw_input,
|
||||
},
|
||||
def get_WorkflowStart_param(self) -> dict:
|
||||
params = self.get_common_param()
|
||||
params.update({
|
||||
'workflow_run_id':self.payload.get('workflow_run_id'),
|
||||
'data':{
|
||||
"id": self.payload.get('workflow_run_id'),
|
||||
"workflow_id": self.payload.get('workflow_id'),
|
||||
"sequence_number": 1709,
|
||||
"inputs": {
|
||||
"sys.query": self.payload.get('query'),
|
||||
"sys.files": [],
|
||||
"sys.conversation_id": self.payload.get('conversation_id'),
|
||||
"sys.user_id": self.payload.get('use_id')
|
||||
},
|
||||
"created_at": int(time.time())
|
||||
}
|
||||
})
|
||||
return params
|
||||
|
||||
def to_response(self):
|
||||
def get_WorkflowFinished_param(self) -> dict:
|
||||
params = self.get_common_param()
|
||||
params.update({
|
||||
'workflow_run_id':self.payload.get('workflow_run_id'),
|
||||
'data':{
|
||||
"id": self.payload.get('workflow_run_id'),
|
||||
"workflow_id": self.payload.get('workflow_id'),
|
||||
"sequence_number": 1709,
|
||||
"status": "succeeded",
|
||||
"outputs": {
|
||||
"answer": self.payload.get('response')
|
||||
},
|
||||
"error": '',
|
||||
"elapsed_time": 36.03764106379822,
|
||||
"total_tokens": 11707,
|
||||
"total_steps": 10,
|
||||
"created_by": {
|
||||
"id": str(uuid.uuid4()),
|
||||
"user": self.payload.get('use_id')
|
||||
},
|
||||
"created_at": int(time.time()),
|
||||
"finished_at": int(time.time()),
|
||||
"files": []
|
||||
}
|
||||
})
|
||||
return params
|
||||
|
||||
def get_NodeStart_param(self) -> dict:
|
||||
params = self.get_common_param()
|
||||
params.update({
|
||||
'workflow_run_id':self.payload.get('workflow_run_id'),
|
||||
'data':{
|
||||
"id": self.payload.get('nodeid'),
|
||||
"node_id": self.payload.get('nodeid'),
|
||||
"node_type": "http-request",
|
||||
"title": self.payload.get('title'),
|
||||
"index": self.payload.get('index'),
|
||||
"predecessor_node_id": self.payload.get('predecessor_node_id'),
|
||||
"inputs": '',
|
||||
"created_at": 1724398751,
|
||||
"extras": {}
|
||||
}
|
||||
})
|
||||
return params
|
||||
|
||||
def get_NodeFinished_param(self) -> dict:
|
||||
params = self.get_common_param()
|
||||
params.update({
|
||||
'workflow_run_id':self.payload.get('workflow_run_id'),
|
||||
'data':{
|
||||
"id": self.payload.get('nodeid'),
|
||||
"node_id": self.payload.get('nodeid'),
|
||||
"node_type": "http-request",
|
||||
"title": self.payload.get('title'),
|
||||
"index": self.payload.get('index'),
|
||||
"predecessor_node_id": self.payload.get('predecessor_node_id'),
|
||||
"inputs": '',
|
||||
"process_data": '',
|
||||
"outputs": '',
|
||||
"status": "succeeded",
|
||||
"error": '',
|
||||
"elapsed_time": 0.10402441816404462,
|
||||
"execution_metadata": '',
|
||||
"created_at": 1724398751,
|
||||
"finished_at": 1724398751,
|
||||
"files": []
|
||||
}
|
||||
})
|
||||
return params
|
||||
|
||||
def get_Message_param(self) -> dict:
|
||||
params = self.get_common_param()
|
||||
params.update({
|
||||
'id':self.payload.get('message_id'),
|
||||
'answer':self.payload.get('answer')
|
||||
})
|
||||
return params
|
||||
|
||||
def get_MessageEnd_param(self) -> dict:
|
||||
params = self.get_common_param()
|
||||
params.update({
|
||||
'id':self.payload.get('message_id'),
|
||||
'metadata':self.payload.get('metadata')
|
||||
})
|
||||
return params
|
||||
|
||||
def to_response(self)-> dict|None:
|
||||
try:
|
||||
match self.event_type:
|
||||
case "retrieve":
|
||||
return self.get_retrieval_message()
|
||||
case "function_call":
|
||||
return self.get_tool_message()
|
||||
case "agent_step":
|
||||
return self.get_agent_tool_response()
|
||||
case "workflow_started":
|
||||
return self.get_WorkflowStart_param()
|
||||
case "workflow_finished":
|
||||
return self.get_WorkflowFinished_param()
|
||||
case "node_started":
|
||||
return self.get_NodeStart_param()
|
||||
case 'node_finished':
|
||||
return self.get_NodeFinished_param()
|
||||
case 'message':
|
||||
return self.get_Message_param()
|
||||
case 'message_end':
|
||||
return self.get_MessageEnd_param()
|
||||
case _:
|
||||
return None
|
||||
except Exception as e:
|
||||
@@ -106,9 +168,7 @@ class ChatEventCallbackHandler(BaseCallbackHandler):
|
||||
_aqueue: asyncio.Queue
|
||||
is_done: bool = False
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
):
|
||||
def __init__(self,**params):
|
||||
"""Initialize the base callback handler."""
|
||||
ignored_events = [
|
||||
# CBEventType.CHUNKING,
|
||||
@@ -119,6 +179,23 @@ class ChatEventCallbackHandler(BaseCallbackHandler):
|
||||
]
|
||||
super().__init__(ignored_events, ignored_events)
|
||||
self._aqueue = asyncio.Queue()
|
||||
self._response:str = ''
|
||||
self._params:Dict[str,Any] = params
|
||||
self._nodeStack:deque = deque()
|
||||
|
||||
#添加工作流开始事件
|
||||
data:ChatRequestData = self._params['data']
|
||||
args:Dict[str,Any] = self._params['ids']
|
||||
args.update(
|
||||
{
|
||||
'use_id': data.user,
|
||||
'query': data.query,
|
||||
'conversation_id': data.conversation_id
|
||||
}
|
||||
)
|
||||
wf_event = ChatCallbackEvent(event_type = ChatEventType.WORKFLOW_START,payload = args)
|
||||
if wf_event.to_response() is not None:
|
||||
self._aqueue.put_nowait(wf_event)
|
||||
|
||||
def on_event_start(
|
||||
self,
|
||||
@@ -129,9 +206,21 @@ class ChatEventCallbackHandler(BaseCallbackHandler):
|
||||
) -> str:
|
||||
logger.info("event_start:{} type:{} payload:{}\n".format(event_id, event_type, payload))
|
||||
|
||||
event = ChatCallbackEvent(event_id=event_id, event_type=event_type, payload=payload)
|
||||
if event.to_response() is not None:
|
||||
self._aqueue.put_nowait(event)
|
||||
self._nodeStack.append(event_id)
|
||||
nindex = self._nodeStack.count() - 1
|
||||
args:Dict[str,Any] = self._params['ids']
|
||||
args.update(
|
||||
{
|
||||
'nodeid':event_id,
|
||||
'title':event_type.name,
|
||||
'index':nindex + 1,
|
||||
'predecessor_node_id': self._nodeStack[nindex - 1] if nindex > 0 else ''
|
||||
}
|
||||
)
|
||||
nd_event = ChatCallbackEvent(event_type = ChatEventType.NODE_START,payload = args)
|
||||
if nd_event.to_response() is not None:
|
||||
self._aqueue.put_nowait(nd_event)
|
||||
|
||||
|
||||
def on_event_end(
|
||||
self,
|
||||
@@ -141,9 +230,25 @@ class ChatEventCallbackHandler(BaseCallbackHandler):
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
logger.info("event_end:{} type:{} payload:{}\n".format(event_id, event_type, payload))
|
||||
event = ChatCallbackEvent(event_id=event_id, event_type=event_type, payload=payload)
|
||||
if event.to_response() is not None:
|
||||
self._aqueue.put_nowait(event)
|
||||
|
||||
#self.response = payload.get("response","")
|
||||
args:Dict[str,Any] = self._params['ids']
|
||||
nodeID = self._nodeStack[-1]
|
||||
if nodeID == event_id:
|
||||
nindex = self._nodeStack.count() - 1
|
||||
args.update(
|
||||
{
|
||||
'nodeid':event_id,
|
||||
'title':event_type.name,
|
||||
'index':nindex + 1,
|
||||
'predecessor_node_id':self._nodeStack[nindex - 1] if nindex > 0 else ''
|
||||
}
|
||||
)
|
||||
nd_event = ChatCallbackEvent(event_type = ChatEventType.NODE_FINISHED,payload = args)
|
||||
if nd_event.to_response() is not None:
|
||||
self._aqueue.put_nowait(nd_event)
|
||||
self._nodeStack.pop()
|
||||
|
||||
|
||||
def start_trace(self, trace_id: Optional[str] = None) -> None:
|
||||
"""No-op."""
|
||||
@@ -156,6 +261,23 @@ class ChatEventCallbackHandler(BaseCallbackHandler):
|
||||
) -> None:
|
||||
"""No-op."""
|
||||
logger.info("trace_end:{} trace_map:{}\n".format(trace_id, trace_map))
|
||||
data:ChatRequestData = self._params['data']
|
||||
args:Dict[str,Any] = self._params['ids']
|
||||
args.update(
|
||||
{
|
||||
'response':self._response,
|
||||
'conversation_id': data.conversation_id
|
||||
}
|
||||
)
|
||||
wf_event = ChatCallbackEvent(event_type = ChatEventType.WORKFLOW_FINISHED,payload = args)
|
||||
if wf_event.to_response() is not None:
|
||||
self._aqueue.put_nowait(wf_event)
|
||||
|
||||
|
||||
args:Dict[str,Any] = self._params['ids']
|
||||
msgEnt_event = ChatCallbackEvent(event_type = ChatEventType.MESSAGE_END,payload = args)
|
||||
if msgEnt_event.to_response() is not None:
|
||||
self._aqueue.put_nowait(msgEnt_event)
|
||||
|
||||
async def async_event_gen(self) -> AsyncGenerator[ChatCallbackEvent, None]:
|
||||
while not self._aqueue.empty() or not self.is_done:
|
||||
@@ -173,95 +295,26 @@ class IDManager:
|
||||
"workflow_id": str(uuid.uuid4())
|
||||
}
|
||||
|
||||
class DifyChatResponseEvent(BaseModel):
|
||||
event: str
|
||||
conversation_id: str
|
||||
message_id: str
|
||||
created_at: int = int(time.time())
|
||||
task_id: str
|
||||
|
||||
class Workflow_started_DifyChatResponseEvent(DifyChatResponseEvent):
|
||||
workflow_run_id:str
|
||||
data:Dict[str,Any]
|
||||
def __init__(self,**args):
|
||||
args['data'] = {
|
||||
"id": args['workflow_run_id'],
|
||||
"workflow_id": args['workflow_id'],
|
||||
"sequence_number": 1709,
|
||||
"inputs": {
|
||||
"sys.query": args['query'],
|
||||
"sys.files": [],
|
||||
"sys.conversation_id": args['conversation_id'],
|
||||
"sys.user_id": args['use_id']
|
||||
},
|
||||
"created_at": int(time.time())
|
||||
}
|
||||
args['event'] = 'workflow_started'
|
||||
super().__init__(**args)
|
||||
|
||||
class Workflow_finished_DifyChatResponseEvent(DifyChatResponseEvent):
|
||||
workflow_run_id:str
|
||||
data:Dict[str,Any]
|
||||
def __init__(self,**args):
|
||||
args['event'] = 'workflow_finished'
|
||||
args['data'] = {
|
||||
"id": args['workflow_run_id'],
|
||||
"workflow_id": args['workflow_id'],
|
||||
"sequence_number": 1709,
|
||||
"status": "succeeded",
|
||||
"outputs": {
|
||||
"answer": args['response']
|
||||
},
|
||||
"error": '',
|
||||
"elapsed_time": 36.03764106379822,
|
||||
"total_tokens": 11707,
|
||||
"total_steps": 10,
|
||||
"created_by": {
|
||||
"id": str(uuid.uuid4()),
|
||||
"user": args['use_id']
|
||||
},
|
||||
"created_at": int(time.time()),
|
||||
"finished_at": int(time.time()),
|
||||
"files": []
|
||||
}
|
||||
super().__init__(**args)
|
||||
|
||||
class Message_DifyChatResponseEvent(DifyChatResponseEvent):
|
||||
id:str
|
||||
answer:str
|
||||
def __init__(self,**args):
|
||||
args['id'] = args['message_id']
|
||||
args['event'] = 'message'
|
||||
super().__init__(**args)
|
||||
|
||||
class MessageEnd_DifyChatResponseEvent(DifyChatResponseEvent):
|
||||
id:str
|
||||
metadata:Dict[str,Any] = {}
|
||||
def __init__(self,**args):
|
||||
args['id'] = args['message_id']
|
||||
args['event'] = 'message_end'
|
||||
super().__init__(**args)
|
||||
|
||||
class ChatStreamResponse(StreamingResponse):
|
||||
TEXT_PREFIX = "data: "
|
||||
DATA_PREFIX = "data: "
|
||||
ids:Dict[str,Any] = {}
|
||||
data:ChatRequestData = None
|
||||
|
||||
@classmethod
|
||||
def convert_text(cls, token: str):
|
||||
# Escape newlines and double quotes to avoid breaking the stream
|
||||
#token = json.dumps(token)
|
||||
|
||||
#return f"data: {{"event": "message", "conversation_id": "80d85523-de92-4b9d-aca0-c48a5eacb068", "message_id": "16a06b1b-a89b-49c0-bc15-123bd999f6d6", "created_at": 1724406492, "task_id": "802f3064-030d-42ac-a882-0e1293712d04", "id": "16a06b1b-a89b-49c0-bc15-123bd999f6d6", "answer": "{token}"}}"
|
||||
return "\n"
|
||||
|
||||
@classmethod
|
||||
def convert_data(cls, data: dict):
|
||||
data_str = json.dumps(data)
|
||||
def convert_Message(cls, token: str):
|
||||
params = cls.ids
|
||||
params.update({
|
||||
'answer':token,
|
||||
'conversation_id':cls.data.conversation_id
|
||||
})
|
||||
event = ChatCallbackEvent(event_type = ChatEventType.MESSAGE,payload = params)
|
||||
data_str = json.dumps(event.to_response())
|
||||
return f"{cls.DATA_PREFIX}{data_str}\n\n"
|
||||
|
||||
@classmethod
|
||||
def convert_event(cls, event: DifyChatResponseEvent):
|
||||
data_str = json.dumps(event.dict())
|
||||
def convert_Event(cls, data: dict):
|
||||
data_str = json.dumps(data)
|
||||
return f"{cls.DATA_PREFIX}{data_str}\n\n"
|
||||
|
||||
def __init__(
|
||||
@@ -269,8 +322,11 @@ class ChatStreamResponse(StreamingResponse):
|
||||
request: Request,
|
||||
event_handler: ChatEventCallbackHandler,
|
||||
response: StreamingAgentChatResponse,
|
||||
data: ChatRequestData
|
||||
data: ChatRequestData,
|
||||
ids:Dict[str,Any]
|
||||
):
|
||||
ChatStreamResponse.ids = ids
|
||||
ChatStreamResponse.data = data
|
||||
content = ChatStreamResponse.content_generator(
|
||||
request, event_handler, response, data
|
||||
)
|
||||
@@ -284,41 +340,26 @@ class ChatStreamResponse(StreamingResponse):
|
||||
response: StreamingAgentChatResponse,
|
||||
data: ChatRequestData
|
||||
):
|
||||
ids = IDManager().createID()
|
||||
|
||||
# Yield the text response
|
||||
async def _chat_response_generator():
|
||||
final_response = ""
|
||||
async for token in response.async_response_gen():
|
||||
final_response += token
|
||||
args = ids
|
||||
args['answer'] = token
|
||||
args['conversation_id'] = data.conversation_id
|
||||
event = Message_DifyChatResponseEvent(**args)
|
||||
yield ChatStreamResponse.convert_event(event)
|
||||
#yield ChatStreamResponse.convert_text(token)
|
||||
yield ChatStreamResponse.convert_Message(token)
|
||||
|
||||
# 存储消息历史
|
||||
message().add(user_id=data.user,conversation_id=data.conversation_id,query=data.query,answer=final_response)
|
||||
|
||||
# the text_generator is the leading stream, once it's finished, also finish the event stream
|
||||
event_handler.is_done = True
|
||||
# 发送工作流结束事件
|
||||
args = ids
|
||||
args['response'] = final_response
|
||||
args['conversation_id'] = data.conversation_id
|
||||
wf_event = Workflow_finished_DifyChatResponseEvent(**args)
|
||||
yield ChatStreamResponse.convert_event(wf_event)
|
||||
|
||||
msgEnt_event = MessageEnd_DifyChatResponseEvent(**ids)
|
||||
yield ChatStreamResponse.convert_event(msgEnt_event)
|
||||
|
||||
|
||||
# Yield the events from the event handler
|
||||
async def _event_generator():
|
||||
async for event in event_handler.async_event_gen():
|
||||
event_response = event.to_response()
|
||||
if event_response is not None:
|
||||
yield ChatStreamResponse.convert_text("")
|
||||
yield ChatStreamResponse.convert_Event(event_response)
|
||||
|
||||
combine = stream.merge(_chat_response_generator(), _event_generator())
|
||||
is_stream_started = False
|
||||
@@ -327,25 +368,11 @@ class ChatStreamResponse(StreamingResponse):
|
||||
if not is_stream_started:
|
||||
is_stream_started = True
|
||||
|
||||
# 发送工作流开始事件
|
||||
args = ids
|
||||
args['use_id'] = data.user
|
||||
args['query'] = data.query
|
||||
args['conversation_id'] = data.conversation_id
|
||||
wf_event = Workflow_started_DifyChatResponseEvent(**args)
|
||||
yield ChatStreamResponse.convert_event(wf_event)
|
||||
|
||||
# Stream a blank message to start the stream
|
||||
# 发送一个空消息事件
|
||||
#yield ChatStreamResponse.convert_text("")
|
||||
|
||||
yield output
|
||||
|
||||
if await request.is_disconnected():
|
||||
break
|
||||
|
||||
|
||||
|
||||
@v.post("/chat-messages")
|
||||
async def post_conversations(request: Request, data: ChatRequestData):
|
||||
userMng.findNoExistCreate(data.user)
|
||||
@@ -365,14 +392,15 @@ async def post_conversations(request: Request, data: ChatRequestData):
|
||||
chat_engine = get_chat_engine(filters=filters, params=params)
|
||||
|
||||
# 启动聊天事件监听
|
||||
event_handler = ChatEventCallbackHandler()
|
||||
ids = IDManager().createID()
|
||||
event_handler = ChatEventCallbackHandler(ids = ids,data = data)
|
||||
chat_engine.callback_manager.handlers.append(event_handler) # type: ignore
|
||||
|
||||
# 执行异步聊天
|
||||
response = await chat_engine.astream_chat(data.query)
|
||||
|
||||
# 返回异步消息回应
|
||||
return ChatStreamResponse(request, event_handler, response, data)
|
||||
return ChatStreamResponse(request, event_handler, response, data,ids)
|
||||
|
||||
@v.get("/messages")
|
||||
async def query_messages(user:str, conversation_id:str):
|
||||
@@ -388,8 +416,9 @@ async def query_messages(user:str, conversation_id:str):
|
||||
|
||||
for record in records:
|
||||
res = record.dict()
|
||||
feeds = feedback().query(res['id'])
|
||||
res["message_files"] = []
|
||||
res["feedback"] = ''
|
||||
res["feedback"] = {'rating':feeds['rating'] } if feeds != None else ''
|
||||
res["retriever_resources"] = []
|
||||
res["created_at"] = 1723444905
|
||||
res["agent_thoughts"] = []
|
||||
@@ -440,48 +469,22 @@ async def query_conversations(user:str, first_id:str = None, limit:str = None, p
|
||||
async def query_parameters(user:str):
|
||||
params = parameter().get(user)
|
||||
if len(params) == 0:
|
||||
params = {
|
||||
"opening_statement": "您好,我是配网D3造价软件小助手,您可以问我有关配网造价软件的相关问题!",
|
||||
"suggested_questions": [],
|
||||
"suggested_questions_after_answer": {
|
||||
"enabled": False
|
||||
},
|
||||
"speech_to_text": {
|
||||
"enabled": False
|
||||
},
|
||||
"text_to_speech": {
|
||||
"enabled": False,
|
||||
"language": "",
|
||||
"voice": ""
|
||||
},
|
||||
"retriever_resource": {
|
||||
"enabled": True
|
||||
},
|
||||
"annotation_reply": {
|
||||
"enabled": False
|
||||
},
|
||||
"more_like_this": {
|
||||
"enabled": False
|
||||
},
|
||||
"user_input_form": [],
|
||||
"sensitive_word_avoidance": {
|
||||
"enabled": False
|
||||
},
|
||||
"file_upload": {
|
||||
"image": {
|
||||
"enabled": False,
|
||||
"number_limits": 3,
|
||||
"transfer_methods": [
|
||||
"remote_url"
|
||||
]
|
||||
}
|
||||
},
|
||||
"system_parameters": {
|
||||
"image_file_size_limit": "10"
|
||||
}
|
||||
}
|
||||
params = BaseConfig().ParamterCfg()
|
||||
return params
|
||||
|
||||
@v.post("/messages/{message_id}/feedbacks")
|
||||
async def post_feedbacks(request: Request,message_id:str,params:Dict[str,Any]):
|
||||
if params['rating'] =='null':
|
||||
feedback().delete(message_id)
|
||||
else:
|
||||
condition = {'id':message_id}
|
||||
results = message().query(**condition)
|
||||
if len(results) > 0:
|
||||
result = results[0]
|
||||
feedback().add(message_id=message_id,query=result['query'],
|
||||
answer=result['answer'],rating=params['rating'])
|
||||
|
||||
@r.post("")
|
||||
def upload_file(request: ChatFileUploadRequest) -> List[str]:
|
||||
pass
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ class conversations:
|
||||
return None
|
||||
|
||||
def add(self,id:str, user_id:str, name:str):
|
||||
template = BaseConfig.ConversationCfg
|
||||
template = BaseConfig().ConversationCfg()
|
||||
template['id'] = id
|
||||
template['user_id'] = user_id
|
||||
template['name'] = name
|
||||
@@ -111,7 +111,7 @@ class message:
|
||||
return datas
|
||||
|
||||
def add(self,user_id:str,conversation_id:str,query:str,answer:str):
|
||||
template = BaseConfig.MessageCfg
|
||||
template = BaseConfig.MessageCfg()
|
||||
template['id'] = str(uuid.uuid4())
|
||||
template['user_id'] = user_id
|
||||
template['conversation_id'] = conversation_id
|
||||
@@ -122,4 +122,34 @@ class message:
|
||||
def delete(self,user_id:str):
|
||||
dbManage.delete(self._tableName,user_id = user_id)
|
||||
|
||||
def query(self,**condition):
|
||||
results = []
|
||||
records = dbManage.query(self._tableName,**condition)
|
||||
for record in records:
|
||||
results.append(record.dict())
|
||||
return results
|
||||
|
||||
class feedback:
|
||||
def __init__(self) -> None:
|
||||
self._tableName = 'feedbacks'
|
||||
dbManage.createTable(self._tableName)
|
||||
|
||||
def add(self,message_id:str,query:str,answer:str,rating:str):
|
||||
record = {
|
||||
'message_id': message_id,
|
||||
'query': query,
|
||||
'answer': answer,
|
||||
'rating': rating,
|
||||
}
|
||||
dbManage.addRecord(self._tableName,record)
|
||||
|
||||
def delete(self,message_id:str):
|
||||
cond = {'message_id':message_id}
|
||||
dbManage.delete(self._tableName,**cond)
|
||||
|
||||
def query(self,message_id:str):
|
||||
cond = {'message_id':message_id}
|
||||
records = dbManage.query(self._tableName,**cond)
|
||||
if len(records) > 0:
|
||||
return records[0].dict()
|
||||
return None
|
||||
@@ -1,8 +1,15 @@
|
||||
from pydantic import BaseModel
|
||||
import os
|
||||
from enum import Enum
|
||||
|
||||
class BaseConfig:
|
||||
ParamterCfg = {
|
||||
"opening_statement": "您好,我是配网D3造价软件小助手,您可以问我有关配网造价软件的相关问题!",
|
||||
"suggested_questions": [],
|
||||
class BaseConfig(BaseModel):
|
||||
projectInfo:str = os.getenv("PROJECT_TITLE","您好,我是博微工程理解小助手,您可以问我有关[线路工程]工程数据的相关问题!")
|
||||
|
||||
def ParamterCfg(self):
|
||||
questions = os.getenv("CONVERSATION_STARTERS", "dev")
|
||||
return{
|
||||
"opening_statement": self.projectInfo,
|
||||
"suggested_questions": questions.split('\n'),
|
||||
"suggested_questions_after_answer": {
|
||||
"enabled": False
|
||||
},
|
||||
@@ -41,18 +48,20 @@ class BaseConfig:
|
||||
}
|
||||
}
|
||||
|
||||
ConversationCfg = {
|
||||
def ConversationCfg(self):
|
||||
return{
|
||||
"id": "",
|
||||
'user_id':'',
|
||||
"name": "",
|
||||
"inputs": {},
|
||||
"status": "normal",
|
||||
"introduction": ParamterCfg['opening_statement'],
|
||||
"introduction": self.projectInfo,
|
||||
"created_at":''
|
||||
}
|
||||
|
||||
|
||||
MessageCfg = {
|
||||
@classmethod
|
||||
def MessageCfg(cls):
|
||||
return {
|
||||
"id": "",
|
||||
'user_id':'',
|
||||
"conversation_id": "",
|
||||
@@ -60,3 +69,12 @@ class BaseConfig:
|
||||
"query": "",
|
||||
"answer": ""
|
||||
}
|
||||
|
||||
|
||||
class ChatEventType(str, Enum):
|
||||
WORKFLOW_START = "workflow_started"
|
||||
WORKFLOW_FINISHED = "workflow_finished"
|
||||
NODE_START = "node_started"
|
||||
NODE_FINISHED = "node_finished"
|
||||
MESSAGE = "message"
|
||||
MESSAGE_END = "message_end"
|
||||
@@ -2,7 +2,7 @@ import os
|
||||
from typing import Dict, List, Any
|
||||
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy import create_engine, Column, String, Integer, JSON
|
||||
from sqlalchemy import create_engine, Column, String, Integer, JSON,Float
|
||||
from sqlalchemy.engine.reflection import Inspector
|
||||
from sqlalchemy.orm import sessionmaker, declarative_base
|
||||
|
||||
@@ -24,10 +24,6 @@ class ConversationOrm(Base):
|
||||
if 'name' in data:
|
||||
self.name = data['name']
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class UserOrm(Base):
|
||||
__tablename__ = "user"
|
||||
|
||||
@@ -51,6 +47,14 @@ class MessagesOrm(Base):
|
||||
query = Column(String)
|
||||
answer = Column(String)
|
||||
|
||||
class FeedBackOrm(Base):
|
||||
__tablename__ = "feedbacks"
|
||||
|
||||
message_id = Column(String,primary_key=True)
|
||||
query = Column(String)
|
||||
answer = Column(String)
|
||||
rating = Column(String)
|
||||
|
||||
#数据结构
|
||||
class ConversationModel(BaseModel):
|
||||
id: str
|
||||
@@ -61,7 +65,6 @@ class ConversationModel(BaseModel):
|
||||
created_at: int
|
||||
|
||||
class Config:
|
||||
#orm_mode = True
|
||||
from_attributes=True
|
||||
|
||||
@classmethod
|
||||
@@ -73,7 +76,6 @@ class UserModel(BaseModel):
|
||||
createtime: str
|
||||
|
||||
class Config:
|
||||
#orm_mode = True
|
||||
from_attributes=True
|
||||
|
||||
@classmethod
|
||||
@@ -86,7 +88,6 @@ class ParametersModel(BaseModel):
|
||||
value : Dict[str, Any]
|
||||
|
||||
class Config:
|
||||
#orm_mode = True
|
||||
from_attributes=True
|
||||
|
||||
@classmethod
|
||||
@@ -101,13 +102,25 @@ class MessagesModel(BaseModel):
|
||||
answer : str
|
||||
|
||||
class Config:
|
||||
#orm_mode = True
|
||||
from_attributes=True
|
||||
|
||||
@classmethod
|
||||
def orm(cls):
|
||||
return MessagesOrm
|
||||
|
||||
class FeedBackModel(BaseModel):
|
||||
message_id :str
|
||||
query :str
|
||||
answer :str
|
||||
rating :str
|
||||
|
||||
class Config:
|
||||
from_attributes=True
|
||||
|
||||
@classmethod
|
||||
def orm(cls):
|
||||
return FeedBackOrm
|
||||
|
||||
class DBManager:
|
||||
def __init__(self) -> None:
|
||||
DATABASE_URL = os.getenv("SQLITE_DATABASE_URL")
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
from typing import Dict, Any
|
||||
from pydantic import BaseModel
|
||||
|
||||
from typing import Optional
|
||||
|
||||
class ChatRequestData(BaseModel):
|
||||
inputs: Dict[str,Any]
|
||||
@@ -13,3 +13,5 @@ class ChatRequestData(BaseModel):
|
||||
|
||||
class ChatFileUploadRequest(BaseModel):
|
||||
base64: str
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import os
|
||||
from typing import Any, Dict, List, Union, Callable, NamedTuple
|
||||
from bm25s.tokenization import *
|
||||
|
||||
@@ -8,9 +9,12 @@ except ImportError:
|
||||
def tqdm(iterable, *args, **kwargs):
|
||||
return iterable
|
||||
|
||||
import jieba
|
||||
jiebapath = os.environ.get("JIEBA_DATA", "")
|
||||
jieba.set_dictionary(os.path.join(jiebapath, 'dict.txt')) #设置字典
|
||||
jieba.initialize() #初始化jeiba
|
||||
|
||||
def chinese_tokenizer(text: str) -> List[str]:
|
||||
import jieba
|
||||
from nltk.corpus import stopwords
|
||||
tokens = jieba.lcut(text)
|
||||
return [token for token in tokens if token not in stopwords.words('chinese')]
|
||||
|
||||
@@ -3,11 +3,10 @@ from typing import Dict
|
||||
|
||||
from llama_index.core.constants import DEFAULT_TEMPERATURE
|
||||
from llama_index.core.settings import Settings
|
||||
from app.xinference.base import XinferenceEmbedding, XinferenceRerank
|
||||
from llama_index.llms.xinference import Xinference
|
||||
from llama_index.llms.xinference.base import DEFAULT_XINFERENCE_TEMP
|
||||
|
||||
from app.xinference.base import XinferenceEmbedding, XinferenceRerank
|
||||
|
||||
|
||||
def get_node_postprocessors():
|
||||
rerank_enabled = os.getenv("RERANK_ENABLED").title()
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
|
||||
from dotenv import load_dotenv
|
||||
from llama_index.core.node_parser import SentenceSplitter
|
||||
|
||||
load_dotenv()
|
||||
|
||||
import logging
|
||||
|
||||
Binary file not shown.
Binary file not shown.
+349046
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@@ -17,7 +17,7 @@ aiostream = "^0.6.2"
|
||||
llama-index = "0.10.63"
|
||||
cachetools = "^5.3.3"
|
||||
protobuf = "4.25.4"
|
||||
nltk = "^3.8.2"
|
||||
nltk = "^3.9.1"
|
||||
jieba = "^0.42.1"
|
||||
|
||||
#arize-phoenix = "^4.12.0"
|
||||
@@ -35,6 +35,7 @@ chroma="^0.2.0"
|
||||
llama-index-vector-stores-chroma = "^0.1.10"
|
||||
llama-index-readers-json = "^0.1.5"
|
||||
llama-index-retrievers-bm25 = "^0.2.2"
|
||||
llama-index-experimental = "^0.2.0"
|
||||
|
||||
duckduckgo_search = "^6.2.6"
|
||||
|
||||
@@ -62,6 +63,12 @@ version = "^0.8"
|
||||
version = "0.0.7"
|
||||
|
||||
|
||||
|
||||
[[tool.poetry.source]]
|
||||
name = "mirrors"
|
||||
url = "https://pypi.tuna.tsinghua.edu.cn/simple/"
|
||||
priority = "default"
|
||||
|
||||
[build-system]
|
||||
requires = [ "poetry-core" ]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
@@ -0,0 +1,138 @@
|
||||
import nest_asyncio
|
||||
nest_asyncio.apply()
|
||||
from llama_index.core import SimpleDirectoryReader
|
||||
from llama_index.core.node_parser import SentenceSplitter
|
||||
from llama_index.core import VectorStoreIndex
|
||||
from llama_index.core.evaluation import (
|
||||
FaithfulnessEvaluator,
|
||||
DatasetGenerator,
|
||||
CorrectnessEvaluator,
|
||||
SemanticSimilarityEvaluator,
|
||||
)
|
||||
from llama_index.experimental.param_tuner import ParamTuner
|
||||
from llama_index.experimental.param_tuner.base import RunResult
|
||||
from llama_index.llms.openai import OpenAI
|
||||
|
||||
import asyncio
|
||||
|
||||
# 初始化环境
|
||||
from app.observability import init_observability
|
||||
from app.settings import init_settings
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
init_settings()
|
||||
init_observability()
|
||||
|
||||
# 读取文档
|
||||
documents = SimpleDirectoryReader("D:/LLM_model/text2sql/zjdataai-app-test/backend/data-test").load_data()
|
||||
|
||||
# 参数字典
|
||||
param_dict = {
|
||||
"chunk_size": [512, 1024],
|
||||
"top_k": [1, 5],
|
||||
"temperature": [0.1, 1.0]
|
||||
}
|
||||
|
||||
# 辅助函数
|
||||
def _build_index(chunk_size, documents):
|
||||
# 构建索引
|
||||
splitter = SentenceSplitter(chunk_size=chunk_size)
|
||||
vector_index = VectorStoreIndex.from_documents(
|
||||
documents, transformations=[splitter],
|
||||
)
|
||||
return vector_index
|
||||
|
||||
# 评估函数
|
||||
def evaluate_query_engine(query_engine, questions):
|
||||
loop = asyncio.get_event_loop()
|
||||
correct, total = loop.run_until_complete(_evaluate_query_engine_async(query_engine, questions))
|
||||
return correct, total
|
||||
|
||||
async def _evaluate_query_engine_async(query_engine, questions):
|
||||
c = [query_engine.aquery(q) for q in questions]
|
||||
gathering_future = asyncio.gather(*c)
|
||||
results = await gathering_future
|
||||
|
||||
total_correct = 0
|
||||
for r in results:
|
||||
eval_result = (
|
||||
1 if FaithfulnessEvaluator().evaluate_response(response=r).passing else 0
|
||||
)
|
||||
total_correct += eval_result
|
||||
|
||||
return total_correct, len(results)
|
||||
|
||||
|
||||
|
||||
# 生成问题
|
||||
question_generator = DatasetGenerator.from_documents(documents)
|
||||
eval_questions = question_generator.generate_questions_from_nodes(1) # 假设生成10个问题
|
||||
|
||||
# 打印生成的问题
|
||||
for i, q in enumerate(eval_questions, start=1):
|
||||
print(f"问题 {i}: {q}")
|
||||
|
||||
# 目标函数
|
||||
def objective_function(params_dict, documents, questions):
|
||||
chunk_size = params_dict["chunk_size"]
|
||||
top_k = params_dict["top_k"]
|
||||
temperature = params_dict["temperature"]
|
||||
|
||||
# 构建索引
|
||||
vector_index = _build_index(chunk_size, documents)
|
||||
|
||||
# 查询引擎
|
||||
query_engine = vector_index.as_query_engine(
|
||||
similarity_top_k=top_k, temperature=temperature
|
||||
)
|
||||
|
||||
# 评估查询引擎
|
||||
correct, total = 0, len(questions)
|
||||
question_answers = [] # 添加列表来收集问题和答案
|
||||
|
||||
for question in questions:
|
||||
response = query_engine.query(question)
|
||||
if response is not None:
|
||||
question_answers.append((question, response.response))
|
||||
eval_result = FaithfulnessEvaluator().evaluate_response(response=response, query_str=question)
|
||||
if eval_result.passing:
|
||||
correct += 1
|
||||
|
||||
# 计算分数
|
||||
score = correct / total if total > 0 else 0
|
||||
return RunResult(score=score, params=params_dict, question_answers=question_answers)
|
||||
|
||||
# 创建 ParamTuner 实例
|
||||
param_tuner = ParamTuner(
|
||||
param_fn=lambda params_dict: objective_function(params_dict, documents, eval_questions),
|
||||
param_dict=param_dict,
|
||||
show_progress=True,
|
||||
)
|
||||
|
||||
# 调用 tune 方法
|
||||
results = param_tuner.tune()
|
||||
best_result = results.best_run_result
|
||||
best_top_k = best_result.params["top_k"]
|
||||
best_chunk_size = best_result.params["chunk_size"]
|
||||
best_temperature = best_result.params["temperature"]
|
||||
print(f"得分: {best_result.score}")
|
||||
print(f"Top-k: {best_top_k}")
|
||||
print(f"文本块大小: {best_chunk_size}")
|
||||
print(f"温度: {best_temperature}")
|
||||
|
||||
# 使用最佳参数再次运行查询引擎,并打印问题与答案
|
||||
best_vector_index = _build_index(best_chunk_size, documents)
|
||||
best_query_engine = best_vector_index.as_query_engine(
|
||||
similarity_top_k=best_top_k, temperature=best_temperature
|
||||
)
|
||||
|
||||
best_question_answers = []
|
||||
for question in eval_questions:
|
||||
response = best_query_engine.query(question)
|
||||
if response is not None:
|
||||
best_question_answers.append((question, response.response))
|
||||
|
||||
# 打印最佳参数下的问题与答案
|
||||
for i, (question, answer) in enumerate(best_question_answers, start=1):
|
||||
print(f"最佳参数 - 问题 {i}: {question}\n答案: {answer}\n")
|
||||
@@ -0,0 +1,81 @@
|
||||
from app.observability import init_observability
|
||||
from app.settings import init_settings
|
||||
from dotenv import load_dotenv
|
||||
|
||||
import nest_asyncio
|
||||
nest_asyncio.apply()
|
||||
|
||||
load_dotenv()
|
||||
|
||||
|
||||
from llama_index.core.node_parser import SentenceSplitter
|
||||
from llama_index.core import (
|
||||
VectorStoreIndex,
|
||||
SimpleDirectoryReader,
|
||||
Response,
|
||||
)
|
||||
from llama_index.core.evaluation import (
|
||||
FaithfulnessEvaluator,
|
||||
DatasetGenerator,
|
||||
CorrectnessEvaluator,
|
||||
SemanticSimilarityEvaluator,)
|
||||
|
||||
|
||||
|
||||
init_settings()
|
||||
init_observability()
|
||||
|
||||
faith_evaluator_qwen = FaithfulnessEvaluator() #诚实度评测
|
||||
corr_evaluator_qwen = CorrectnessEvaluator() #准确率评测
|
||||
Seman_evaluator_qwen = SemanticSimilarityEvaluator()#嵌入相似度评估
|
||||
|
||||
documents = SimpleDirectoryReader("D:/LLM_model/text2sql/zjdataai-app-test/backend/data-test").load_data()
|
||||
|
||||
splitter = SentenceSplitter(chunk_size=512)
|
||||
|
||||
|
||||
vector_index = VectorStoreIndex.from_documents(
|
||||
documents, transformations=[splitter],
|
||||
)
|
||||
|
||||
|
||||
# # 运行评估
|
||||
# query_engine = vector_index.as_query_engine()
|
||||
# response_vector = query_engine.query("工程监理费的金额是多少?")
|
||||
# eval_result = evaluator_qwen.evaluate_response(response=response_vector)
|
||||
|
||||
# print(response_vector)
|
||||
# print(eval_result)
|
||||
|
||||
|
||||
question_generator = DatasetGenerator.from_documents(documents)
|
||||
eval_questions = question_generator.generate_questions_from_nodes(5)
|
||||
print(eval_questions)
|
||||
|
||||
import asyncio
|
||||
|
||||
async def evaluate_query_engine_async(query_engine, questions):
|
||||
c = [query_engine.aquery(q) for q in questions]
|
||||
gathering_future = asyncio.gather(*c)
|
||||
results = await gathering_future
|
||||
#print(results)
|
||||
|
||||
total_correct = 0
|
||||
for r in results:
|
||||
eval_result = (
|
||||
1 if faith_evaluator_qwen.evaluate_response(response=r).passing else 0
|
||||
)
|
||||
total_correct += eval_result
|
||||
|
||||
return total_correct, len(results)
|
||||
|
||||
def evaluate_query_engine(query_engine, questions):
|
||||
loop = asyncio.get_event_loop()
|
||||
correct, total = loop.run_until_complete(evaluate_query_engine_async(query_engine, questions))
|
||||
return correct, total
|
||||
|
||||
# 使用 evaluate_query_engine 函数
|
||||
vector_query_engine = vector_index.as_query_engine()
|
||||
correct, total = evaluate_query_engine(vector_query_engine, eval_questions[:5])
|
||||
|
||||
print(f"score: {correct}/{total}")
|
||||
@@ -0,0 +1,202 @@
|
||||
[
|
||||
{
|
||||
"question": "人工费的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "临时设施费的费率是多少?",
|
||||
"answer": "费率是6.3500000000"
|
||||
},
|
||||
{
|
||||
"question": "乙供装置性材料费的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "直接费的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "甲供装置性材料费的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "直接费的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "夜间施工增加费的费率是多少?",
|
||||
"answer": "费率是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "装置性材料费的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "冬雨季施工增加费的费率是多少?",
|
||||
"answer": "费率是3.5700000000"
|
||||
},
|
||||
{
|
||||
"question": "材料费的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "机械价差的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "规费的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "直接工程费的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "安全文明施工费的费率是多少?",
|
||||
"answer": "费率是3.5500000000"
|
||||
},
|
||||
{
|
||||
"question": "企业管理费的费率是多少?",
|
||||
"answer": "费率是35.7600000000"
|
||||
},
|
||||
{
|
||||
"question": "税金的费率是多少?",
|
||||
"answer": "费率是9.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "直接费的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "安全文明施工费的费率是多少?",
|
||||
"answer": "费率是3.5500000000"
|
||||
},
|
||||
{
|
||||
"question": "合计的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "税金的费率是多少?",
|
||||
"answer": "费率是9.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "安全文明施工费的费率是多少?",
|
||||
"answer": "费率是3.5500000000"
|
||||
},
|
||||
{
|
||||
"question": "直接工程费的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "税金的费率是多少?",
|
||||
"answer": "费率是9.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "社会保险费的费率是多少?",
|
||||
"answer": "费率是15.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "间接费的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "合计的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "临时设施费的费率是多少?",
|
||||
"answer": "费率是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "利润的费率是多少?",
|
||||
"answer": "费率是5.2400000000"
|
||||
},
|
||||
{
|
||||
"question": "税金的费率是多少?",
|
||||
"answer": "费率是9.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "社会保险费的费率是多少?",
|
||||
"answer": "费率是15.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "直接工程费的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "乙供设备不含税价的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "企业管理费的费率是多少?",
|
||||
"answer": "费率是17.1300000000"
|
||||
},
|
||||
{
|
||||
"question": "企业管理费的费率是多少?",
|
||||
"answer": "费率是35.7600000000"
|
||||
},
|
||||
{
|
||||
"question": "夜间施工增加费的费率是多少?",
|
||||
"answer": "费率是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "直接费的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "夜间施工增加费的费率是多少?",
|
||||
"answer": "费率是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "甲供设备含税价的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "施工机械使用费的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "安全文明施工费的费率是多少?",
|
||||
"answer": "费率是3.5500000000"
|
||||
},
|
||||
{
|
||||
"question": "定额直接费的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "主材费的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "直接费的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "施工企业配合调试费的费率是多少?",
|
||||
"answer": "费率是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "施工机械使用费的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "临时设施费的费率是多少?",
|
||||
"answer": "费率是6.3500000000"
|
||||
},
|
||||
{
|
||||
"question": "施工工具用具使用费的费率是多少?",
|
||||
"answer": "费率是3.8200000000"
|
||||
},
|
||||
{
|
||||
"question": "措施费的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "材料价差的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "措施费的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,202 @@
|
||||
[
|
||||
{
|
||||
"question": "前期工作管理费用的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "特种设备安全监测费的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "工程监理费的金额是多少?",
|
||||
"answer": "金额是131009.9200000000"
|
||||
},
|
||||
{
|
||||
"question": "水土保持方案编审费用的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "生产准备费的金额是多少?",
|
||||
"answer": "金额是472373669.4635599852"
|
||||
},
|
||||
{
|
||||
"question": "电力工程技术经济标准编制费的金额是多少?",
|
||||
"answer": "金额是84352440.9756360054"
|
||||
},
|
||||
{
|
||||
"question": "项目建设技术服务费的金额是多少?",
|
||||
"answer": "金额是16855957065.4302005768"
|
||||
},
|
||||
{
|
||||
"question": "工程保险费的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "其他的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "施工图文件评审费的金额是多少?",
|
||||
"answer": "金额是24940.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "节能评估费用的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "桩基检测费的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "项目前期工作费的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "其他的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "项目法人管理费的金额是多少?",
|
||||
"answer": "金额是986923559.4149370193"
|
||||
},
|
||||
{
|
||||
"question": "专业爆破服务费的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "节能评估费用的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "用地预审费用的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "设备材料监造费的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "环境监测及环境保护验收费的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "环境监测及环境保护验收费的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "设备材料监造费的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "勘察费的金额是多少?",
|
||||
"answer": "金额是12122154260.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "项目法人管理费的金额是多少?",
|
||||
"answer": "金额是986923559.4149370193"
|
||||
},
|
||||
{
|
||||
"question": "社会稳定风险评估费用的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "勘察费的金额是多少?",
|
||||
"answer": "金额是12122154260.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "环境影响评价费用的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "水土保持方案编审费用的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "使用林地可行性研究费用的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "环境监测及环境保护验收费的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "桩基检测费的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "设计费的金额是多少?",
|
||||
"answer": "金额是4042055949.4299998283"
|
||||
},
|
||||
{
|
||||
"question": "环境监测及环境保护验收费的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "建设场地征用及清理费的金额是多少?",
|
||||
"answer": "金额是16831284.2287110016"
|
||||
},
|
||||
{
|
||||
"question": "施工图文件评审费的金额是多少?",
|
||||
"answer": "金额是24940.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "项目后评价费的金额是多少?",
|
||||
"answer": "金额是421762204.8781780005"
|
||||
},
|
||||
{
|
||||
"question": "水土保持方案编审费用的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "勘察设计费的金额是多少?",
|
||||
"answer": "金额是16164210209.4300003052"
|
||||
},
|
||||
{
|
||||
"question": "前期工作管理费用的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "节能评估费用的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "初步设计文件评审费的金额是多少?",
|
||||
"answer": "金额是18560.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "特种设备安全监测费的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "初步设计文件评审费的金额是多少?",
|
||||
"answer": "金额是18560.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "桩基检测费的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "矿产压覆评估费用的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "设计费的金额是多少?",
|
||||
"answer": "金额是4042055949.4299998283"
|
||||
},
|
||||
{
|
||||
"question": "水土保持方案编审费用的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "电力工程技术经济标准编制费的金额是多少?",
|
||||
"answer": "金额是84352440.9756360054"
|
||||
},
|
||||
{
|
||||
"question": "桩基检测费的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "矿产压覆评估费用的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,202 @@
|
||||
[
|
||||
{
|
||||
"question": "新增项目名称的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "预制基础的合价是多少?",
|
||||
"answer": "合价是40567.2639480000"
|
||||
},
|
||||
{
|
||||
"question": "绝缘子串及金具安装的合价是多少?",
|
||||
"answer": "合价是2897171.9878110001"
|
||||
},
|
||||
{
|
||||
"question": "杆塔工程材料工地运输的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "基础防护的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "护坡、挡土墙及排洪沟土石方工程的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "新增项目名称的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "(1)拆除后能利用的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "地基处理的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "灌注桩基础的合价是多少?",
|
||||
"answer": "合价是43466660.0544390008"
|
||||
},
|
||||
{
|
||||
"question": "(1)拆除后能利用的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "悬垂绝缘子串及金具安装的合价是多少?",
|
||||
"answer": "合价是1251465.0340440001"
|
||||
},
|
||||
{
|
||||
"question": "护坡、挡土墙及排洪沟土石方工程的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "附件安装工程的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "导地线跨越架设的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "辅助工程的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "新增项目名称的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "绝缘子串及金具安装的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "护坡、挡土墙及排洪沟砌筑的合价是多少?",
|
||||
"answer": "合价是709931.9013930000"
|
||||
},
|
||||
{
|
||||
"question": "锚杆基础的合价是多少?",
|
||||
"answer": "合价是15344967.9002950005"
|
||||
},
|
||||
{
|
||||
"question": "建筑工程的合价是多少?",
|
||||
"answer": "合价是25411.2790780000"
|
||||
},
|
||||
{
|
||||
"question": "辅助工程的合价是多少?",
|
||||
"answer": "合价是1046253.4135240000"
|
||||
},
|
||||
{
|
||||
"question": "导地线跨越架设的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "电缆工程的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "输、送电线路试运的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "基础土石方工程的合价是多少?",
|
||||
"answer": "合价是32872843180.7429008484"
|
||||
},
|
||||
{
|
||||
"question": "基础永久性围堰的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "基础永久性围堰的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "混凝土及钢筋混凝土结构的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "输、送电线路试运的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "混合结构的合价是多少?",
|
||||
"answer": "合价是16967.5193850000"
|
||||
},
|
||||
{
|
||||
"question": "杆塔组立的合价是多少?",
|
||||
"answer": "合价是2253906.0859830002"
|
||||
},
|
||||
{
|
||||
"question": "附件安装工程的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "接地工程材料工地运输的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "新增项目名称的合价是多少?",
|
||||
"answer": "合价是27148.0310160000"
|
||||
},
|
||||
{
|
||||
"question": "导地线架设的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "护坡、挡土墙及排洪沟的合价是多少?",
|
||||
"answer": "合价是709931.9013930000"
|
||||
},
|
||||
{
|
||||
"question": "(1)拆除后能利用的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "基础永久性围堰砌筑的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "(2)拆除后不能利用的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "安装工程的合价是多少?",
|
||||
"answer": "合价是65324.9496330000"
|
||||
},
|
||||
{
|
||||
"question": "尖峰、施工基面土石方工程的合价是多少?",
|
||||
"answer": "合价是325205.4178770000"
|
||||
},
|
||||
{
|
||||
"question": "架线工程的合价是多少?",
|
||||
"answer": "合价是4844399648.0778598785"
|
||||
},
|
||||
{
|
||||
"question": "杆塔组立的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "架线工程材料工地运输的合价是多少?",
|
||||
"answer": "合价是2088570123.2409000397"
|
||||
},
|
||||
{
|
||||
"question": "导地线架设的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "耐张绝缘子串及金具安装的合价是多少?",
|
||||
"answer": "合价是1645706.9537680000"
|
||||
},
|
||||
{
|
||||
"question": "架线工程材料工地运输的合价是多少?",
|
||||
"answer": "合价是2088570123.2409000397"
|
||||
},
|
||||
{
|
||||
"question": "其他基础的合价是多少?",
|
||||
"answer": "合价是3839666.7656879998"
|
||||
},
|
||||
{
|
||||
"question": "架线工程材料工地运输的合价是多少?",
|
||||
"answer": "合价是0E-10"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,202 @@
|
||||
[
|
||||
{
|
||||
"question": "线路取费表的直接费是多少?",
|
||||
"answer": "直接费是440877984.9458540082"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表(拆除)的直接费是多少?",
|
||||
"answer": "直接费是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表的直接费是多少?",
|
||||
"answer": "直接费是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表的直接费是多少?",
|
||||
"answer": "直接费是1086586.9018659999"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表的直接费是多少?",
|
||||
"answer": "直接费是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表(拆除)的直接费是多少?",
|
||||
"answer": "直接费是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表的直接费是多少?",
|
||||
"answer": "直接费是51486.7898090000"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表的直接费是多少?",
|
||||
"answer": "直接费是3321.8139230000"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表的直接费是多少?",
|
||||
"answer": "直接费是78005.0340730000"
|
||||
},
|
||||
{
|
||||
"question": "的直接费是多少?",
|
||||
"answer": "直接费是3535892767.0972299576"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表的直接费是多少?",
|
||||
"answer": "直接费是24045.2334060000"
|
||||
},
|
||||
{
|
||||
"question": "的直接费是多少?",
|
||||
"answer": "直接费是336253.7482950000"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表的直接费是多少?",
|
||||
"answer": "直接费是142270.1346780000"
|
||||
},
|
||||
{
|
||||
"question": "的直接费是多少?",
|
||||
"answer": "直接费是61049.8665780000"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表(拆除)的直接费是多少?",
|
||||
"answer": "直接费是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表的直接费是多少?",
|
||||
"answer": "直接费是933061.7795919999"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表的直接费是多少?",
|
||||
"answer": "直接费是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "的直接费是多少?",
|
||||
"answer": "直接费是182949.5997350000"
|
||||
},
|
||||
{
|
||||
"question": "的直接费是多少?",
|
||||
"answer": "直接费是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表(余物清理)的直接费是多少?",
|
||||
"answer": "直接费是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表(拆除)的直接费是多少?",
|
||||
"answer": "直接费是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表的直接费是多少?",
|
||||
"answer": "直接费是21220645.1637400016"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表的直接费是多少?",
|
||||
"answer": "直接费是933061.7795919999"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表的直接费是多少?",
|
||||
"answer": "直接费是2501470269.7231497765"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表的直接费是多少?",
|
||||
"answer": "直接费是51486.7898090000"
|
||||
},
|
||||
{
|
||||
"question": "的直接费是多少?",
|
||||
"answer": "直接费是55265.9111100000"
|
||||
},
|
||||
{
|
||||
"question": "的直接费是多少?",
|
||||
"answer": "直接费是442897633.6273120046"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表(拆除)的直接费是多少?",
|
||||
"answer": "直接费是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表的直接费是多少?",
|
||||
"answer": "直接费是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "的直接费是多少?",
|
||||
"answer": "直接费是1057484.3306960000"
|
||||
},
|
||||
{
|
||||
"question": "的直接费是多少?",
|
||||
"answer": "直接费是442897633.6273120046"
|
||||
},
|
||||
{
|
||||
"question": "的直接费是多少?",
|
||||
"answer": "直接费是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表的直接费是多少?",
|
||||
"answer": "直接费是21220645.1637400016"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表(余物清理)的直接费是多少?",
|
||||
"answer": "直接费是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "的直接费是多少?",
|
||||
"answer": "直接费是336253.7482950000"
|
||||
},
|
||||
{
|
||||
"question": "的直接费是多少?",
|
||||
"answer": "直接费是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "的直接费是多少?",
|
||||
"answer": "直接费是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "的直接费是多少?",
|
||||
"answer": "直接费是61049.8665780000"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表(余物清理)(1)的直接费是多少?",
|
||||
"answer": "直接费是61049.8665780000"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表的直接费是多少?",
|
||||
"answer": "直接费是24045.2334060000"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表(拆除)的直接费是多少?",
|
||||
"answer": "直接费是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表(拆除)的直接费是多少?",
|
||||
"answer": "直接费是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表的直接费是多少?",
|
||||
"answer": "直接费是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表(余物清理)的直接费是多少?",
|
||||
"answer": "直接费是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表(拆除)的直接费是多少?",
|
||||
"answer": "直接费是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表(拆除)的直接费是多少?",
|
||||
"answer": "直接费是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表的直接费是多少?",
|
||||
"answer": "直接费是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表的直接费是多少?",
|
||||
"answer": "直接费是659466.5955000001"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表(拆除)的直接费是多少?",
|
||||
"answer": "直接费是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "线路取费表的直接费是多少?",
|
||||
"answer": "直接费是2501470269.7231497765"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,202 @@
|
||||
[
|
||||
{
|
||||
"question": "降阻剂_数量的属性值是多少?",
|
||||
"answer": "属性值是f"
|
||||
},
|
||||
{
|
||||
"question": "导线2_单位单价的属性值是多少?",
|
||||
"answer": "属性值是9"
|
||||
},
|
||||
{
|
||||
"question": "导线_单公里用量的属性值是多少?",
|
||||
"answer": "属性值是36"
|
||||
},
|
||||
{
|
||||
"question": "线路参数_导地线防震措施的属性值是多少?",
|
||||
"answer": "属性值是457"
|
||||
},
|
||||
{
|
||||
"question": "合成绝缘子_数量的属性值是多少?",
|
||||
"answer": "属性值是5"
|
||||
},
|
||||
{
|
||||
"question": "基础垫层的属性值是多少?",
|
||||
"answer": "属性值是"
|
||||
},
|
||||
{
|
||||
"question": "其中:基础护壁用量的属性值是多少?",
|
||||
"answer": "属性值是74394.212"
|
||||
},
|
||||
{
|
||||
"question": "铺石加混凝土的属性值是多少?",
|
||||
"answer": "属性值是0.0"
|
||||
},
|
||||
{
|
||||
"question": "导线用量(西北)的属性值是多少?",
|
||||
"answer": "属性值是-795976.0855"
|
||||
},
|
||||
{
|
||||
"question": "导线单公里用量(西北)的属性值是多少?",
|
||||
"answer": "属性值是-159195.2171"
|
||||
},
|
||||
{
|
||||
"question": "灰土垫层单公里用量(西北)的属性值是多少?",
|
||||
"answer": "属性值是8.0"
|
||||
},
|
||||
{
|
||||
"question": "地线瓷绝缘子单公里用量(西北)的属性值是多少?",
|
||||
"answer": "属性值是738.253"
|
||||
},
|
||||
{
|
||||
"question": "地形条件_高山的属性值是多少?",
|
||||
"answer": "属性值是7"
|
||||
},
|
||||
{
|
||||
"question": "流砂坑比例的属性值是多少?",
|
||||
"answer": "属性值是0.001"
|
||||
},
|
||||
{
|
||||
"question": "碎石_数量的属性值是多少?",
|
||||
"answer": "属性值是12"
|
||||
},
|
||||
{
|
||||
"question": "线路参数_导地线防震措施的属性值是多少?",
|
||||
"answer": "属性值是457"
|
||||
},
|
||||
{
|
||||
"question": "灰土垫层的属性值是多少?",
|
||||
"answer": "属性值是40.0"
|
||||
},
|
||||
{
|
||||
"question": "交叉跨越_弱电线路的属性值是多少?",
|
||||
"answer": "属性值是45"
|
||||
},
|
||||
{
|
||||
"question": "地线1_根数的属性值是多少?",
|
||||
"answer": "属性值是12"
|
||||
},
|
||||
{
|
||||
"question": "土质比例_岩石(人凿)的属性值是多少?",
|
||||
"answer": "属性值是49"
|
||||
},
|
||||
{
|
||||
"question": "耐张混凝土杆基数的属性值是多少?",
|
||||
"answer": "属性值是26.0"
|
||||
},
|
||||
{
|
||||
"question": "设计单位的属性值是多少?",
|
||||
"answer": "属性值是3"
|
||||
},
|
||||
{
|
||||
"question": "接地钢的属性值是多少?",
|
||||
"answer": "属性值是"
|
||||
},
|
||||
{
|
||||
"question": "间隔棒_单公里用量的属性值是多少?",
|
||||
"answer": "属性值是r"
|
||||
},
|
||||
{
|
||||
"question": "导线其中:跳线和导线弧垂单公里用量(西北)的属性值是多少?",
|
||||
"answer": "属性值是159203.0171"
|
||||
},
|
||||
{
|
||||
"question": "桩基础的属性值是多少?",
|
||||
"answer": "属性值是310.0"
|
||||
},
|
||||
{
|
||||
"question": "降阻剂的属性值是多少?",
|
||||
"answer": "属性值是"
|
||||
},
|
||||
{
|
||||
"question": "可抵扣增值税(万元)的属性值是多少?",
|
||||
"answer": "属性值是2005241.808822"
|
||||
},
|
||||
{
|
||||
"question": "主要技术经济指标2的属性值是多少?",
|
||||
"answer": "属性值是"
|
||||
},
|
||||
{
|
||||
"question": "合成绝缘子_数量的属性值是多少?",
|
||||
"answer": "属性值是5"
|
||||
},
|
||||
{
|
||||
"question": "土质比例_水坑的属性值是多少?",
|
||||
"answer": "属性值是47"
|
||||
},
|
||||
{
|
||||
"question": "基础_插入式的属性值是多少?",
|
||||
"answer": "属性值是3"
|
||||
},
|
||||
{
|
||||
"question": "耐张角钢塔比例的属性值是多少?",
|
||||
"answer": "属性值是250%"
|
||||
},
|
||||
{
|
||||
"question": "地线的属性值是多少?",
|
||||
"answer": "属性值是"
|
||||
},
|
||||
{
|
||||
"question": "回路数的属性值是多少?",
|
||||
"answer": "属性值是三回"
|
||||
},
|
||||
{
|
||||
"question": "导线其中:跳线和导线弧垂用量的属性值是多少?",
|
||||
"answer": "属性值是796015.0855"
|
||||
},
|
||||
{
|
||||
"question": "OPGW用量(西北)的属性值是多少?",
|
||||
"answer": "属性值是2904.737"
|
||||
},
|
||||
{
|
||||
"question": "现浇混凝土_单公里用量的属性值是多少?",
|
||||
"answer": "属性值是22"
|
||||
},
|
||||
{
|
||||
"question": "架线工程费用(万元)(含价差)的属性值是多少?",
|
||||
"answer": "属性值是3203726.0"
|
||||
},
|
||||
{
|
||||
"question": "耐张钢管塔比例的属性值是多少?",
|
||||
"answer": "属性值是300%"
|
||||
},
|
||||
{
|
||||
"question": "单公里土石方量_基面的属性值是多少?",
|
||||
"answer": "属性值是8*8"
|
||||
},
|
||||
{
|
||||
"question": "地线2的属性值是多少?",
|
||||
"answer": "属性值是"
|
||||
},
|
||||
{
|
||||
"question": "降阻剂的属性值是多少?",
|
||||
"answer": "属性值是"
|
||||
},
|
||||
{
|
||||
"question": "土质比例的属性值是多少?",
|
||||
"answer": "属性值是"
|
||||
},
|
||||
{
|
||||
"question": "地线1_单位单价的属性值是多少?",
|
||||
"answer": "属性值是113"
|
||||
},
|
||||
{
|
||||
"question": "绝缘子串型式_悬垂串的属性值是多少?",
|
||||
"answer": "属性值是48"
|
||||
},
|
||||
{
|
||||
"question": "基坑土石方量(西北)的属性值是多少?",
|
||||
"answer": "属性值是405403506.156"
|
||||
},
|
||||
{
|
||||
"question": "基坑坚土的属性值是多少?",
|
||||
"answer": "属性值是25585167.713"
|
||||
},
|
||||
{
|
||||
"question": "基坑普通土的属性值是多少?",
|
||||
"answer": "属性值是313873965.334"
|
||||
},
|
||||
{
|
||||
"question": "瓷绝缘子单公里用量(西北)的属性值是多少?",
|
||||
"answer": "属性值是201.0"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,202 @@
|
||||
[
|
||||
{
|
||||
"question": "电杆坑、塔坑、拉线坑人工挖方(或爆破)及回填 水坑 坑深2.0m以内的编码是多少?",
|
||||
"answer": "编码是YX2-72"
|
||||
},
|
||||
{
|
||||
"question": "钢筋加工及制作的编码是多少?",
|
||||
"answer": "编码是YX3-43"
|
||||
},
|
||||
{
|
||||
"question": "船舶运输 线材 每件重400kg以内 运输的编码是多少?",
|
||||
"answer": "编码是YX1-132"
|
||||
},
|
||||
{
|
||||
"question": "船舶运输 钢管塔材 运输的编码是多少?",
|
||||
"answer": "编码是YX1-152"
|
||||
},
|
||||
{
|
||||
"question": "碎石的编码是多少?",
|
||||
"answer": "编码是C10020103"
|
||||
},
|
||||
{
|
||||
"question": "混凝土(保护帽)的编码是多少?",
|
||||
"answer": "编码是ZH1001"
|
||||
},
|
||||
{
|
||||
"question": "船舶运输 金具、绝缘子、零星钢材 运输的编码是多少?",
|
||||
"answer": "编码是YX1-144"
|
||||
},
|
||||
{
|
||||
"question": "人力运输 混凝土杆 每件重500kg以内的编码是多少?",
|
||||
"answer": "编码是YX1-1"
|
||||
},
|
||||
{
|
||||
"question": "船舶运输 线材 每件重1000kg以内 运输的编码是多少?",
|
||||
"answer": "编码是YX1-136"
|
||||
},
|
||||
{
|
||||
"question": "混凝土搅拌及浇制 每基基础联系梁混凝土量20m³以内的编码是多少?",
|
||||
"answer": "编码是YX3-69"
|
||||
},
|
||||
{
|
||||
"question": "索道运输 循环式 塔材 荷载1t以内 装卸的编码是多少?",
|
||||
"answer": "编码是YX1-185"
|
||||
},
|
||||
{
|
||||
"question": "人力运输 混凝土预制品 每件重100kg以内的编码是多少?",
|
||||
"answer": "编码是YX1-6"
|
||||
},
|
||||
{
|
||||
"question": "船舶运输 混凝土杆 每件重1500kg以上 运输的编码是多少?",
|
||||
"answer": "编码是YX1-118"
|
||||
},
|
||||
{
|
||||
"question": "碎石的编码是多少?",
|
||||
"answer": "编码是C10020103"
|
||||
},
|
||||
{
|
||||
"question": "电杆坑、塔坑、拉线坑人工挖方(或爆破)及回填 泥水 坑深8.0m以上的编码是多少?",
|
||||
"answer": "编码是YX2-55"
|
||||
},
|
||||
{
|
||||
"question": "机械施工土方 场地平整的编码是多少?",
|
||||
"answer": "编码是GT1-1"
|
||||
},
|
||||
{
|
||||
"question": "汽车运输 混凝土预制品 每件重100kg以内 装卸的编码是多少?",
|
||||
"answer": "编码是YX1-69"
|
||||
},
|
||||
{
|
||||
"question": "汽车运输 其他建筑安装材料 运输的编码是多少?",
|
||||
"answer": "编码是YX1-108"
|
||||
},
|
||||
{
|
||||
"question": "钻孔灌注桩基础 混凝土搅拌及浇制 孔深10m以内的编码是多少?",
|
||||
"answer": "编码是YX3-171"
|
||||
},
|
||||
{
|
||||
"question": "线路复测及分坑 直线双杆及拉线塔的编码是多少?",
|
||||
"answer": "编码是YX2-3"
|
||||
},
|
||||
{
|
||||
"question": "氧化锌避雷器安装 35kV的编码是多少?",
|
||||
"answer": "编码是YX7-32"
|
||||
},
|
||||
{
|
||||
"question": "混凝土(保护帽)的编码是多少?",
|
||||
"answer": "编码是ZH1002"
|
||||
},
|
||||
{
|
||||
"question": "汽车运输 其他建筑安装材料 装卸的编码是多少?",
|
||||
"answer": "编码是YX1-107"
|
||||
},
|
||||
{
|
||||
"question": "船舶运输 混凝土杆 每件重500kg以内 装卸的编码是多少?",
|
||||
"answer": "编码是YX1-109"
|
||||
},
|
||||
{
|
||||
"question": "混凝土(保护帽)的编码是多少?",
|
||||
"answer": "编码是ZH1001"
|
||||
},
|
||||
{
|
||||
"question": "人力运输 混凝土杆 每件重500kg以内的编码是多少?",
|
||||
"answer": "编码是YX1-1"
|
||||
},
|
||||
{
|
||||
"question": "人力运输 混凝土杆 每件重500kg以内的编码是多少?",
|
||||
"answer": "编码是YX1-1"
|
||||
},
|
||||
{
|
||||
"question": "普通硅酸盐水泥的编码是多少?",
|
||||
"answer": "编码是C09010102"
|
||||
},
|
||||
{
|
||||
"question": "拖拉机运输 钢管塔材 运输的编码是多少?",
|
||||
"answer": "编码是YX1-44"
|
||||
},
|
||||
{
|
||||
"question": "尖峰及施工基面挖方(或爆破) 普通土的编码是多少?",
|
||||
"answer": "编码是YX2-226"
|
||||
},
|
||||
{
|
||||
"question": "汽车运输 角钢塔材 装卸的编码是多少?",
|
||||
"answer": "编码是YX1-103"
|
||||
},
|
||||
{
|
||||
"question": "接地槽挖方(或爆破)及回填 普通土的编码是多少?",
|
||||
"answer": "编码是YX2-213"
|
||||
},
|
||||
{
|
||||
"question": "水的编码是多少?",
|
||||
"answer": "编码是C21010101"
|
||||
},
|
||||
{
|
||||
"question": "直线(直线换位、直线转角)杆塔绝缘子串悬挂安装 35kV 针式单联串(悬垂串)的编码是多少?",
|
||||
"answer": "编码是YX6-21"
|
||||
},
|
||||
{
|
||||
"question": "直线(直线换位、直线转角)杆塔绝缘子串悬挂安装 35kV I型双联串(悬垂串)的编码是多少?",
|
||||
"answer": "编码是YX6-22"
|
||||
},
|
||||
{
|
||||
"question": "钻孔灌注桩基础 机械推钻成孔 砂砾石 孔深20m以内 孔径1.0m以内的编码是多少?",
|
||||
"answer": "编码是YX3-117"
|
||||
},
|
||||
{
|
||||
"question": "线路复测及分坑 直线自立塔的编码是多少?",
|
||||
"answer": "编码是YX2-6"
|
||||
},
|
||||
{
|
||||
"question": "钻孔灌注桩基础 凿桩头 桩径0.8m以上的编码是多少?",
|
||||
"answer": "编码是YX3-180"
|
||||
},
|
||||
{
|
||||
"question": "线路复测及分坑 耐张(转角)单杆的编码是多少?",
|
||||
"answer": "编码是YX2-2"
|
||||
},
|
||||
{
|
||||
"question": "中砂的编码是多少?",
|
||||
"answer": "编码是C10010101"
|
||||
},
|
||||
{
|
||||
"question": "人力运输 混凝土杆 每件重500kg以内的编码是多少?",
|
||||
"answer": "编码是YX1-1"
|
||||
},
|
||||
{
|
||||
"question": "带电跨越电力线 被跨线电压等级 35kV的编码是多少?",
|
||||
"answer": "编码是YX5-186"
|
||||
},
|
||||
{
|
||||
"question": "人工挖土方 普土 深2m以内的编码是多少?",
|
||||
"answer": "编码是YT1-1"
|
||||
},
|
||||
{
|
||||
"question": "混凝土杆的编码是多少?",
|
||||
"answer": "编码是"
|
||||
},
|
||||
{
|
||||
"question": "接地模块安装的编码是多少?",
|
||||
"answer": "编码是YX3-213"
|
||||
},
|
||||
{
|
||||
"question": "拖拉机运输 线材 每件重400kg以内 运输的编码是多少?",
|
||||
"answer": "编码是YX1-34"
|
||||
},
|
||||
{
|
||||
"question": "拖拉机运输 其他建筑安装材料 装卸的编码是多少?",
|
||||
"answer": "编码是YX1-45"
|
||||
},
|
||||
{
|
||||
"question": "普通硅酸盐水泥的编码是多少?",
|
||||
"answer": "编码是C09010102"
|
||||
},
|
||||
{
|
||||
"question": "船舶运输 线材 每件重4000kg以内 装卸的编码是多少?",
|
||||
"answer": "编码是YX1-139"
|
||||
},
|
||||
{
|
||||
"question": "水的编码是多少?",
|
||||
"answer": "编码是C21010101"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,202 @@
|
||||
[
|
||||
{
|
||||
"question": "架空输电线路本体工程的金额是多少?",
|
||||
"answer": "金额是55105688268.5176010132"
|
||||
},
|
||||
{
|
||||
"question": "价差预备费的金额是多少?",
|
||||
"answer": "金额是22731130869.6655998230"
|
||||
},
|
||||
{
|
||||
"question": "工程静态投资的金额是多少?",
|
||||
"answer": "金额是715035853336.3909912109"
|
||||
},
|
||||
{
|
||||
"question": "工程动态投资的金额是多少?",
|
||||
"answer": "金额是776282009093.5660400391"
|
||||
},
|
||||
{
|
||||
"question": "其中:工程建设检测费的金额是多少?",
|
||||
"answer": "金额是185575370.1463980079"
|
||||
},
|
||||
{
|
||||
"question": "工程静态投资的金额是多少?",
|
||||
"answer": "金额是715035853336.3909912109"
|
||||
},
|
||||
{
|
||||
"question": "建设期贷款利息的金额是多少?",
|
||||
"answer": "金额是38515024887.5095977783"
|
||||
},
|
||||
{
|
||||
"question": "特殊项目的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "动态费用的金额是多少?",
|
||||
"answer": "金额是61246155757.1752014160"
|
||||
},
|
||||
{
|
||||
"question": "动态费用的金额是多少?",
|
||||
"answer": "金额是61246155757.1752014160"
|
||||
},
|
||||
{
|
||||
"question": "小计的金额是多少?",
|
||||
"answer": "金额是458257942570.3129882812"
|
||||
},
|
||||
{
|
||||
"question": "其他费用的金额是多少?",
|
||||
"answer": "金额是210942912572.8689880371"
|
||||
},
|
||||
{
|
||||
"question": "基本预备费的金额是多少?",
|
||||
"answer": "金额是14020310849.7332000732"
|
||||
},
|
||||
{
|
||||
"question": "其中:水土保持监测及验收费的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "其中:工程建设检测费的金额是多少?",
|
||||
"answer": "金额是185575370.1463980079"
|
||||
},
|
||||
{
|
||||
"question": "其中:特种设备安全监测费的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "工程静态投资的金额是多少?",
|
||||
"answer": "金额是715035853336.3909912109"
|
||||
},
|
||||
{
|
||||
"question": "其中:水土保持监测及验收费的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "架空输电线路本体工程的金额是多少?",
|
||||
"answer": "金额是55105688268.5176010132"
|
||||
},
|
||||
{
|
||||
"question": "基本预备费的金额是多少?",
|
||||
"answer": "金额是14020310849.7332000732"
|
||||
},
|
||||
{
|
||||
"question": "其中:水土保持监测及验收费的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "小计的金额是多少?",
|
||||
"answer": "金额是458257942570.3129882812"
|
||||
},
|
||||
{
|
||||
"question": "编制基准期价差的金额是多少?",
|
||||
"answer": "金额是29246752707.1180000305"
|
||||
},
|
||||
{
|
||||
"question": "其中:水土保持监测及验收费的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "小计的金额是多少?",
|
||||
"answer": "金额是458257942570.3129882812"
|
||||
},
|
||||
{
|
||||
"question": "其他费用的金额是多少?",
|
||||
"answer": "金额是210942912572.8689880371"
|
||||
},
|
||||
{
|
||||
"question": "特殊项目的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "编制基准期价差的金额是多少?",
|
||||
"answer": "金额是29246752707.1180000305"
|
||||
},
|
||||
{
|
||||
"question": "特殊项目的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "小计的金额是多少?",
|
||||
"answer": "金额是458257942570.3129882812"
|
||||
},
|
||||
{
|
||||
"question": "工程动态投资的金额是多少?",
|
||||
"answer": "金额是776282009093.5660400391"
|
||||
},
|
||||
{
|
||||
"question": "其中:建设场地征用及清理费的金额是多少?",
|
||||
"answer": "金额是16831284.2287110016"
|
||||
},
|
||||
{
|
||||
"question": "其中:可抵扣增值税额的金额是多少?",
|
||||
"answer": "金额是20069645492.2888984680"
|
||||
},
|
||||
{
|
||||
"question": "小计的金额是多少?",
|
||||
"answer": "金额是458257942570.3129882812"
|
||||
},
|
||||
{
|
||||
"question": "动态费用的金额是多少?",
|
||||
"answer": "金额是61246155757.1752014160"
|
||||
},
|
||||
{
|
||||
"question": "建设期贷款利息的金额是多少?",
|
||||
"answer": "金额是38515024887.5095977783"
|
||||
},
|
||||
{
|
||||
"question": "工程静态投资的金额是多少?",
|
||||
"answer": "金额是715035853336.3909912109"
|
||||
},
|
||||
{
|
||||
"question": "其中:建设场地征用及清理费的金额是多少?",
|
||||
"answer": "金额是16831284.2287110016"
|
||||
},
|
||||
{
|
||||
"question": "建设期贷款利息的金额是多少?",
|
||||
"answer": "金额是38515024887.5095977783"
|
||||
},
|
||||
{
|
||||
"question": "工程动态投资的金额是多少?",
|
||||
"answer": "金额是776282009093.5660400391"
|
||||
},
|
||||
{
|
||||
"question": "架空输电线路本体工程的金额是多少?",
|
||||
"answer": "金额是55105688268.5176010132"
|
||||
},
|
||||
{
|
||||
"question": "其中:工程建设检测费的金额是多少?",
|
||||
"answer": "金额是185575370.1463980079"
|
||||
},
|
||||
{
|
||||
"question": "其中:水土保持监测及验收费的金额是多少?",
|
||||
"answer": "金额是0E-10"
|
||||
},
|
||||
{
|
||||
"question": "工程动态投资的金额是多少?",
|
||||
"answer": "金额是776282009093.5660400391"
|
||||
},
|
||||
{
|
||||
"question": "其中:可抵扣增值税额的金额是多少?",
|
||||
"answer": "金额是20069645492.2888984680"
|
||||
},
|
||||
{
|
||||
"question": "价差预备费的金额是多少?",
|
||||
"answer": "金额是22731130869.6655998230"
|
||||
},
|
||||
{
|
||||
"question": "一般线路本体工程的金额是多少?",
|
||||
"answer": "金额是55105688268.5176010132"
|
||||
},
|
||||
{
|
||||
"question": "其中:工程建设检测费的金额是多少?",
|
||||
"answer": "金额是185575370.1463980079"
|
||||
},
|
||||
{
|
||||
"question": "基本预备费的金额是多少?",
|
||||
"answer": "金额是14020310849.7332000732"
|
||||
},
|
||||
{
|
||||
"question": "设备购置费的金额是多少?",
|
||||
"answer": "金额是2567934636.3574500084"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,118 @@
|
||||
import json
|
||||
from dotenv import load_dotenv
|
||||
import asyncio
|
||||
import nest_asyncio
|
||||
nest_asyncio.apply()
|
||||
from llama_index.core.prompts import (
|
||||
ChatMessage,
|
||||
ChatPromptTemplate,
|
||||
MessageRole
|
||||
)
|
||||
|
||||
DEFAULT_SYSTEM_TEMPLATE = """
|
||||
您是一个问答聊天机器人的专业评估系统。
|
||||
|
||||
您将获得以下信息:
|
||||
|
||||
- 用户查询,
|
||||
- 生成的回答,
|
||||
|
||||
也可能提供一个参考答案作为评估的依据。
|
||||
|
||||
您的任务是判断生成回答的相关性和正确性。
|
||||
输出一个代表全面评估的单一分数。
|
||||
您必须在一行中仅返回该分数。
|
||||
不要以其他任何格式返回答案。
|
||||
在单独的一行提供给定分数的理由。
|
||||
|
||||
请遵循以下评分指南:
|
||||
|
||||
- 您的分数必须在1到5之间,其中1是最差,5是最好的。
|
||||
-如果生成的回答与用户查询不相关,您应该给出1分。
|
||||
-如果生成的回答相关但包含错误,您应该给出2到3分之间的分数。
|
||||
-如果生成的回答相关且完全正确,您应该给出4到5分之间的分数。
|
||||
示例响应:
|
||||
4.0
|
||||
生成的回答与参考答案的指标完全相同,但不够精炼。
|
||||
|
||||
"""
|
||||
|
||||
DEFAULT_USER_TEMPLATE = """
|
||||
## User Query
|
||||
{query}
|
||||
|
||||
## Reference Answer
|
||||
{reference_answer}
|
||||
|
||||
## Generated Answer
|
||||
{generated_answer}
|
||||
"""
|
||||
|
||||
DEFAULT_EVAL_TEMPLATE = ChatPromptTemplate(
|
||||
message_templates=[
|
||||
ChatMessage(role=MessageRole.SYSTEM, content=DEFAULT_SYSTEM_TEMPLATE),
|
||||
ChatMessage(role=MessageRole.USER, content=DEFAULT_USER_TEMPLATE),
|
||||
]
|
||||
)
|
||||
|
||||
from app.api.routers.models import ChatData, Message
|
||||
from llama_index.core.chat_engine.types import BaseChatEngine, NodeWithScore
|
||||
from llama_index.core.vector_stores.types import MetadataFilter, MetadataFilters
|
||||
from llama_index.core.evaluation import CorrectnessEvaluator
|
||||
from app.engine import get_chat_engine
|
||||
from app.api.routers.chat import generate_filters
|
||||
from app.engine.index import get_index
|
||||
from app.observability import init_observability
|
||||
from app.settings import init_settings
|
||||
|
||||
|
||||
load_dotenv()
|
||||
|
||||
|
||||
init_settings()
|
||||
init_observability()
|
||||
|
||||
index = get_index()
|
||||
|
||||
# 初始化聊天引擎和评估器
|
||||
chat_engine = get_chat_engine()
|
||||
corr_evaluator_qwen = CorrectnessEvaluator()
|
||||
|
||||
# 加载本地问题回答文件
|
||||
file_path = 'D:/LLM_model/text2sql/zjdataai-app-test/backend/unit_test/test.json'
|
||||
output_file_path = file_path.replace('.json', '_test.json')
|
||||
|
||||
with open(file_path, 'r', encoding='utf-8') as f:
|
||||
data = json.load(f)
|
||||
|
||||
# 异步函数用于评估查询
|
||||
async def evaluate_query(question, answer, index, output_file):
|
||||
response = await chat_engine.astream_chat(question)
|
||||
content_str = str(response.sources[0])
|
||||
|
||||
result = corr_evaluator_qwen.evaluate(
|
||||
query=question,
|
||||
response=content_str,
|
||||
reference=answer,
|
||||
)
|
||||
|
||||
result_dict = {
|
||||
"编号": index,
|
||||
"问题": question,
|
||||
"答案": answer,
|
||||
"回答": result.response,
|
||||
"得分(0~5)": result.score,
|
||||
"评价": result.feedback
|
||||
}
|
||||
|
||||
with open(output_file, 'a', encoding='utf-8') as f:
|
||||
f.write(json.dumps(result_dict, ensure_ascii=False, indent=4))
|
||||
f.write(',')
|
||||
|
||||
# 主异步函数
|
||||
async def main():
|
||||
for index, item in enumerate(data, start=1):
|
||||
await evaluate_query(item['question'], item['answer'], index, output_file_path)
|
||||
|
||||
# 运行主协程
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,10 @@
|
||||
[
|
||||
{
|
||||
"question": "人工费的费率是多少?",
|
||||
"answer": "费率是100.0000000000"
|
||||
},
|
||||
{
|
||||
"question": "临时设施费的费率是多少?",
|
||||
"answer": "费率是6.3500000000"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"编号": 1,
|
||||
"问题": "人工费的费率是多少?",
|
||||
"答案": "费率是100.0000000000",
|
||||
"实际回答": "人工费的费率是100.0。",
|
||||
"得分": 4.5,
|
||||
"评价": "生成的答案与参考答案一致,只是表达方式略有不同,但完全正确且相关。"
|
||||
}
|
||||
********************
|
||||
{
|
||||
"编号": 2,
|
||||
"问题": "临时设施费的费率是多少?",
|
||||
"答案": "费率是6.3500000000",
|
||||
"实际回答": "在新的上下文中,临时设施费的计算应当基于取费定额人工费和取费定额机械费,但当前费率被设置为0.0,这意味着需要重新确认或调整费率。在没有具体费率的情况下,不能直接给出确定的费率值。如果需要计算临时设施费,应根据实际的取费定额人工费和取费定额机械费进行计算。参考之前的6.35%的费率可能是一个起点,但请注意,这需要根据项目的具体情况和最新的费用标准进行调整。",
|
||||
"得分": 1.0,
|
||||
"评价": "生成的答案与用户查询不相关,用户询问的是临时设施费的费率,而生成的答案提供的是一个关于如何计算临时设施费的解释,且提到了一个不相关的0.0费率,这与用户的问题不符。同时,即使提到了6.35%的费率,也没有明确指出这就是用户想要的答案,反而强调了需要根据项目具体情况调整,这增加了用户的困惑。"
|
||||
}
|
||||
********************
|
||||
@@ -1,9 +1,10 @@
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv()
|
||||
|
||||
import phoenix as px
|
||||
|
||||
|
||||
os.environ['PHOENIX_HOST'] = "0.0.0.0"
|
||||
|
||||
session = px.launch_app(use_temp_dir=False)
|
||||
|
||||
import msvcrt
|
||||
|
||||
Reference in New Issue
Block a user