Unverified Commit e53e729d authored by YeAnbang's avatar YeAnbang Committed by GitHub
Browse files

[Feature] Add document retrieval QA (#5020)



* add langchain

* add langchain

* Add files via upload

* add langchain

* fix style

* fix style: remove extra space

* add pytest; modified retriever

* add pytest; modified retriever

* add tests to build_on_pr.yml

* fix build_on_pr.yml

* fix build on pr; fix environ vars

* seperate unit tests for colossalqa from build from pr

* fix container setting; fix environ vars

* commented dev code

* add incremental update

* remove stale code

* fix style

* change to sha3 224

* fix retriever; fix style; add unit test for document loader

* fix ci workflow config

* fix ci workflow config

* add set cuda visible device script in ci

* fix doc string

* fix style; update readme; refactored

* add force log info

* change build on pr, ignore colossalqa

* fix docstring, captitalize all initial letters

* fix indexing; fix text-splitter

* remove debug code, update reference

* reset previous commit

* update LICENSE update README add key-value mode, fix bugs

* add files back

* revert force push

* remove junk file

* add test files

* fix retriever bug, add intent classification

* change conversation chain design

* rewrite prompt and conversation chain

* add ui v1

* ui v1

* fix atavar

* add header

* Refactor the RAG Code and support Pangu

* Refactor the ColossalQA chain to Object-Oriented Programming and the UI demo.

* resolved conversation. tested scripts under examples. web demo still buggy

* fix ci tests

* Some modifications to add ChatGPT api

* modify llm.py and remove unnecessary files

* Delete applications/ColossalQA/examples/ui/test_frontend_input.json

* Remove OpenAI api key

* add colossalqa

* move files

* move files

* move files

* move files

* fix style

* Add Readme and fix some bugs.

* Add something to readme and modify some code

* modify a directory name for clarity

* remove redundant directory

* Correct a type in  llm.py

* fix AI prefix

* fix test_memory.py

* fix conversation

* fix some erros and typos

* Fix a missing import in RAG_ChatBot.py

* add colossalcloud LLM wrapper, correct issues in code review

---------
Co-authored-by: default avatarYeAnbang <anbangy2@outlook.com>
Co-authored-by: default avatarOrion-Zheng <zheng_zian@u.nus.edu>
Co-authored-by: default avatarZian(Andy) Zheng <62330719+Orion-Zheng@users.noreply.github.com>
Co-authored-by: default avatarOrion-Zheng <zhengzian@u.nus.edu>
parent 3acbf6d4
"""
Implement a memory class for storing conversation history
Support long term and short term memory
"""
from typing import Any, Dict, List
from colossalqa.chain.memory.summary import ConversationSummaryMemory
from colossalqa.chain.retrieval_qa.load_chain import load_qa_chain
from langchain.chains.combine_documents.base import BaseCombineDocumentsChain
from langchain.memory.chat_message_histories.in_memory import ChatMessageHistory
from langchain.schema import BaseChatMessageHistory
from langchain.schema.messages import BaseMessage
from langchain.schema.retriever import BaseRetriever
from pydantic import Field
class ConversationBufferWithSummary(ConversationSummaryMemory):
"""Memory class for storing information about entities."""
# Define dictionary to store information about entities.
# Store the most recent conversation history
buffered_history: BaseChatMessageHistory = Field(default_factory=ChatMessageHistory)
# Temp buffer
summarized_history_temp: BaseChatMessageHistory = Field(default_factory=ChatMessageHistory)
human_prefix: str = "Human"
ai_prefix: str = "Assistant"
buffer: str = "" # Formated conversation in str
existing_summary: str = "" # Summarization of stale converstion in str
# Define key to pass information about entities into prompt.
memory_key: str = "chat_history"
input_key: str = "question"
retriever: BaseRetriever = None
max_tokens: int = 2000
chain: BaseCombineDocumentsChain = None
input_chain_type_kwargs: List = {}
@property
def buffer(self) -> Any:
"""String buffer of memory."""
return self.buffer_as_messages if self.return_messages else self.buffer_as_str
@property
def buffer_as_str(self) -> str:
"""Exposes the buffer as a string in case return_messages is True."""
self.buffer = self.format_dialogue()
return self.buffer
@property
def buffer_as_messages(self) -> List[BaseMessage]:
"""Exposes the buffer as a list of messages in case return_messages is False."""
return self.buffered_history.messages
def clear(self):
"""Clear all the memory"""
self.buffered_history.clear()
self.summarized_history_temp.clear()
def initiate_document_retrieval_chain(
self, llm: Any, prompt_template: Any, retriever: Any, chain_type_kwargs: Dict[str, Any] = {}
) -> None:
"""
Since we need to calculate the length of the prompt, we need to initiate a retrieval chain
to calculate the length of the prompt.
Args:
llm: the language model for the retrieval chain (we won't actually return the output)
prompt_template: the prompt template for constructing the retrieval chain
retriever: the retriever for the retrieval chain
max_tokens: the max length of the prompt (not include the output)
chain_type_kwargs: the kwargs for the retrieval chain
memory_key: the key for the chat history
input_key: the key for the input query
"""
self.retriever = retriever
input_chain_type_kwargs = {k: v for k, v in chain_type_kwargs.items() if k not in [self.memory_key]}
self.input_chain_type_kwargs = input_chain_type_kwargs
self.chain = load_qa_chain(llm, chain_type="stuff", prompt=prompt_template, **self.input_chain_type_kwargs)
@property
def memory_variables(self) -> List[str]:
"""Define the variables we are providing to the prompt."""
return [self.memory_key]
def format_dialogue(self, lang: str = "en") -> str:
"""Format memory into two parts--- summarization of historical conversation and most recent conversation"""
if len(self.summarized_history_temp.messages) != 0:
for i in range(int(len(self.summarized_history_temp.messages) / 2)):
self.existing_summary = (
self.predict_new_summary(
self.summarized_history_temp.messages[i * 2 : i * 2 + 2], self.existing_summary, stop=["\n\n"]
)
.strip()
.split("\n")[0]
.strip()
)
for i in range(int(len(self.summarized_history_temp.messages) / 2)):
self.summarized_history_temp.messages.pop(0)
self.summarized_history_temp.messages.pop(0)
conversation_buffer = []
for t in self.buffered_history.messages:
if t.type == "human":
prefix = self.human_prefix
else:
prefix = self.ai_prefix
conversation_buffer.append(prefix + ": " + t.content)
conversation_buffer = "\n".join(conversation_buffer)
if len(self.existing_summary) > 0:
if lang == "en":
message = f"A summarization of historical conversation:\n{self.existing_summary}\nMost recent conversation:\n{conversation_buffer}"
elif lang == "zh":
message = f"历史对话概要:\n{self.existing_summary}\n最近的对话:\n{conversation_buffer}"
else:
raise ValueError("Unsupported language")
return message
else:
message = conversation_buffer
return message
def get_conversation_length(self):
"""Get the length of the formatted conversation"""
prompt = self.format_dialogue()
length = self.llm.get_num_tokens(prompt)
return length
def load_memory_variables(self, inputs: Dict[str, Any]) -> Dict[str, str]:
"""Load the memory variables.
Summarize oversize conversation to fit into the length constraint defined by max_tokene
Args:
inputs: the kwargs of the chain of your definition
Returns:
a dict that maps from memory key to the formated dialogue
the formated dialogue has the following format
if conversation is too long:
A summarization of historical conversation:
{summarization}
Most recent conversation:
Human: XXX
Assistant: XXX
...
otherwise
Human: XXX
Assistant: XXX
...
"""
# Calculate remain length
if "input_documents" in inputs:
# Run in a retrieval qa chain
docs = inputs["input_documents"]
else:
# For test
docs = self.retriever.get_relevant_documents(inputs[self.input_key])
inputs[self.memory_key] = ""
inputs = {k: v for k, v in inputs.items() if k in [self.chain.input_key, self.input_key, self.memory_key]}
prompt_length = self.chain.prompt_length(docs, **inputs)
remain = self.max_tokens - prompt_length
while self.get_conversation_length() > remain:
if len(self.buffered_history.messages) <= 2:
raise RuntimeError("Exeeed max_tokens, trunck size of retrieved documents is too large")
temp = self.buffered_history.messages.pop(0)
self.summarized_history_temp.messages.append(temp)
temp = self.buffered_history.messages.pop(0)
self.summarized_history_temp.messages.append(temp)
return {self.memory_key: self.format_dialogue()}
def save_context(self, inputs: Dict[str, Any], outputs: Dict[str, str]) -> None:
"""Save context from this conversation to buffer."""
input_str, output_str = self._get_input_output(inputs, outputs)
self.buffered_history.add_user_message(input_str.strip())
self.buffered_history.add_ai_message(output_str.strip())
"""
Class for logging with extra control for debugging
"""
import logging
class ColossalQALogger:
"""This is a distributed event logger class essentially based on :class:`logging`.
Args:
name (str): The name of the logger.
Note:
Logging types: ``info``, ``warning``, ``debug`` and ``error``
"""
__instances = dict()
def __init__(self, name):
if name in ColossalQALogger.__instances:
raise ValueError("Logger with the same name has been created")
else:
self._name = name
self._logger = logging.getLogger(name)
ColossalQALogger.__instances[name] = self
@staticmethod
def get_instance(name: str):
"""Get the unique single logger instance based on name.
Args:
name (str): The name of the logger.
Returns:
DistributedLogger: A DistributedLogger object
"""
if name in ColossalQALogger.__instances:
return ColossalQALogger.__instances[name]
else:
logger = ColossalQALogger(name=name)
return logger
def info(self, message: str, verbose: bool = False) -> None:
"""Log an info message.
Args:
message (str): The message to be logged.
verbose (bool): Whether to print the message to stdout.
"""
if verbose:
logging.basicConfig(level=logging.INFO)
self._logger.info(message)
def warning(self, message: str, verbose: bool = False) -> None:
"""Log a warning message.
Args:
message (str): The message to be logged.
verbose (bool): Whether to print the message to stdout.
"""
if verbose:
self._logger.warning(message)
def debug(self, message: str, verbose: bool = False) -> None:
"""Log a debug message.
Args:
message (str): The message to be logged.
verbose (bool): Whether to print the message to stdout.
"""
if verbose:
self._logger.debug(message)
def error(self, message: str) -> None:
"""Log an error message.
Args:
message (str): The message to be logged.
"""
self._logger.error(message)
def get_logger(name: str = None, level=logging.INFO) -> ColossalQALogger:
"""
Get the logger by name, if name is None, return the default logger
"""
if name:
logger = ColossalQALogger.get_instance(name=name)
else:
logger = ColossalQALogger.get_instance(name="colossalqa")
return logger
# Prompt Design Guide
For the retriever conversation system, users can customize three prompts.
## The Retrieval QA Prompt
This is the prompt for retrieval QA, the input is user's inputs, the retrieved documents, the historical conversation.
### Chinese
```
你是一个善于解答用户问题的AI助手。在保证安全的前提下,回答问题要尽可能有帮助。你的答案不应该包含任何有害的、不道德的、种族主义的、性别歧视的、危险的或非法的内容。请确保你的回答是公正和积极的。
如果不能根据给定的上下文推断出答案,请不要分享虚假、不确定的信息。
使用提供的背景信息和聊天记录对用户的输入作出回应或继续对话。您应该只生成一个回复。不需要跟进回答。请使用中文作答。
背景信息:
[retrieved documents]
聊天记录:
[historical conversation, overlength chat history will be summarized]
用户: [question]
Assistant:
```
### English
```
[INST] <<SYS>>Always answer as helpfully as possible, while being safe. Your answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure that your responses are socially unbiased and positive in nature.
If the answer cannot be infered based on the given context, please don't share false information.<</SYS>>
Use the context and chat history to respond to the human's input at the end or carry on the conversation. You should generate one response only. No following up is needed.
context:
[retrieved documents]
chat history
[historical conversation, overlength chat history will be summarized]
Human: {question}
Assistant:
```
## Summarization Prompt
This prompt is used by the memory module to recursively summarize overlength conversation to shrink the length of the prompt.
## Disambiguity Prompt
This prompt is used to perform zero-shot reference resolution to disambiguate entity references within user's questions.
## Final Prompt Examples
Assume k=3 for the retriever.
### English
Note that the "[INST] <<SYS>>...<</SYS>>" template is the specific prompt format used in LLaMA2.
#### Normal Length
```
[INST] <<SYS>>Always answer as helpfully as possible, while being safe. Your answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure that your responses are socially unbiased and positive in nature.
If the answer cannot be infered based on the given context, please don't share false information.<</SYS>>
Use the context and chat history to respond to the human's input at the end or carry on the conversation. You should generate one response only. No following up is needed.
context:
[document 1]
[document 2]
[document 3]
chat history
Human: XXX
Assistant: XXX
...
Human: {question}
Assistant:
```
#### Overlength
```
[INST] <<SYS>>Always answer as helpfully as possible, while being safe. Your answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure that your responses are socially unbiased and positive in nature.
If the answer cannot be infered based on the given context, please don't share false information.<</SYS>>
Use the context and chat history to respond to the human's input at the end or carry on the conversation. You should generate one response only. No following up is needed.
context:
[document 1]
[document 2]
[document 3]
chat history
A summarization of historical conversation:
[one line summary of historical conversation]
Most recent conversation:
Human: XXX
Assistant: XXX
...
Human: {question}
Assistant:
```
### Chinese
#### Normal Length
```
你是一个善于解答用户问题的AI助手。在保证安全的前提下,回答问题要尽可能有帮助。你的答案不应该包含任何有害的、不道德的、种族主义的、性别歧视的、危险的或非法的内容。请确保你的回答是公正和积极的。
如果不能根据给定的上下文推断出答案,请不要分享虚假、不确定的信息。
使用提供的背景信息和聊天记录对用户的输入作出回应或继续对话。您应该只生成一个回复。不需要跟进回答。请使用中文作答。
背景信息:
[document 1]
[document 2]
[document 3]
聊天记录:
用户: XXX
Assistant: XXX
...
用户: [question]
Assistant:
```
#### Overlength
```
你是一个善于解答用户问题的AI助手。在保证安全的前提下,回答问题要尽可能有帮助。你的答案不应该包含任何有害的、不道德的、种族主义的、性别歧视的、危险的或非法的内容。请确保你的回答是公正和积极的。
如果不能根据给定的上下文推断出答案,请不要分享虚假、不确定的信息。
使用提供的背景信息和聊天记录对用户的输入作出回应或继续对话。您应该只生成一个回复。不需要跟进回答。请使用中文作答。
背景信息:
[document 1]
[document 2]
[document 3]
聊天记录:
历史对话概要:
[one line summary of historical conversation]
最近的对话:
用户: XXX
Assistant: XXX
...
用户: [question]
Assistant:
```
"""
All custom prompt templates are defined here.
"""
from langchain.prompts.prompt import PromptTemplate
_CUSTOM_SUMMARIZER_TEMPLATE_ZH = """请递进式地总结所提供的当前对话,将当前对话的摘要内容添加到先前已有的摘要上,返回一个融合了当前对话的新的摘要。
例1:
已有的摘要:
人类问Assistant对人工智能的看法。人工智能认为人工智能是一种善的力量。
新的对话内容:
人类: 为什么你认为人工智能是一种好的力量?
Assistant: 因为人工智能将帮助人类充分发挥潜力。
新的摘要:
人类问Assistant对人工智能的看法。人工智能认为人工智能是一种积极的力量,因为它将帮助人类充分发挥潜力。
示例结束
已有的摘要:
{summary}
新的对话内容:
{new_lines}
新的摘要:"""
# Chinese retrieval qa prompt
_ZH_RETRIEVAL_QA_PROMPT = """<指令>根据下列支持文档和对话历史,简洁和专业地来回答问题。如果无法从支持文档中得到答案,请说 “根据已知信息无法回答该问题”。回答中请不要涉及支持文档中没有提及的信息,答案请使用中文。 </指令>
{context}
<对话历史>
{chat_history}
</对话历史>
<问题>{question}</问题>
答案:"""
ZH_RETRIEVAL_QA_TRIGGER_KEYWORDS = ["无法回答该问题"]
ZH_RETRIEVAL_QA_REJECTION_ANSWER = "抱歉,根据提供的信息无法回答该问题。"
_ZH_RETRIEVAL_CLASSIFICATION_USE_CASE = """使用提供的参考案例判断客户遇到的故障所属的故障原因分类。
背景信息:
{context}
客服记录:
{question}
故障原因分类:"""
_ZH_DISAMBIGUATION_PROMPT = """你是一个乐于助人、恭敬而诚实的助手。你总是按照指示去做。
请用聊天记录中提到的具体名称或实体名称替换给定句子中的任何模糊或有歧义的指代,如果没有提供聊天记录或句子中不包含模糊或有歧义的指代,则只输出原始句子。您的输出应该是消除歧义的句子本身(与“消除歧义的句子:”在同一行中),并且不包含任何其他内容。
下面是一个例子:
聊天记录:
用户: 我有一个朋友,张三。你认识他吗?
Assistant: 我认识一个叫张三的人
句子: 他最喜欢的食物是什么?
消除歧义的句子: 张三最喜欢的食物是什么?
聊天记录:
{chat_history}
句子: {input}
消除歧义的句子:"""
# English retrieval qa prompt
_EN_RETRIEVAL_QA_PROMPT = """[INST] <<SYS>>Always answer as helpfully as possible, while being safe. Your answers should not include any harmful, unethical, racist, sexist content.
If the answer cannot be infered based on the given context, please say "I cannot answer the question based on the information given.".<</SYS>>
Use the context and chat history to answer the question.
context:
{context}
chat history
{chat_history}
question: {question}
answer:"""
EN_RETRIEVAL_QA_TRIGGER_KEYWORDS = ["cannot answer the question"]
EN_RETRIEVAL_QA_REJECTION_ANSWER = "Sorry, this question cannot be answered based on the information provided."
_EN_DISAMBIGUATION_PROMPT = """[INST] <<SYS>>You are a helpful, respectful and honest assistant. You always follow the instruction.<</SYS>>
Please replace any ambiguous references in the given sentence with the specific names or entities mentioned in the chat history or just output the original sentence if no chat history is provided or if the sentence doesn't contain ambiguous references. Your output should be the disambiguated sentence itself (in the same line as "disambiguated sentence:") and contain nothing else.
Here is an example:
Chat history:
Human: I have a friend, Mike. Do you know him?
Assistant: Yes, I know a person named Mike
sentence: What's his favorate food?
disambiguated sentence: What's Mike's favorate food?
[/INST]
Chat history:
{chat_history}
sentence: {input}
disambiguated sentence:"""
PROMPT_RETRIEVAL_QA_EN = PromptTemplate(
template=_EN_RETRIEVAL_QA_PROMPT, input_variables=["question", "chat_history", "context"]
)
PROMPT_DISAMBIGUATE_EN = PromptTemplate(template=_EN_DISAMBIGUATION_PROMPT, input_variables=["chat_history", "input"])
SUMMARY_PROMPT_ZH = PromptTemplate(input_variables=["summary", "new_lines"], template=_CUSTOM_SUMMARIZER_TEMPLATE_ZH)
PROMPT_DISAMBIGUATE_ZH = PromptTemplate(template=_ZH_DISAMBIGUATION_PROMPT, input_variables=["chat_history", "input"])
PROMPT_RETRIEVAL_QA_ZH = PromptTemplate(
template=_ZH_RETRIEVAL_QA_PROMPT, input_variables=["question", "chat_history", "context"]
)
PROMPT_RETRIEVAL_CLASSIFICATION_USE_CASE_ZH = PromptTemplate(
template=_ZH_RETRIEVAL_CLASSIFICATION_USE_CASE, input_variables=["question", "context"]
)
"""
Script for Chinese retrieval based conversation system backed by ChatGLM
"""
from typing import Tuple
from colossalqa.chain.retrieval_qa.base import RetrievalQA
from colossalqa.local.llm import ColossalAPI, ColossalLLM
from colossalqa.memory import ConversationBufferWithSummary
from colossalqa.mylogging import get_logger
from colossalqa.prompt.prompt import PROMPT_DISAMBIGUATE_EN, PROMPT_RETRIEVAL_QA_EN
from colossalqa.retriever import CustomRetriever
from langchain import LLMChain
logger = get_logger()
class EnglishRetrievalConversation:
"""
Wrapper class for Chinese retrieval conversation system
"""
def __init__(self, retriever: CustomRetriever, model_path: str, model_name: str) -> None:
"""
Setup retrieval qa chain for Chinese retrieval based QA
"""
logger.info(f"model_name: {model_name}; model_path: {model_path}", verbose=True)
colossal_api = ColossalAPI.get_api(model_name, model_path)
self.llm = ColossalLLM(n=1, api=colossal_api)
# Define the retriever
self.retriever = retriever
# Define the chain to preprocess the input
# Disambiguate the input. e.g. "What is the capital of that country?" -> "What is the capital of France?"
# Prompt is summarization prompt
self.llm_chain_disambiguate = LLMChain(
llm=self.llm,
prompt=PROMPT_DISAMBIGUATE_EN,
llm_kwargs={"max_new_tokens": 30, "temperature": 0.6, "do_sample": True},
)
self.retriever.set_rephrase_handler(self.disambiguity)
# Define memory with summarization ability
self.memory = ConversationBufferWithSummary(
llm=self.llm, llm_kwargs={"max_new_tokens": 50, "temperature": 0.6, "do_sample": True}
)
self.memory.initiate_document_retrieval_chain(
self.llm,
PROMPT_RETRIEVAL_QA_EN,
self.retriever,
chain_type_kwargs={
"chat_history": "",
},
)
self.retrieval_chain = RetrievalQA.from_chain_type(
llm=self.llm,
verbose=False,
chain_type="stuff",
retriever=self.retriever,
chain_type_kwargs={"prompt": PROMPT_RETRIEVAL_QA_EN, "memory": self.memory},
llm_kwargs={"max_new_tokens": 50, "temperature": 0.75, "do_sample": True},
)
def disambiguity(self, input: str):
out = self.llm_chain_disambiguate.run(input=input, chat_history=self.memory.buffer, stop=["\n"])
return out.split("\n")[0]
@classmethod
def from_retriever(
cls, retriever: CustomRetriever, model_path: str, model_name: str
) -> "EnglishRetrievalConversation":
return cls(retriever, model_path, model_name)
def run(self, user_input: str, memory: ConversationBufferWithSummary) -> Tuple[str, ConversationBufferWithSummary]:
if memory:
# TODO add translation chain here
self.memory.buffered_history.messages = memory.buffered_history.messages
self.memory.summarized_history_temp.messages = memory.summarized_history_temp.messages
return (
self.retrieval_chain.run(
query=user_input,
stop=[self.memory.human_prefix + ": "],
rejection_trigger_keywrods=["cannot answer the question"],
rejection_answer="Sorry, this question cannot be answered based on the information provided.",
).split("\n")[0],
self.memory,
)
"""
Multilingual retrieval based conversation system
"""
from typing import List
from colossalqa.data_loader.document_loader import DocumentLoader
from colossalqa.mylogging import get_logger
from colossalqa.retrieval_conversation_en import EnglishRetrievalConversation
from colossalqa.retrieval_conversation_zh import ChineseRetrievalConversation
from colossalqa.retriever import CustomRetriever
from colossalqa.text_splitter import ChineseTextSplitter
from colossalqa.utils import detect_lang_naive
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter, TextSplitter
logger = get_logger()
class UniversalRetrievalConversation:
"""
Wrapper class for bilingual retrieval conversation system
"""
def __init__(
self,
embedding_model_path: str = "moka-ai/m3e-base",
embedding_model_device: str = "cpu",
zh_model_path: str = None,
zh_model_name: str = None,
en_model_path: str = None,
en_model_name: str = None,
sql_file_path: str = None,
files_zh: List[List[str]] = None,
files_en: List[List[str]] = None,
text_splitter_chunk_size=100,
text_splitter_chunk_overlap=10,
) -> None:
"""
Warpper for multilingual retrieval qa class (Chinese + English)
Args:
embedding_model_path: local or huggingface embedding model
embedding_model_device:
files_zh: [[file_path, name_of_file, separator],...] defines the files used as supporting documents for Chinese retrieval QA
files_en: [[file_path, name_of_file, separator],...] defines the files used as supporting documents for English retrieval QA
"""
self.embedding = HuggingFaceEmbeddings(
model_name=embedding_model_path,
model_kwargs={"device": embedding_model_device},
encode_kwargs={"normalize_embeddings": False},
)
print("Select files for constructing Chinese retriever")
docs_zh = self.load_supporting_docs(
files=files_zh,
text_splitter=ChineseTextSplitter(
chunk_size=text_splitter_chunk_size, chunk_overlap=text_splitter_chunk_overlap
),
)
# Create retriever
self.information_retriever_zh = CustomRetriever(
k=3, sql_file_path=sql_file_path.replace(".db", "_zh.db"), verbose=True
)
self.information_retriever_zh.add_documents(
docs=docs_zh, cleanup="incremental", mode="by_source", embedding=self.embedding
)
print("Select files for constructing English retriever")
docs_en = self.load_supporting_docs(
files=files_en,
text_splitter=RecursiveCharacterTextSplitter(
chunk_size=text_splitter_chunk_size, chunk_overlap=text_splitter_chunk_overlap
),
)
# Create retriever
self.information_retriever_en = CustomRetriever(
k=3, sql_file_path=sql_file_path.replace(".db", "_en.db"), verbose=True
)
self.information_retriever_en.add_documents(
docs=docs_en, cleanup="incremental", mode="by_source", embedding=self.embedding
)
self.chinese_retrieval_conversation = ChineseRetrievalConversation.from_retriever(
self.information_retriever_zh, model_path=zh_model_path, model_name=zh_model_name
)
self.english_retrieval_conversation = EnglishRetrievalConversation.from_retriever(
self.information_retriever_en, model_path=en_model_path, model_name=en_model_name
)
self.memory = None
def load_supporting_docs(self, files: List[List[str]] = None, text_splitter: TextSplitter = None):
"""
Load supporting documents, currently, all documents will be stored in one vector store
"""
documents = []
if files:
for file in files:
retriever_data = DocumentLoader([[file["data_path"], file["name"]]]).all_data
splits = text_splitter.split_documents(retriever_data)
documents.extend(splits)
else:
while True:
file = input("Select a file to load or press Enter to exit:")
if file == "":
break
data_name = input("Enter a short description of the data:")
separator = input(
"Enter a separator to force separating text into chunks, if no separator is given, the defaut separator is '\\n\\n', press ENTER directly to skip:"
)
separator = separator if separator != "" else "\n\n"
retriever_data = DocumentLoader([[file, data_name.replace(" ", "_")]]).all_data
# Split
splits = text_splitter.split_documents(retriever_data)
documents.extend(splits)
return documents
def start_test_session(self):
"""
Simple multilingual session for testing purpose, with naive language selection mechanism
"""
while True:
user_input = input("User: ")
lang = detect_lang_naive(user_input)
if "END" == user_input:
print("Agent: Happy to chat with you :)")
break
agent_response = self.run(user_input, which_language=lang)
print(f"Agent: {agent_response}")
def run(self, user_input: str, which_language=str):
"""
Generate the response given the user input and a str indicates the language requirement of the output string
"""
assert which_language in ["zh", "en"]
if which_language == "zh":
agent_response, self.memory = self.chinese_retrieval_conversation.run(user_input, self.memory)
else:
agent_response, self.memory = self.english_retrieval_conversation.run(user_input, self.memory)
return agent_response.split("\n")[0]
"""
Script for Chinese retrieval based conversation system backed by ChatGLM
"""
from typing import Tuple
from colossalqa.chain.retrieval_qa.base import RetrievalQA
from colossalqa.local.llm import ColossalAPI, ColossalLLM
from colossalqa.memory import ConversationBufferWithSummary
from colossalqa.mylogging import get_logger
from colossalqa.prompt.prompt import PROMPT_DISAMBIGUATE_ZH, PROMPT_RETRIEVAL_QA_ZH, SUMMARY_PROMPT_ZH
from colossalqa.retriever import CustomRetriever
from langchain import LLMChain
logger = get_logger()
class ChineseRetrievalConversation:
"""
Wrapper class for Chinese retrieval conversation system
"""
def __init__(self, retriever: CustomRetriever, model_path: str, model_name: str) -> None:
"""
Setup retrieval qa chain for Chinese retrieval based QA
"""
# Local coati api
logger.info(f"model_name: {model_name}; model_path: {model_path}", verbose=True)
colossal_api = ColossalAPI.get_api(model_name, model_path)
self.llm = ColossalLLM(n=1, api=colossal_api)
# Define the retriever
self.retriever = retriever
# Define the chain to preprocess the input
# Disambiguate the input. e.g. "What is the capital of that country?" -> "What is the capital of France?"
# Prompt is summarization prompt
self.llm_chain_disambiguate = LLMChain(
llm=self.llm,
prompt=PROMPT_DISAMBIGUATE_ZH,
llm_kwargs={"max_new_tokens": 30, "temperature": 0.6, "do_sample": True},
)
self.retriever.set_rephrase_handler(self.disambiguity)
# Define memory with summarization ability
self.memory = ConversationBufferWithSummary(
llm=self.llm,
prompt=SUMMARY_PROMPT_ZH,
human_prefix="用户",
ai_prefix="Assistant",
max_tokens=2000,
llm_kwargs={"max_new_tokens": 50, "temperature": 0.6, "do_sample": True},
)
self.memory.initiate_document_retrieval_chain(
self.llm,
PROMPT_RETRIEVAL_QA_ZH,
self.retriever,
chain_type_kwargs={
"chat_history": "",
},
)
self.retrieval_chain = RetrievalQA.from_chain_type(
llm=self.llm,
verbose=False,
chain_type="stuff",
retriever=self.retriever,
chain_type_kwargs={"prompt": PROMPT_RETRIEVAL_QA_ZH, "memory": self.memory},
llm_kwargs={"max_new_tokens": 150, "temperature": 0.9, "do_sample": True},
)
def disambiguity(self, input: str):
out = self.llm_chain_disambiguate.run(input=input, chat_history=self.memory.buffer, stop=["\n"])
return out.split("\n")[0]
@classmethod
def from_retriever(
cls, retriever: CustomRetriever, model_path: str, model_name: str
) -> "ChineseRetrievalConversation":
return cls(retriever, model_path, model_name)
def run(self, user_input: str, memory: ConversationBufferWithSummary) -> Tuple[str, ConversationBufferWithSummary]:
if memory:
# TODO add translation chain here
self.memory.buffered_history.messages = memory.buffered_history.messages
self.memory.summarized_history_temp.messages = memory.summarized_history_temp.messages
return (
self.retrieval_chain.run(
query=user_input,
stop=["</答案>"],
doc_prefix="支持文档",
rejection_trigger_keywrods=["无法回答该问题"],
rejection_answer="抱歉,根据提供的信息无法回答该问题。",
).split("\n")[0],
self.memory,
)
"""
Code for custom retriver with incremental update
"""
import copy
import hashlib
import os
from collections import defaultdict
from typing import Any, Callable, Dict, List
from colossalqa.mylogging import get_logger
from langchain.callbacks.manager import CallbackManagerForRetrieverRun
from langchain.embeddings.base import Embeddings
from langchain.indexes import SQLRecordManager, index
from langchain.schema.retriever import BaseRetriever, Document
from langchain.vectorstores.base import VectorStore
from langchain.vectorstores.chroma import Chroma
logger = get_logger()
class CustomRetriever(BaseRetriever):
"""
Custom retriever class with support for incremental update of indexes
"""
vector_stores: Dict[str, VectorStore] = {}
sql_index_database: Dict[str, str] = {}
record_managers: Dict[str, SQLRecordManager] = {}
sql_db_chains = []
k = 3
rephrase_handler: Callable = None
buffer: Dict = []
buffer_size: int = 5
verbose: bool = False
sql_file_path: str = None
@classmethod
def from_documents(
cls,
documents: List[Document],
embeddings: Embeddings,
**kwargs: Any,
) -> BaseRetriever:
k = kwargs.pop("k", 3)
cleanup = kwargs.pop("cleanup", "incremental")
mode = kwargs.pop("mode", "by_source")
ret = cls(k=k)
ret.add_documents(documents, embedding=embeddings, cleanup=cleanup, mode=mode)
return ret
def add_documents(
self,
docs: Dict[str, Document] = [],
cleanup: str = "incremental",
mode: str = "by_source",
embedding: Embeddings = None,
) -> None:
"""
Add documents to retriever
Args:
docs: the documents to add
cleanup: choose from "incremental" (update embeddings, skip existing embeddings) and "full" (destory and rebuild retriever)
mode: choose from "by source" (documents are grouped by source) and "merge" (documents are merged into one vector store)
"""
if cleanup == "full":
# Cleanup
for source in self.vector_stores:
os.remove(self.sql_index_database[source])
# Add documents
data_by_source = defaultdict(list)
if mode == "by_source":
for doc in docs:
data_by_source[doc.metadata["source"]].append(doc)
elif mode == "merge":
data_by_source["merged"] = docs
for source in data_by_source:
if source not in self.vector_stores:
hash_encoding = hashlib.sha3_224(source.encode()).hexdigest()
if os.path.exists(f"{self.sql_file_path}/{hash_encoding}.db"):
# Remove the stale file
os.remove(f"{self.sql_file_path}/{hash_encoding}.db")
# Create a new sql database to store indexes, sql files are stored in the same directory as the source file
sql_path = f"sqlite:///{self.sql_file_path}/{hash_encoding}.db"
self.vector_stores[source] = Chroma(embedding_function=embedding, collection_name=hash_encoding)
self.sql_index_database[source] = f"{self.sql_file_path}/{hash_encoding}.db"
self.record_managers[source] = SQLRecordManager(source, db_url=sql_path)
self.record_managers[source].create_schema()
index(
data_by_source[source],
self.record_managers[source],
self.vector_stores[source],
cleanup=cleanup,
source_id_key="source",
)
def __del__(self):
for source in self.sql_index_database:
if os.path.exists(self.sql_index_database[source]):
os.remove(self.sql_index_database[source])
def set_sql_database_chain(self, db_chains) -> None:
"""
set sql agent chain to retrieve information from sql database
Not used in this version
"""
self.sql_db_chains = db_chains
def set_rephrase_handler(self, handler: Callable = None) -> None:
"""
Set a handler to preprocess the input str before feed into the retriever
"""
self.rephrase_handler = handler
def _get_relevant_documents(
self,
query: str,
*,
run_manager: CallbackManagerForRetrieverRun = None,
score_threshold: float = None,
return_scores: bool = False,
) -> List[Document]:
"""
This function is called by the retriever to get the relevant documents.
recent vistied queries are stored in buffer, if the query is in buffer, return the documents directly
Args:
query: the query to be searched
run_manager: the callback manager for retriever run
Returns:
documents: the relevant documents
"""
for buffered_doc in self.buffer:
if buffered_doc[0] == query:
return buffered_doc[1]
query_ = str(query)
# Use your existing retriever to get the documents
if self.rephrase_handler:
query = self.rephrase_handler(query)
documents = []
for k in self.vector_stores:
# Retrieve documents from each retriever
vectorstore = self.vector_stores[k]
documents.extend(vectorstore.similarity_search_with_score(query, self.k, score_threshold=score_threshold))
# print(documents)
# Return the top k documents among all retrievers
documents = sorted(documents, key=lambda x: x[1], reverse=False)[: self.k]
if return_scores:
# Return score
documents = copy.deepcopy(documents)
for doc in documents:
doc[0].metadata["score"] = doc[1]
documents = [doc[0] for doc in documents]
# Retrieve documents from sql database (not applicable for the local chains)
for sql_chain in self.sql_db_chains:
documents.append(
Document(
page_content=f"Query: {query} Answer: {sql_chain.run(query)}", metadata={"source": "sql_query"}
)
)
if len(self.buffer) < self.buffer_size:
self.buffer.append([query_, documents])
else:
self.buffer.pop(0)
self.buffer.append([query_, documents])
logger.info(f"retrieved documents:\n{str(documents)}", verbose=self.verbose)
return documents
from .chinese_text_splitter import ChineseTextSplitter
"""
Code for Chinese text splitter
"""
from typing import Any, List, Optional
from colossalqa.text_splitter.utils import get_cleaned_paragraph
from langchain.text_splitter import RecursiveCharacterTextSplitter
class ChineseTextSplitter(RecursiveCharacterTextSplitter):
def __init__(self, separators: Optional[List[str]] = None, is_separator_regrx: bool = False, **kwargs: Any):
self._separators = separators or ["\n\n", "\n", ",", "。", "!", "?", "?"]
if "chunk_size" not in kwargs:
kwargs["chunk_size"] = 50
if "chunk_overlap" not in kwargs:
kwargs["chunk_overlap"] = 10
super().__init__(separators=separators, keep_separator=True, **kwargs)
self._is_separator_regex = is_separator_regrx
def split_text(self, text: str) -> List[str]:
"""Return the list of separated text chunks"""
cleaned_paragraph = get_cleaned_paragraph(text)
splitted = []
for paragraph in cleaned_paragraph:
segs = super().split_text(paragraph)
for i in range(len(segs) - 1):
if segs[i][-1] not in self._separators:
pos = text.find(segs[i])
pos_end = pos + len(segs[i])
if i > 0:
last_sentence_start = max([text.rfind(m, 0, pos) for m in ["。", "!", "?"]])
pos = last_sentence_start + 1
segs[i] = str(text[pos:pos_end])
if i != len(segs) - 1:
next_sentence_end = max([text.find(m, pos_end) for m in ["。", "!", "?"]])
segs[i] = str(text[pos : next_sentence_end + 1])
splitted.append(segs[i])
if len(splitted) <= 1:
return splitted
splitted_text = []
i = 1
if splitted[0] not in splitted[1]:
splitted_text.append([splitted[0], 0])
if splitted[-1] not in splitted[-2]:
splitted_text.append([splitted[-1], len(splitted) - 1])
while i < len(splitted) - 1:
if splitted[i] not in splitted[i + 1] and splitted[i] not in splitted[i - 1]:
splitted_text.append([splitted[i], i])
i += 1
splitted_text = sorted(splitted_text, key=lambda x: x[1])
splitted_text = [splitted_text[i][0] for i in range(len(splitted_text))]
ret = []
for s in splitted_text:
if s not in ret:
ret.append(s)
return ret
import re
def remove_format(text: str) -> str:
# if the accout of \t, \r, \v, \f is less than 3, replace \t, \r, \v, \f with space
if len(re.findall(r"\s", text.replace(" ", ""))) > 3:
# in case this is a line of a table
return text
return re.sub(r"\s", " ", text)
# remove newlines
def get_cleaned_paragraph(s: str) -> str:
text = str(s)
text = re.sub(r"\n{3,}", r"\n", text) # replace \n\n\n... with \n
text = re.sub("\n\n", "", text)
lines = text.split("\n")
lines_remove_format = [remove_format(line) for line in lines]
return lines_remove_format
import re
from typing import Union
from colossalqa.mylogging import get_logger
from sqlalchemy import Engine, MetaData, create_engine
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.ext.declarative import declarative_base
logger = get_logger()
def drop_table(engine: Engine) -> None:
"""
Drop all existing table
"""
Base = declarative_base()
metadata = MetaData()
metadata.reflect(bind=engine)
for key in metadata.tables:
table = metadata.tables[key]
if table is not None:
Base.metadata.drop_all(engine, [table], checkfirst=True)
def create_empty_sql_database(database_uri):
try:
# Create an SQLAlchemy engine to connect to the database
engine = create_engine(database_uri)
# Create the database
engine.connect()
logger.info(f"Database created at {database_uri}")
except SQLAlchemyError as e:
logger.error(f"Error creating database: {str(e)}")
return engine, database_uri
def destroy_sql_database(sql_engine: Union[Engine, str]) -> None:
"""
Destroy an sql database
"""
if isinstance(sql_engine, str):
sql_engine = create_engine(sql_engine)
drop_table(sql_engine)
sql_engine.dispose()
sql_engine = None
def detect_lang_naive(s):
"""
Naive function for language detection, should be replaced by an independant layer
"""
remove_nota = "[’·°–!\"#$%&'()*+,-./:;<=>?@,。?★、…【】()《》?“”‘’![\\]^_`{|}~]+"
s = re.sub(remove_nota, "", s)
s = re.sub("[0-9]", "", s).strip()
res = re.sub("[a-zA-Z]", "", s).strip()
if len(res) <= 0:
return "en"
else:
return "zh"
Overview The Straits Times is the English flagship daily of SPH Media, one of the leading media companies in Asia. Launched on July 15, 1845, its comprehensive coverage of news from home and around the world makes The Straits Times the most-read newspaper in Singapore. Quality news, in-depth analyses, impactful commentaries and breaking stories are packaged to give readers riveting accounts of events in Singapore, the region, and beyond. The most read newspaper in Singapore, both in terms of print and digital, it reaches 1.33 million people every day. The Straits Times'​ key strength is in its world class coverage of news outside Singapore. With 20 bureaus in major cities around the world, The Straits Times correspondents bring world news to readers on a Singapore platter, helping readers to appreciate world events from a Singaporean perspective. Website http://www.straitstimes.com Phone 63196319Phone number is 63196319 Industry Newspaper Publishing Company size 1,001-5,000 employees 183 on LinkedIn Includes members with current employer listed as The Straits Times, including part-time roles. Headquarters Singapore, Singapore Founded 1845 Specialties News and Digital media
About With over 500 properties worldwide, Marriott Hotels has reimagined hospitality to exceed the expectations of business, group, and leisure travelers.
Marriott Hotels, Marriott’s flagship brand of quality-tier, full-service hotels and resorts, provides consistent, dependable and genuinely caring experiences to guests on their terms. Marriott is a brilliant host to guests who effortlessly blend life and work, and who are inspired by how modern travel enhances them both. Our hotels offer warm, professional service; sophisticated yet functional guest room design; lobby spaces that facilitate working, dining and socializing; restaurants and bars serving international cuisine prepared simply and from the freshest ingredients; meeting and event spaces and services that are gold standard; and expansive, 24-hour fitness facilities.
Overview AERCO International, Inc. is a recognized leader in delivering cost-effective, condensing commercial boilers, high-efficiency water heaters across a variety of markets including education, lodging, government, office buildings, healthcare, industrial and multifamily housing. AERCO's system design approach provides customer-specific solutions that deliver superior building performance at a lower operating cost while assuring uptime reliability. When AERCO was founded in 1949, it introduced a revolutionary design for an indirect-fired water heater that heated water on demand, and without storage, at a controlled temperature. This innovation became today's standard for water heaters, maximizing the recovery of latent heat energy and significantly increasing operating efficiency. AERCO continued to innovate and in 1988, introduced the first condensing and fully modulating boiler and water heater to the commercial market. The modulating capability of these products, still unsurpassed more than 25 years later, matches the equipment's output to real-time heating demand, ensuring the units draw no more fuel to operate than is absolutely necessary. This not only saves precious energy, but also ensures money doesn't needlessly disappear "up the stack."​ AERCO differentiates itself through a solution-based model, leveraging decades of engineering experience and industry application expertise to understand each customer’s unique needs. By partnering directly with customers and end-users to understand their project-specific requirements, AERCO provides tailored application solutions that are comprised of original product technologies including high efficiency condensing products, compact footprints, high turndown ratios, unique fuel delivery, leading control systems and proprietary design elements that combine to deliver up to 99% efficiency. Website http://www.aerco.com Phone 845-580-8000Phone number is 845-580-8000 Industry Industrial Machinery Manufacturing Company size 51-200 employees 119 on LinkedIn Includes members with current employer listed as AERCO International, Inc., including part-time roles. Headquarters Blauvelt, NY Founded 1949 Specialties Leading manufacturer of condensing boilers, water heating and energy recovery products and The originator of semi-instantaneous water heating
Prince PLC: Overview We are a global leader of quality water solutions for residential, industrial, municipal, and commercial settings. Our family of brands offers one of the most varied product lines in the world, with world-class, water-related solutions focused on: • Plumbing & Flow Control • Water Quality & Conditioning • Water Reuse & Drainage • HVAC • Municipal Waterworks Strategic Goals Watts Water is traded on the New York Stock Exchange under the symbol “WTS.” As a public company, growing shareholder value is critical. To that end, we focus on a five-part Global Strategy: Growth, Commercial Excellence, Operational Excellence, “One Watts Water,” and a Talent & Performance Culture. Follow us on all social media platforms @WattsWater Website http://www.watts.com/ Industry Wholesale Building Materials Company size 5,001-10,000 employees 2,248 on LinkedIn Includes members with current employer listed as Watts Water Technologies, including part-time roles. Headquarters North Andover, MA Specialties Plumbing, HVAC, Water Quality, Gas, Conditioning, Waterworks, and Drainage
About Courtyard Hotels is Marriott International’s largest hotel brand, with more than 1,100 hotels in over 50 countries worldwide. So, no matter where passion takes you, you’ll find us there to help you follow it. Proud members of Marriott Bonvoy.
\ No newline at end of file
《海峡时报》是SPH传媒旗下的英文旗舰日报,SPH传媒是亚洲领先的传媒公司之一。《海峡时报》创刊于1845年7月15日,全面报道国内外新闻,是新加坡发行量最大的报纸。高质量的新闻、深入的分析、有影响力的评论和突发事件,为读者提供新加坡、该地区乃至其他地区的引人入胜的事件报道。无论是纸媒还是电子版,它都是新加坡阅读量最大的报纸,每天有133万人阅读。《海峡时报》的主要优势在于它对新加坡以外新闻的世界级报道。《海峡时报》记者在全球主要城市设有20个分社,用新加坡的盘子把世界新闻带给读者,帮助读者从新加坡的角度了解世界大事。网站http://www.straitstimes.com电话63196319电话63196319工业报纸出版公司规模1,001-5,000员工LinkedIn 183包括目前雇主为海峡时报的成员,包括兼职工作。总部位于新加坡,新加坡成立于1845年,专业从事新闻和数字媒体
万豪酒店在全球拥有500多家酒店,以超越商务、团体和休闲旅客的期望,重塑酒店服务。
万豪酒店(Marriott Hotels)是万豪旗下优质、全方位服务酒店和度假村的旗舰品牌,为客人提供始终如一、可靠和真诚关怀的体验。万豪是一个出色的主人,客人可以轻松地将生活和工作融合在一起,并受到现代旅行如何增强两者的启发。我们的酒店提供热情、专业的服务;精致而实用的客房设计;大堂空间,方便工作、餐饮和社交;餐厅和酒吧提供简单的国际美食和最新鲜的食材;会议及活动场地及服务均属黄金标准;还有宽敞的24小时健身设施。
AERCO International, Inc.是公认的领导者,为教育、住宿、政府、办公楼、医疗保健、工业和多户住宅等各种市场提供具有成本效益的冷凝商用锅炉和高效热水器。AERCO的系统设计方法为客户提供特定的解决方案,以较低的运营成本提供卓越的建筑性能,同时确保正常运行时间的可靠性。AERCO成立于1949年,它推出了一种革命性的设计,用于间接燃烧热水器,在控制温度下按需加热水,而无需储存。这一创新成为当今热水器的标准,最大限度地回收潜热能量,显著提高运行效率。AERCO不断创新,并于1988年向商业市场推出了第一台冷凝和全调制锅炉和热水器。这些产品的调制能力,在超过25年后仍然无与伦比,使设备的输出与实时加热需求相匹配,确保机组不会消耗更多的燃料来运行,除非绝对必要。这不仅节省了宝贵的能源,还确保了钱不会不必要地消失在“堆栈”上。AERCO通过基于解决方案的模式脱颖而出,利用数十年的工程经验和行业应用专业知识来了解每个客户的独特需求。通过与客户和最终用户直接合作,了解他们的项目具体要求,AERCO提供量身定制的应用解决方案,这些解决方案由原创产品技术组成,包括高效冷凝产品,紧凑的足迹,高降压比,独特的燃料输送,领先的控制系统和专有设计元素,结合起来可提供高达99%的效率。网址http://www.aerco.com电话845-580- 8000电话号码845-580-8000工业工业机械制造公司规模51-200名员工LinkedIn上包括当前雇主AERCO International, Inc的成员,包括兼职职位。总部成立于1949年,纽约州布劳维尔特,专长:冷凝锅炉,水加热和能源回收产品的领先制造商,半瞬时水加热的鼻祖
Prince PLC:概述Prince PLC是为住宅、工业、市政和商业环境提供优质水解决方案的全球领导者。我们的品牌家族提供世界上最多样化的产品线之一,拥有世界级的水相关解决方案,专注于:•管道和流量控制•水质和调理•水再利用和排水•hvac•市政水务战略目标瓦茨水务在纽约证券交易所上市,代码为“WTS”。作为一家上市公司,股东价值的增长至关重要。为此,我们将重点放在五部分全球战略上:增长、卓越商业、卓越运营、“一瓦茨水”以及人才与绩效文化。在所有社交媒体平台关注我们@WattsWater网站http://www.watts.com/行业批发建材公司规模5,001-10,000名员工领英2,248名包括目前雇主为WattsWater Technologies的成员,包括兼职职位。总部北安多弗,MA专业管道,暖通空调,水质,气体,空调,自来水厂和排水
万怡酒店是万豪国际最大的酒店品牌,在全球50多个国家拥有1100多家酒店。所以,无论你的激情带你去哪里,你都会发现我们会帮助你追随它。万豪酒店的骄傲会员。
\ No newline at end of file
Index,Organization Id,Company Name,Website,Country,Description,Founded,Industry,Number of employees
1,FAB0d41d5b5d22c,Ferrell LLC,https://price.net/,Papua New Guinea,Horizontal empowering knowledgebase,1990,Plastics,3498
2,6A7EdDEA9FaDC52,"Mckinney, Riley and Day",http://www.hall-buchanan.info/,Finland,User-centric system-worthy leverage,2015,Glass / Ceramics / Concrete,4952
3,0bFED1ADAE4bcC1,Hester Ltd,http://sullivan-reed.com/,China,Switchable scalable moratorium,1971,Public Safety,5287
4,2bFC1Be8a4ce42f,Holder-Sellers,https://becker.com/,Turkmenistan,De-engineered systemic artificial intelligence,2004,Automotive,921
5,9eE8A6a4Eb96C24,Mayer Group,http://www.brewer.com/,Mauritius,Synchronized needs-based challenge,1991,Transportation,7870
6,cC757116fe1C085,Henry-Thompson,http://morse.net/,Bahamas,Face-to-face well-modulated customer loyalty,1992,Primary / Secondary Education,4914
7,219233e8aFF1BC3,Hansen-Everett,https://www.kidd.org/,Pakistan,Seamless disintermediate collaboration,2018,Publishing Industry,7832
8,ccc93DCF81a31CD,Mcintosh-Mora,https://www.brooks.com/,Heard Island and McDonald Islands,Centralized attitude-oriented capability,1970,Import / Export,4389
9,0B4F93aA06ED03e,Carr Inc,http://ross.com/,Kuwait,Distributed impactful customer loyalty,1996,Plastics,8167
10,738b5aDe6B1C6A5,Gaines Inc,http://sandoval-hooper.com/,Uzbekistan,Multi-lateral scalable protocol,1997,Outsourcing / Offshoring,9698
11,AE61b8Ffebbc476,Kidd Group,http://www.lyons.com/,Bouvet Island (Bouvetoya),Proactive foreground paradigm,2001,Primary / Secondary Education,7473
12,eb3B7D06cCdD609,Crane-Clarke,https://www.sandoval.com/,Denmark,Front-line clear-thinking encryption,2014,Food / Beverages,9011
13,8D0c29189C9798B,"Keller, Campos and Black",https://www.garner.info/,Liberia,Ameliorated directional emulation,2020,Museums / Institutions,2862
14,D2c91cc03CA394c,Glover-Pope,http://www.silva.biz/,United Arab Emirates,Persevering contextually-based approach,2013,Medical Practice,9079
15,C8AC1eaf9C036F4,Pacheco-Spears,https://aguilar.com/,Sweden,Secured logistical synergy,1984,Maritime,769
16,b5D10A14f7a8AfE,Hodge-Ayers,http://www.archer-elliott.com/,Honduras,Future-proofed radical implementation,1990,Facilities Services,8508
17,68139b5C4De03B4,"Bowers, Guerra and Krause",http://www.carrillo-nicholson.com/,Uganda,De-engineered transitional strategy,1972,Primary / Secondary Education,6986
18,5c2EffEfdba2BdF,Mckenzie-Melton,http://montoya-thompson.com/,Hong Kong,Reverse-engineered heuristic alliance,1998,Investment Management / Hedge Fund / Private Equity,4589
19,ba179F19F7925f5,Branch-Mann,http://www.lozano.com/,Botswana,Adaptive intangible frame,1999,Architecture / Planning,7961
20,c1Ce9B350BAc66b,Weiss and Sons,https://barrett.com/,Korea,Sharable optimal functionalities,2011,Plastics,5984
21,8de40AC4e6EaCa4,"Velez, Payne and Coffey",http://burton.com/,Luxembourg,Mandatory coherent synergy,1986,Wholesale,5010
22,Aad86a4F0385F2d,Harrell LLC,http://www.frey-rosario.com/,Guadeloupe,Reverse-engineered mission-critical moratorium,2018,Construction,2185
23,22aC3FFd64fD703,"Eaton, Reynolds and Vargas",http://www.freeman.biz/,Monaco,Self-enabling multi-tasking process improvement,2014,Luxury Goods / Jewelry,8987
24,5Ec4C272bCf085c,Robbins-Cummings,http://donaldson-wilkins.com/,Belgium,Organic non-volatile hierarchy,1991,Pharmaceuticals,5038
25,5fDBeA8BB91a000,Jenkins Inc,http://www.kirk.biz/,South Africa,Front-line systematic help-desk,2002,Insurance,1215
26,dFfD6a6F9AC2d9C,"Greene, Benjamin and Novak",http://www.kent.net/,Romania,Centralized leadingedge moratorium,2012,Museums / Institutions,4941
27,4B217cC5a0674C5,"Dickson, Richmond and Clay",http://everett.com/,Czech Republic,Team-oriented tangible complexity,1980,Real Estate / Mortgage,3122
28,88b1f1cDcf59a37,Prince-David,http://thompson.com/,Christmas Island,Virtual holistic methodology,1970,Banking / Mortgage,1046
29,f9F7bBCAEeC360F,Ayala LLC,http://www.zhang.com/,Philippines,Open-source zero administration hierarchy,2021,Legal Services,7664
30,7Cb3AeFcE4Ba31e,Rivas Group,https://hebert.org/,Australia,Open-architected well-modulated capacity,1998,Logistics / Procurement,4155
31,ccBcC32adcbc530,"Sloan, Mays and Whitehead",http://lawson.com/,Chad,Face-to-face high-level conglomeration,1997,Civil Engineering,365
32,f5afd686b3d05F5,"Durham, Allen and Barnes",http://chan-stafford.org/,Zimbabwe,Synergistic web-enabled framework,1993,Mechanical or Industrial Engineering,6135
33,38C6cfC5074Fa5e,Fritz-Franklin,http://www.lambert.com/,Nepal,Automated 4thgeneration website,1972,Hospitality,4516
34,5Cd7efccCcba38f,Burch-Ewing,http://cline.net/,Taiwan,User-centric 4thgeneration system engine,1981,Venture Capital / VC,7443
35,9E6Acb51e3F9d6F,"Glass, Barrera and Turner",https://dunlap.com/,Kyrgyz Republic,Multi-channeled 3rdgeneration open system,2020,Utilities,2610
36,4D4d7E18321eaeC,Pineda-Cox,http://aguilar.org/,Bolivia,Fundamental asynchronous capability,2010,Human Resources / HR,1312
37,485f5d06B938F2b,"Baker, Mccann and Macdonald",http://www.anderson-barker.com/,Kenya,Cross-group user-facing focus group,2013,Legislative Office,1638
38,19E3a5Bf6dBDc4F,Cuevas-Moss,https://dodson-castaneda.net/,Guatemala,Extended human-resource intranet,1994,Music,9995
39,6883A965c7b68F7,Hahn PLC,http://newman.com/,Belarus,Organic logistical leverage,2012,Electrical / Electronic Manufacturing,3715
40,AC5B7AA74Aa4A2E,"Valentine, Ferguson and Kramer",http://stuart.net/,Jersey,Centralized secondary time-frame,1997,Non - Profit / Volunteering,3585
41,decab0D5027CA6a,Arroyo Inc,https://www.turner.com/,Grenada,Managed demand-driven website,2006,Writing / Editing,9067
42,dF084FbBb613eea,Walls LLC,http://www.reese-vasquez.biz/,Cape Verde,Self-enabling fresh-thinking installation,1989,Investment Management / Hedge Fund / Private Equity,1678
43,A2D89Ab9bCcAd4e,"Mitchell, Warren and Schneider",https://fox.biz/,Trinidad and Tobago,Enhanced intangible time-frame,2021,Capital Markets / Hedge Fund / Private Equity,3816
44,77aDc905434a49f,Prince PLC,https://www.watts.com/,Sweden,Profit-focused coherent installation,2016,Individual / Family Services,7645
45,235fdEFE2cfDa5F,Brock-Blackwell,http://www.small.com/,Benin,Secured foreground emulation,1986,Online Publishing,7034
46,1eD64cFe986BBbE,Walton-Barnett,https://ashley-schaefer.com/,Western Sahara,Right-sized clear-thinking flexibility,2001,Luxury Goods / Jewelry,1746
47,CbBbFcdd0eaE2cF,Bartlett-Arroyo,https://cruz.com/,Northern Mariana Islands,Realigned didactic function,1976,Civic / Social Organization,3987
48,49aECbDaE6aBD53,"Wallace, Madden and Morris",http://www.blevins-fernandez.biz/,Germany,Persistent real-time customer loyalty,2016,Pharmaceuticals,9443
49,7b3fe6e7E72bFa4,Berg-Sparks,https://cisneros-love.com/,Canada,Stand-alone static implementation,1974,Arts / Crafts,2073
50,c6DedA82A8aef7E,Gonzales Ltd,http://bird.com/,Tonga,Managed human-resource policy,1988,Consumer Goods,9069
51,7D9FBF85cdC3871,Lawson and Sons,https://www.wong.com/,French Southern Territories,Compatible analyzing intranet,2021,Arts / Crafts,3527
52,7dd18Fb7cB07b65,"Mcguire, Mcconnell and Olsen",https://melton-briggs.com/,Korea,Profound client-server frame,1988,Printing,8445
53,EF5B55FadccB8Fe,Charles-Phillips,https://bowman.com/,Cote d'Ivoire,Monitored client-server implementation,2012,Mental Health Care,3450
54,f8D4B99e11fAF5D,Odom Ltd,https://www.humphrey-hess.com/,Cote d'Ivoire,Advanced static process improvement,2012,Management Consulting,1825
55,e24D21BFd3bF1E5,Richard PLC,https://holden-coleman.net/,Mayotte,Object-based optimizing model,1971,Broadcast Media,4942
56,B9BdfEB6D3Ca44E,Sampson Ltd,https://blevins.com/,Cayman Islands,Intuitive local adapter,2005,Farming,1418
57,2a74D6f3D3B268e,"Cherry, Le and Callahan",https://waller-delacruz.biz/,Nigeria,Universal human-resource collaboration,2017,Entertainment / Movie Production,7202
58,Bf3F3f62c8aBC33,Cherry PLC,https://www.avila.info/,Marshall Islands,Persistent tertiary website,1980,Plastics,8245
59,aeBe26B80a7a23c,Melton-Nichols,https://kennedy.com/,Palau,User-friendly clear-thinking productivity,2021,Legislative Office,8741
60,aAeb29ad43886C6,Potter-Walsh,http://thomas-french.org/,Turkey,Optional non-volatile open system,2008,Human Resources / HR,6923
61,bD1bc6bB6d1FeD3,Freeman-Chen,https://mathis.com/,Timor-Leste,Phased next generation adapter,1973,International Trade / Development,346
62,EB9f456e8b7022a,Soto Group,https://norris.info/,Vietnam,Enterprise-wide executive installation,1988,Business Supplies / Equipment,9097
63,Dfef38C51D8DAe3,"Poole, Cruz and Whitney",https://reed.info/,Reunion,Balanced analyzing groupware,1978,Marketing / Advertising / Sales,2992
64,055ffEfB2Dd95B0,Riley Ltd,http://wiley.com/,Brazil,Optional exuding superstructure,1986,Textiles,9315
65,cBfe4dbAE1699da,"Erickson, Andrews and Bailey",https://www.hobbs-grant.com/,Eritrea,Vision-oriented secondary project,2014,Consumer Electronics,7829
66,fdFbecbadcdCdf1,"Wilkinson, Charles and Arroyo",http://hunter-mcfarland.com/,United States Virgin Islands,Assimilated 24/7 archive,1996,Building Materials,602
67,5DCb8A5a5ca03c0,Floyd Ltd,http://www.whitney.com/,Falkland Islands (Malvinas),Function-based fault-tolerant concept,2017,Public Relations / PR,2911
68,ce57DCbcFD6d618,Newman-Galloway,https://www.scott.com/,Luxembourg,Enhanced foreground collaboration,1987,Information Technology / IT,3934
69,5aaD187dc929371,Frazier-Butler,https://www.daugherty-farley.info/,Northern Mariana Islands,Persistent interactive circuit,1972,Outsourcing / Offshoring,5130
70,902D7Ac8b6d476b,Newton Inc,https://www.richmond-manning.info/,Netherlands Antilles,Fundamental stable info-mediaries,1976,Military Industry,563
71,32BB9Ff4d939788,Duffy-Levy,https://www.potter.com/,Guernsey,Diverse exuding installation,1982,Wireless,6146
72,adcB0afbE58bAe3,Wagner LLC,https://decker-esparza.com/,Uruguay,Reactive attitude-oriented toolset,1987,International Affairs,6874
73,dfcA1c84AdB61Ac,Mccall-Holmes,http://www.dean.com/,Benin,Object-based value-added database,2009,Legal Services,696
74,208044AC2fe52F3,Massey LLC,https://frazier.biz/,Suriname,Configurable zero administration Graphical User Interface,1986,Accounting,5004
75,f3C365f0c1A0623,Hicks LLC,http://alvarez.biz/,Pakistan,Quality-focused client-server Graphical User Interface,1970,Computer Software / Engineering,8480
76,ec5Bdd3CBAfaB93,"Cole, Russell and Avery",http://www.blankenship.com/,Mongolia,De-engineered fault-tolerant challenge,2000,Law Enforcement,7012
77,DDB19Be7eeB56B4,Cummings-Rojas,https://simon-pearson.com/,Svalbard & Jan Mayen Islands,User-centric modular customer loyalty,2012,Financial Services,7529
78,dd6CA3d0bc3cAfc,"Beasley, Greene and Mahoney",http://www.petersen-lawrence.com/,Togo,Extended content-based methodology,1976,Religious Institutions,869
79,A0B9d56e61070e3,"Beasley, Sims and Allison",http://burke.info/,Latvia,Secured zero tolerance hub,1972,Facilities Services,6182
80,cBa7EFe5D05Adaf,Crawford-Rivera,https://black-ramirez.org/,Cuba,Persevering exuding budgetary management,1999,Online Publishing,7805
81,Ea3f6D52Ec73563,Montes-Hensley,https://krueger.org/,Liechtenstein,Multi-tiered secondary productivity,2009,Printing,8433
82,bC0CEd48A8000E0,Velazquez-Odom,https://stokes.com/,Djibouti,Streamlined 6thgeneration function,2002,Alternative Dispute Resolution,4044
83,c89b9b59BC4baa1,Eaton-Morales,https://www.reeves-graham.com/,Micronesia,Customer-focused explicit frame,1990,Capital Markets / Hedge Fund / Private Equity,7013
84,FEC51bce8421a7b,"Roberson, Pennington and Palmer",http://www.keith-fisher.com/,Cameroon,Adaptive bi-directional hierarchy,1993,Telecommunications,5571
85,e0E8e27eAc9CAd5,"George, Russo and Guerra",https://drake.com/,Sweden,Centralized non-volatile capability,1989,Military Industry,2880
86,B97a6CF9bf5983C,Davila Inc,https://mcconnell.info/,Cocos (Keeling) Islands,Profit-focused dedicated frame,2017,Consumer Electronics,2215
87,a0a6f9b3DbcBEb5,Mays-Preston,http://www.browning-key.com/,Mali,User-centric heuristic focus group,2006,Military Industry,5786
88,8cC1bDa330a5871,Pineda-Morton,https://www.carr.com/,United States Virgin Islands,Grass-roots methodical info-mediaries,1991,Printing,6168
89,ED889CB2FE9cbd3,Huang and Sons,https://www.bolton.com/,Eritrea,Re-contextualized dynamic hierarchy,1981,Semiconductors,7484
90,F4Dc1417BC6cb8f,Gilbert-Simon,https://www.bradford.biz/,Burundi,Grass-roots radical parallelism,1973,Newspapers / Journalism,1927
91,7ABc3c7ecA03B34,Sampson-Griffith,http://hendricks.org/,Benin,Multi-layered composite paradigm,1972,Textiles,3881
92,4e0719FBE38e0aB,Miles-Dominguez,http://www.turner.com/,Gibraltar,Organized empowering forecast,1996,Civic / Social Organization,897
93,dEbDAAeDfaed00A,Rowe and Sons,https://www.simpson.org/,El Salvador,Balanced multimedia knowledgebase,1978,Facilities Services,8172
94,61BDeCfeFD0cEF5,"Valenzuela, Holmes and Rowland",https://www.dorsey.net/,Taiwan,Persistent tertiary focus group,1999,Transportation,1483
95,4e91eD25f486110,"Best, Wade and Shepard",https://zimmerman.com/,Zimbabwe,Innovative background definition,1991,Gambling / Casinos,4873
96,0a0bfFbBbB8eC7c,Holmes Group,https://mcdowell.org/,Ethiopia,Right-sized zero tolerance focus group,1975,Photography,2988
97,BA6Cd9Dae2Efd62,Good Ltd,http://duffy.com/,Anguilla,Reverse-engineered composite moratorium,1971,Consumer Services,4292
98,E7df80C60Abd7f9,Clements-Espinoza,http://www.flowers.net/,Falkland Islands (Malvinas),Progressive modular hub,1991,Broadcast Media,236
99,AFc285dbE2fEd24,Mendez Inc,https://www.burke.net/,Kyrgyz Republic,User-friendly exuding migration,1993,Education Management,339
100,e9eB5A60Cef8354,Watkins-Kaiser,http://www.herring.com/,Togo,Synergistic background access,2009,Financial Services,2785
\ No newline at end of file
{"features":[{"feature_idx":0,"name":"query","type":{"dtype":"string","_type":"Value"}},{"feature_idx":1,"name":"response","type":{"dtype":"string","_type":"Value"}}],"rows":[{"row_idx":0,"row":{"query":"My order hasn't arrived yet.","response":"We apologize for the inconvenience. Can you please provide your order number so we can investigate?"},"truncated_cells":[]},{"row_idx":1,"row":{"query":"I received a damaged product.","response":"We apologize for the inconvenience. Can you please provide a photo of the damaged product so we can assist you further?"},"truncated_cells":[]},{"row_idx":2,"row":{"query":"I need to return an item.","response":"Certainly. Please provide your order number and reason for return, and we will provide you with instructions on how to proceed."},"truncated_cells":[]},{"row_idx":3,"row":{"query":"I want to change my shipping address.","response":"No problem. Can you please provide your order number and the new shipping address you'd like to use?"},"truncated_cells":[]},{"row_idx":4,"row":{"query":"I have a question about my bill.","response":"We'd be happy to help. Can you please provide your account number and a brief description of your question?"},"truncated_cells":[]},{"row_idx":5,"row":{"query":"How do I cancel my subscription?","response":"We're sorry to hear that. Can you please provide your account email and the name of the subscription you'd like to cancel?"},"truncated_cells":[]},{"row_idx":6,"row":{"query":"Can I get a refund for my purchase?","response":"We understand your concern. Please provide your order number and the reason for your refund request so we can assist you further."},"truncated_cells":[]},{"row_idx":7,"row":{"query":"I'd like to track my order.","response":"Of course. Can you please provide your order number so we can check the current status for you?"},"truncated_cells":[]},{"row_idx":8,"row":{"query":"My account has been locked.","response":"We apologize for the inconvenience. Can you please provide your account email so we can help you regain access?"},"truncated_cells":[]},{"row_idx":9,"row":{"query":"I can't find the item I'm looking for.","response":"We're here to help. Can you please provide a description or product name of the item you're looking for so we can assist you?"},"truncated_cells":[]},{"row_idx":10,"row":{"query":"I'm having trouble applying a promo code.","response":"We apologize for the inconvenience. Can you please provide the promo code you're trying to use, and we'll help you resolve the issue?"},"truncated_cells":[]},{"row_idx":11,"row":{"query":"How do I update my payment information?","response":"We can help with that. Can you please provide your account email so we can guide you through updating your payment information?"},"truncated_cells":[]},{"row_idx":12,"row":{"query":"I haven't received a response to my email inquiry.","response":"We apologize for the delay. Can you please provide your ticket number or account email so we can follow up on your inquiry?"},"truncated_cells":[]},{"row_idx":13,"row":{"query":"Can I change the size of an item in my order?","response":"Certainly. Can you please provide your order number and the details of the item you'd like to change?"},"truncated_cells":[]},{"row_idx":14,"row":{"query":"What is the status of my warranty claim?","response":"We'd be happy to check for you. Can you please provide your claim number or the product's serial number?"},"truncated_cells":[]},{"row_idx":15,"row":{"query":"Is my item in stock?","response":"To check availability, can you please provide the product name or SKU so we can assist you?"},"truncated_cells":[]},{"row_idx":16,"row":{"query":"My promo code has expired. Can I still use it?","response":"Unfortunately, expired promo codes cannot be used. However, please provide the code, and we'll see if there's a similar offer currently available."},"truncated_cells":[]},{"row_idx":17,"row":{"query":"How do I reset my password?","response":"We can help with that. Please provide your account email, and we'll send you instructions on how to reset your password."},"truncated_cells":[]},{"row_idx":18,"row":{"query":"Can I place a bulk order?","response":"Certainly. Can you please provide the product name or SKU, and the quantity you'd like to order so we can check availability and pricing?"},"truncated_cells":[]},{"row_idx":19,"row":{"query":"How do I apply for a job at your company?","response":"Thank you for your interest. Can you please provide your email address so we can send you information on how to apply?"},"truncated_cells":[]},{"row_idx":20,"row":{"query":"Can I add an item to an existing order?","response":"We'll do our best to help. Can you please provide your order number and the details of the item you'd like to add?"},"truncated_cells":[]},{"row_idx":21,"row":{"query":"How long does shipping take?","response":"We'd be happy to provide an estimate. Can you please provide your shipping destination and the product name or SKU?"},"truncated_cells":[]},{"row_idx":22,"row":{"query":"I was charged twice for my order.","response":"We apologize for the inconvenience. Can you please provide your order number so we can investigate and resolve the issue?"},"truncated_cells":[]},{"row_idx":23,"row":{"query":"Where can I find your sizing chart?","response":"We'd be happy to help. Can you please provide the product name or SKU so we can direct you to the appropriate sizing chart?"},"truncated_cells":[]},{"row_idx":24,"row":{"query":"I need technical support for a product.","response":"We're here to help. Can you please provide the product name, SKU, or serial number, and a description of the issue you're experiencing?"},"truncated_cells":[]},{"row_idx":25,"row":{"query":"Can I exchange an item for a different color?","response":"Certainly. Can you please provide your order number and the details of the item you'd like to exchange?"},"truncated_cells":[]},{"row_idx":26,"row":{"query":"How do I apply for a store credit card?","response":"Thank you for your interest. Can you please provide your email address so we can send you information on how to apply?"},"truncated_cells":[]},{"row_idx":27,"row":{"query":"Where is your store located?","response":"We'd be happy to help you find a store near you. Can you please provide your city and state or zip code?"},"truncated_cells":[]},{"row_idx":28,"row":{"query":"I can't log into my account.","response":"We apologize for the inconvenience. Can you please provide your account email so we can help you troubleshoot the issue?"},"truncated_cells":[]},{"row_idx":29,"row":{"query":"Do you offer gift wrapping?","response":"We do offer gift wrapping for select items. Can you please provide the product name or SKU so we can confirm if gift wrapping is available?"},"truncated_cells":[]},{"row_idx":30,"row":{"query":"Can I schedule a delivery?","response":"Certainly. Can you please provide your order number and the preferred date and time for delivery?"},"truncated_cells":[]},{"row_idx":31,"row":{"query":"How do I unsubscribe from your newsletter?","response":"We're sorry to see you go. Can you please provide your email address so we can remove you from our mailing list?"},"truncated_cells":[]},{"row_idx":32,"row":{"query":"What is your return policy?","response":"We'd be happy to provide information on our return policy. Can you please provide the product name or SKU so we can give you the most accurate information?"},"truncated_cells":[]},{"row_idx":33,"row":{"query":"Do you offer price matching?","response":"We do offer price matching in certain cases. Can you please provide the product name or SKU and the competitor's pricing information?"},"truncated_cells":[]},{"row_idx":34,"row":{"query":"Are there any current promotions or sales?","response":"We'd be happy to inform you of any current promotions. Can you please provide the product name or SKU you're interested in, or the type of promotion you're looking for?"},"truncated_cells":[]},{"row_idx":35,"row":{"query":"My coupon isn't working.","response":"We apologize for the inconvenience. Can you please provide the coupon code and the product name or SKU you're trying to apply it to?"},"truncated_cells":[]},{"row_idx":36,"row":{"query":"Can you help me with a product recommendation?","response":"Of course! Can you please provide some details about what you're looking for, such as product type, features, or price range?"},"truncated_cells":[]},{"row_idx":37,"row":{"query":"Do you offer international shipping?","response":"We'd be happy to help. Can you please provide your shipping destination and the product name or SKU you're interested in?"},"truncated_cells":[]},{"row_idx":38,"row":{"query":"Can I place an order over the phone?","response":"Certainly. Can you please provide your phone number and the best time to reach you, and one of our representatives will contact you to place the order?"},"truncated_cells":[]},{"row_idx":39,"row":{"query":"How do I know if my order went through?","response":"We can help you with that. Can you please provide your account email or order number so we can check the status for you?"},"truncated_cells":[]},{"row_idx":40,"row":{"query":"Can I use multiple promo codes on one order?","response":"In most cases, only one promo code can be applied per order. Can you please provide the promo codes you're trying to use so we can check their compatibility?"},"truncated_cells":[]},{"row_idx":41,"row":{"query":"What are your customer service hours?","response":"Our customer service team is available 24/7 to assist you. Please feel free to reach out with any questions or concerns."},"truncated_cells":[]},{"row_idx":42,"row":{"query":"Where can I find the user manual for my product?","response":"We'd be happy to help. Can you please provide the product name, SKU, or serial number so we can direct you to the appropriate user manual?"},"truncated_cells":[]},{"row_idx":43,"row":{"query":"Do you offer a warranty on your products?","response":"We do offer warranties on select products. Can you please provide the product name or SKU so we can provide you with warranty information?"},"truncated_cells":[]},{"row_idx":44,"row":{"query":"Can I place an order for in-store pickup?","response":"Certainly. Can you please provide the product name or SKU and the store location where you'd like to pick up your order?"},"truncated_cells":[]},{"row_idx":45,"row":{"query":"How do I sign up for your rewards program?","response":"Thank you for your interest in our rewards program. Can you please provide your email address so we can send you information on how to sign up?"},"truncated_cells":[]},{"row_idx":46,"row":{"query":"Can I pay with a gift card online?","response":"Yes, you can use gift cards for online purchases. Can you please provide the gift card number and the product name or SKU you're interested in?"},"truncated_cells":[]},{"row_idx":47,"row":{"query":"I can't find my order confirmation email.","response":"We apologize for the inconvenience. Can you please provide your account email or order number so we can resend the confirmation email?"},"truncated_cells":[]},{"row_idx":48,"row":{"query":"Do you offer a military discount?","response":"Yes, we do offer a military discount. Can you please provide your military ID or email address so we can apply the discount to your account?"},"truncated_cells":[]},{"row_idx":49,"row":{"query":"What is the processing time for my order?","response":"We'd be happy to provide an estimate. Can you please provide your order number or the product name or SKU?"},"truncated_cells":[]},{"row_idx":50,"row":{"query":"How do I update my shipping preferences?","response":"We can help with that. Can you please provide your account email so we can guide you through updating your shipping preferences?"},"truncated_cells":[]},{"row_idx":51,"row":{"query":"Is my payment information secure?","response":"Yes, we take security very seriously. Can you please provide your account email so we can verify the security measures in place for your payment information?"},"truncated_cells":[]},{"row_idx":52,"row":{"query":"Can I pre-order an item?","response":"Certainly. Can you please provide the product name or SKU and your email address so we can notify you when pre-orders are available?"},"truncated_cells":[]},{"row_idx":53,"row":{"query":"How do I use a gift card in-store?","response":"To use a gift card in-store, simply present the gift card at the time of purchase. Can you please provide the gift card number so we can check the balance for you?"},"truncated_cells":[]},{"row_idx":54,"row":{"query":"Do you have a loyalty program?","response":"Yes, we do have a loyalty program. Can you please provide your email address so we can send you information on how to join and enjoy the benefits?"},"truncated_cells":[]},{"row_idx":55,"row":{"query":"Is there a mobile app for your store?","response":"Yes, we do have a mobile app. Can you please provide your email address so we can send you a link to download the app and instructions on how to use it?"},"truncated_cells":[]},{"row_idx":56,"row":{"query":"I need help assembling my product.","response":"We're here to help. Can you please provide the product name, SKU, or serial number, and a description of the issue you're experiencing during assembly?"},"truncated_cells":[]},{"row_idx":57,"row":{"query":"Do you offer financing options?","response":"We do offer financing options for select purchases. Can you please provide the product name or SKU and your email address so we can send you more information?"},"truncated_cells":[]},{"row_idx":58,"row":{"query":"Can I reserve an item in-store?","response":"Certainly. Can you please provide the product name or SKU and the store location where you'd like to reserve the item?"},"truncated_cells":[]},{"row_idx":59,"row":{"query":"How do I get a price adjustment for a recent purchase?","response":"We'd be happy to help. Can you please provide your order number and the product name or SKU for the item you'd like a price adjustment on?"},"truncated_cells":[]},{"row_idx":60,"row":{"query":"How do I change my email preferences?","response":"We can help with that. Can you please provide your account email so we can guide you through updating your email preferences?"},"truncated_cells":[]},{"row_idx":61,"row":{"query":"Can I use my store credit online?","response":"Yes, you can use store credit for online purchases. Can you please provide the store credit number and the product name or SKU you're interested in?"},"truncated_cells":[]},{"row_idx":62,"row":{"query":"What are the washing instructions for this item?","response":"We'd be happy to help. Can you please provide the product name or SKU so we can provide you with the proper washing instructions?"},"truncated_cells":[]},{"row_idx":63,"row":{"query":"Can I get a replacement part for my product?","response":"Certainly. Can you please provide the product name, SKU, or serial number, and a description of the part you need?"},"truncated_cells":[]},{"row_idx":64,"row":{"query":"Do you offer free shipping?","response":"We do offer free shipping on select orders. Can you please provide the product name or SKU and your shipping destination so we can check if your order qualifies?"},"truncated_cells":[]},{"row_idx":65,"row":{"query":"Can I place a custom order?","response":"We'd be happy to assist you. Can you please provide the product name or SKU and a description of the customizations you'd like?"},"truncated_cells":[]},{"row_idx":66,"row":{"query":"How do I report a problem with your website?","response":"We appreciate your feedback. Can you please provide a description of the issue you're experiencing and your email address so we can follow up with you?"},"truncated_cells":[]},{"row_idx":67,"row":{"query":"What is your policy on price adjustments?","response":"We'd be happy to provide information on our price adjustment policy. Can you please provide the product name or SKU so we can give you the most accurate information?"},"truncated_cells":[]},{"row_idx":68,"row":{"query":"Do you have any upcoming sales or events?","response":"We'd be happy to inform you of any upcoming sales or events. Can you please provide your email address so we can keep you updated?"},"truncated_cells":[]},{"row_idx":69,"row":{"query":"How do I schedule a consultation or appointment?","response":"We'd be happy to help. Can you please provide your name, phone number, and the service you're interested in so we can schedule your appointment?"},"truncated_cells":[]},{"row_idx":70,"row":{"query":"Can I get a copy of my receipt?","response":"Certainly. Can you please provide your order number or account email so we can locate your receipt and send you a copy?"},"truncated_cells":[]},{"row_idx":71,"row":{"query":"Can I use a competitor's coupon at your store?","response":"In some cases, we may accept competitor coupons. Can you please provide the competitor's coupon code and the product name or SKU you'd like to apply it to?"},"truncated_cells":[]},{"row_idx":72,"row":{"query":"Do you have a recycling program?","response":"Yes, we do have a recycling program. Can you please provide your email address so we can send you information on how to participate?"},"truncated_cells":[]},{"row_idx":73,"row":{"query":"How do I report a lost or stolen gift card?","response":"We're sorry to hear that. Can you please provide the gift card number, if available, and your email address so we can assist you further?"},"truncated_cells":[]}],"num_rows_total":74,"num_rows_per_page":100}
{
"data": [
{
"key": "客户反映手机无法接收短信,但可以正常拨打电话,已确认手机号码正常,需要处理。",
"value": "故障原因分类: 短信接收问题"
},
{
"key": "客户申请开通国际漫游服务,但在目的地无法使用手机信号,已核实客户所在地国家为不支持漫游的区域,已通知客户。",
"value": "故障原因分类: 国际漫游服务"
},
{
"key": "客户称手机信号时强时弱,经过测试发现在不同区域信号确实存在波动,属于正常现象。",
"value": "故障原因分类: 信号强弱波动"
},
{
"key": "客户反映在家中无法连接Wi-Fi,建议检查路由器或尝试更换位置。",
"value": "故障原因分类: 家庭网络问题"
},
{
"key": "客户申请更换新的SIM卡,因旧卡损坏,已为客户办理新卡。",
"value": "故障原因分类: SIM卡更换"
},
{
"key": "客户反映通话时听不清对方声音,经检查发现是手机内置扬声器故障,建议维修。",
"value": "故障原因分类: 扬声器故障"
},
{
"key": "客户手机丢失,请求挂失并办理新卡,已为客户挂失旧卡并补办新卡。",
"value": "故障原因分类: 挂失与补办"
},
{
"key": "客户反映在市区内无法使用手机信号,经排查发现信号塔维护,属于暂时性故障。",
"value": "故障原因分类: 信号塔维护"
},
{
"key": "客户反映手机充电时出现过热情况,建议更换充电器。",
"value": "故障原因分类: 充电器故障"
},
{
"key": "客户要求关闭数据漫游功能,已为客户关闭。",
"value": "故障原因分类: 关闭数据漫游"
},
{
"key": "客户申请办理家庭套餐业务,已为客户办理。",
"value": "故障原因分类: 家庭套餐办理"
},
{
"key": "客户反映在商场内无法使用手机信号,建议检查手机信号设置。",
"value": "故障原因分类: 手机信号设置"
},
{
"key": "客户申请开通国际长途业务,已为客户办理。",
"value": "故障原因分类: 国际长途业务办理"
},
{
"key": "客户反映手机屏幕出现蓝屏,建议客户前往维修。",
"value": "故障原因分类: 手机屏幕故障"
},
{
"key": "客户申请办理免流量业务,已为客户办理。",
"value": "故障原因分类: 免流量业务办理"
}
]
}
{"data": [{"key": "My order hasn't arrived yet.", "value": "We apologize for the inconvenience. Can you please provide your order number so we can investigate?"}, {"key": "I received a damaged product.", "value": "We apologize for the inconvenience. Can you please provide a photo of the damaged product so we can assist you further?"}, {"key": "I need to return an item.", "value": "Certainly. Please provide your order number and reason for return, and we will provide you with instructions on how to proceed."}, {"key": "I want to change my shipping address.", "value": "No problem. Can you please provide your order number and the new shipping address you'd like to use?"}, {"key": "I have a question about my bill.", "value": "We'd be happy to help. Can you please provide your account number and a brief description of your question?"}, {"key": "How do I cancel my subscription?", "value": "We're sorry to hear that. Can you please provide your account email and the name of the subscription you'd like to cancel?"}, {"key": "Can I get a refund for my purchase?", "value": "We understand your concern. Please provide your order number and the reason for your refund request so we can assist you further."}, {"key": "I'd like to track my order.", "value": "Of course. Can you please provide your order number so we can check the current status for you?"}, {"key": "My account has been locked.", "value": "We apologize for the inconvenience. Can you please provide your account email so we can help you regain access?"}, {"key": "I can't find the item I'm looking for.", "value": "We're here to help. Can you please provide a description or product name of the item you're looking for so we can assist you?"}, {"key": "I'm having trouble applying a promo code.", "value": "We apologize for the inconvenience. Can you please provide the promo code you're trying to use, and we'll help you resolve the issue?"}, {"key": "How do I update my payment information?", "value": "We can help with that. Can you please provide your account email so we can guide you through updating your payment information?"}, {"key": "I haven't received a response to my email inquiry.", "value": "We apologize for the delay. Can you please provide your ticket number or account email so we can follow up on your inquiry?"}, {"key": "Can I change the size of an item in my order?", "value": "Certainly. Can you please provide your order number and the details of the item you'd like to change?"}, {"key": "What is the status of my warranty claim?", "value": "We'd be happy to check for you. Can you please provide your claim number or the product's serial number?"}, {"key": "Is my item in stock?", "value": "To check availability, can you please provide the product name or SKU so we can assist you?"}, {"key": "My promo code has expired. Can I still use it?", "value": "Unfortunately, expired promo codes cannot be used. However, please provide the code, and we'll see if there's a similar offer currently available."}, {"key": "How do I reset my password?", "value": "We can help with that. Please provide your account email, and we'll send you instructions on how to reset your password."}, {"key": "Can I place a bulk order?", "value": "Certainly. Can you please provide the product name or SKU, and the quantity you'd like to order so we can check availability and pricing?"}, {"key": "How do I apply for a job at your company?", "value": "Thank you for your interest. Can you please provide your email address so we can send you information on how to apply?"}, {"key": "Can I add an item to an existing order?", "value": "We'll do our best to help. Can you please provide your order number and the details of the item you'd like to add?"}, {"key": "How long does shipping take?", "value": "We'd be happy to provide an estimate. Can you please provide your shipping destination and the product name or SKU?"}, {"key": "I was charged twice for my order.", "value": "We apologize for the inconvenience. Can you please provide your order number so we can investigate and resolve the issue?"}, {"key": "Where can I find your sizing chart?", "value": "We'd be happy to help. Can you please provide the product name or SKU so we can direct you to the appropriate sizing chart?"}, {"key": "I need technical support for a product.", "value": "We're here to help. Can you please provide the product name, SKU, or serial number, and a description of the issue you're experiencing?"}, {"key": "Can I exchange an item for a different color?", "value": "Certainly. Can you please provide your order number and the details of the item you'd like to exchange?"}, {"key": "How do I apply for a store credit card?", "value": "Thank you for your interest. Can you please provide your email address so we can send you information on how to apply?"}, {"key": "Where is your store located?", "value": "We'd be happy to help you find a store near you. Can you please provide your city and state or zip code?"}, {"key": "I can't log into my account.", "value": "We apologize for the inconvenience. Can you please provide your account email so we can help you troubleshoot the issue?"}, {"key": "Do you offer gift wrapping?", "value": "We do offer gift wrapping for select items. Can you please provide the product name or SKU so we can confirm if gift wrapping is available?"}, {"key": "Can I schedule a delivery?", "value": "Certainly. Can you please provide your order number and the preferred date and time for delivery?"}, {"key": "How do I unsubscribe from your newsletter?", "value": "We're sorry to see you go. Can you please provide your email address so we can remove you from our mailing list?"}, {"key": "What is your return policy?", "value": "We'd be happy to provide information on our return policy. Can you please provide the product name or SKU so we can give you the most accurate information?"}, {"key": "Do you offer price matching?", "value": "We do offer price matching in certain cases. Can you please provide the product name or SKU and the competitor's pricing information?"}, {"key": "Are there any current promotions or sales?", "value": "We'd be happy to inform you of any current promotions. Can you please provide the product name or SKU you're interested in, or the type of promotion you're looking for?"}, {"key": "My coupon isn't working.", "value": "We apologize for the inconvenience. Can you please provide the coupon code and the product name or SKU you're trying to apply it to?"}, {"key": "Can you help me with a product recommendation?", "value": "Of course! Can you please provide some details about what you're looking for, such as product type, features, or price range?"}, {"key": "Do you offer international shipping?", "value": "We'd be happy to help. Can you please provide your shipping destination and the product name or SKU you're interested in?"}, {"key": "Can I place an order over the phone?", "value": "Certainly. Can you please provide your phone number and the best time to reach you, and one of our representatives will contact you to place the order?"}, {"key": "How do I know if my order went through?", "value": "We can help you with that. Can you please provide your account email or order number so we can check the status for you?"}, {"key": "Can I use multiple promo codes on one order?", "value": "In most cases, only one promo code can be applied per order. Can you please provide the promo codes you're trying to use so we can check their compatibility?"}, {"key": "What are your customer service hours?", "value": "Our customer service team is available 24/7 to assist you. Please feel free to reach out with any questions or concerns."}, {"key": "Where can I find the user manual for my product?", "value": "We'd be happy to help. Can you please provide the product name, SKU, or serial number so we can direct you to the appropriate user manual?"}, {"key": "Do you offer a warranty on your products?", "value": "We do offer warranties on select products. Can you please provide the product name or SKU so we can provide you with warranty information?"}, {"key": "Can I place an order for in-store pickup?", "value": "Certainly. Can you please provide the product name or SKU and the store location where you'd like to pick up your order?"}, {"key": "How do I sign up for your rewards program?", "value": "Thank you for your interest in our rewards program. Can you please provide your email address so we can send you information on how to sign up?"}, {"key": "Can I pay with a gift card online?", "value": "Yes, you can use gift cards for online purchases. Can you please provide the gift card number and the product name or SKU you're interested in?"}, {"key": "I can't find my order confirmation email.", "value": "We apologize for the inconvenience. Can you please provide your account email or order number so we can resend the confirmation email?"}, {"key": "Do you offer a military discount?", "value": "Yes, we do offer a military discount. Can you please provide your military ID or email address so we can apply the discount to your account?"}, {"key": "What is the processing time for my order?", "value": "We'd be happy to provide an estimate. Can you please provide your order number or the product name or SKU?"}, {"key": "How do I update my shipping preferences?", "value": "We can help with that. Can you please provide your account email so we can guide you through updating your shipping preferences?"}, {"key": "Is my payment information secure?", "value": "Yes, we take security very seriously. Can you please provide your account email so we can verify the security measures in place for your payment information?"}, {"key": "Can I pre-order an item?", "value": "Certainly. Can you please provide the product name or SKU and your email address so we can notify you when pre-orders are available?"}, {"key": "How do I use a gift card in-store?", "value": "To use a gift card in-store, simply present the gift card at the time of purchase. Can you please provide the gift card number so we can check the balance for you?"}, {"key": "Do you have a loyalty program?", "value": "Yes, we do have a loyalty program. Can you please provide your email address so we can send you information on how to join and enjoy the benefits?"}, {"key": "Is there a mobile app for your store?", "value": "Yes, we do have a mobile app. Can you please provide your email address so we can send you a link to download the app and instructions on how to use it?"}, {"key": "I need help assembling my product.", "value": "We're here to help. Can you please provide the product name, SKU, or serial number, and a description of the issue you're experiencing during assembly?"}, {"key": "Do you offer financing options?", "value": "We do offer financing options for select purchases. Can you please provide the product name or SKU and your email address so we can send you more information?"}, {"key": "Can I reserve an item in-store?", "value": "Certainly. Can you please provide the product name or SKU and the store location where you'd like to reserve the item?"}, {"key": "How do I get a price adjustment for a recent purchase?", "value": "We'd be happy to help. Can you please provide your order number and the product name or SKU for the item you'd like a price adjustment on?"}, {"key": "How do I change my email preferences?", "value": "We can help with that. Can you please provide your account email so we can guide you through updating your email preferences?"}, {"key": "Can I use my store credit online?", "value": "Yes, you can use store credit for online purchases. Can you please provide the store credit number and the product name or SKU you're interested in?"}, {"key": "What are the washing instructions for this item?", "value": "We'd be happy to help. Can you please provide the product name or SKU so we can provide you with the proper washing instructions?"}, {"key": "Can I get a replacement part for my product?", "value": "Certainly. Can you please provide the product name, SKU, or serial number, and a description of the part you need?"}, {"key": "Do you offer free shipping?", "value": "We do offer free shipping on select orders. Can you please provide the product name or SKU and your shipping destination so we can check if your order qualifies?"}, {"key": "Can I place a custom order?", "value": "We'd be happy to assist you. Can you please provide the product name or SKU and a description of the customizations you'd like?"}, {"key": "How do I report a problem with your website?", "value": "We appreciate your feedback. Can you please provide a description of the issue you're experiencing and your email address so we can follow up with you?"}, {"key": "What is your policy on price adjustments?", "value": "We'd be happy to provide information on our price adjustment policy. Can you please provide the product name or SKU so we can give you the most accurate information?"}, {"key": "Do you have any upcoming sales or events?", "value": "We'd be happy to inform you of any upcoming sales or events. Can you please provide your email address so we can keep you updated?"}, {"key": "How do I schedule a consultation or appointment?", "value": "We'd be happy to help. Can you please provide your name, phone number, and the service you're interested in so we can schedule your appointment?"}, {"key": "Can I get a copy of my receipt?", "value": "Certainly. Can you please provide your order number or account email so we can locate your receipt and send you a copy?"}, {"key": "Can I use a competitor's coupon at your store?", "value": "In some cases, we may accept competitor coupons. Can you please provide the competitor's coupon code and the product name or SKU you'd like to apply it to?"}, {"key": "Do you have a recycling program?", "value": "Yes, we do have a recycling program. Can you please provide your email address so we can send you information on how to participate?"}, {"key": "How do I report a lost or stolen gift card?", "value": "We're sorry to hear that. Can you please provide the gift card number, if available, and your email address so we can assist you further?"}]}
潞晨科技是一家致力于“解放AI生产力”的全球性公司,技术团队核心成员来自美国加州伯克利、斯坦福、新加坡国立、南洋理工、清华、北大等国内外知名高校。在高性能计算、人工智能、分布式系统等方面已有十余年的技术积累,并在国际顶级学术刊物或会议发表论文近百篇。公司核心产品面向大模型时代的通用深度学习系统 Colossal-AI,可实现高效快速部署AI大模型训练和推理,降低AI大模型应用成本。公司在种子轮、天使轮融资已获得“清科中国早期投资机构30强”前三甲创新工场、真格基金、蓝驰创投的600万美元投资。
{
"data":[
{"content":"Donec lobortis eleifend condimentum. Cras dictum dolor lacinia lectus vehicula rutrum. Maecenas quis nisi nunc. Nam tristique feugiat est vitae mollis. Maecenas quis nisi nunc."},
{"content":"Aliquam sollicitudin ante ligula, eget malesuada nibh efficitur et. Pellentesque massa sem, scelerisque sit amet odio id, cursus tempor urna. Etiam congue dignissim volutpat. Vestibulum pharetra libero et velit gravida euismod."}
],
"name":"player"
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment