一、問題
我們希望實(shí)現(xiàn)人們通過自然的口語對話來使用大模型應(yīng)用。然而,在口語表達(dá)需求和意圖時(shí),人們往往會(huì)遇到一些問題。例如,表達(dá)過于簡略或含糊,容易引發(fā)語義歧義,導(dǎo)致大模型產(chǎn)生誤解;
用戶的問題可能包含許多隱含要素,但表達(dá)的信息卻不足,智能通過多輪對話逐步補(bǔ)全;
理想情況:通過大模型多次主動(dòng)與用戶溝通,不斷收集信息,完善對用戶真實(shí)意圖的理解,補(bǔ)全執(zhí)行用戶需求所需的各項(xiàng)參數(shù)

理想情況
二、示例代碼
import json
from langchain_core.output_parsers import StrOutputParser, JsonOutputParser
from langchain_core.prompts import PromptTemplate, ChatPromptTemplate
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.runnables import RunnableWithMessageHistory
from Common import get_dashscopeModel
llm = get_dashscopeModel()
user_input = str(input("請輸入你的需求:"))
# 根據(jù)用戶要求,進(jìn)行意圖識(shí)別,獲取對應(yīng)的模板
# 示例業(yè)務(wù)模板
templates = {
"訂機(jī)票":[
{
"paramsKey":"start",
"paramsName":"起點(diǎn)"
},
{
"paramsKey":"end",
"paramsName":"終點(diǎn)"
},
{
"paramsKey":"date",
"paramsName":"日期"
},
{
"paramsKey":"people",
"paramsName":"人數(shù)"
},
{
"paramsKey":"level",
"paramsName":"座位等級"
},
{
"paramsKey":"preference",
"paramsName":"座位偏好"
}
],
"訂酒店":["城市", "入住日期", "離店日期", "人數(shù)", "房型"]
}
# 意圖識(shí)別提示詞模板
input_prompt = PromptTemplate(
input_variables=["user_input","template"],
template="根據(jù)用戶輸入'{user_input}',選擇最合適的業(yè)務(wù)模板??捎脴I(yè)務(wù)模板有:{templates}。請返回模板名稱。"
)
intent_chain = input_prompt | llm | StrOutputParser()
# 意圖識(shí)別
intent = intent_chain.invoke({"user_input":user_input, "templates":str(list(templates.keys()))})
print(f"意圖識(shí)別結(jié)果:{intent}")
# 獲取對應(yīng)的模板
select_template = templates.get( intent)
print(f"選擇的模板為:{select_template}")
# 根據(jù)用戶意圖選擇的模板,進(jìn)行參數(shù)識(shí)別
# 補(bǔ)充信息提示模板{",".join(select_template)}
info_prompt = f"""
請根據(jù)用戶原始問題和模板,判斷原始問題是否完善。
如果問題缺乏需要的信息,請生成一個(gè)友好的請求,明確指出需要補(bǔ)充的信息,嚴(yán)格按照模板指出的參數(shù),不要添加其他信息。
若問題完善后,返回包含所有信息的完整問題。
### 原始問題
{user_input}
### 模板
{select_template}
### 輸出示例
{{
"isComplete": true,
"content":"完整問題",
"data":{{
"intent":"訂機(jī)票",
"params":收集到的select_template內(nèi)的參數(shù)paramsKey作為鍵值,值為用戶輸入的參數(shù)值
}}
}}
{{
"isComplete": false,
"content":"友好的引導(dǎo)用戶補(bǔ)充需要的信息",
"data":{{}}
}}
"""
# 歷史記錄
chat_history = ChatMessageHistory()
# 聊天模板
prompt = ChatPromptTemplate.from_messages(
[
("system","你是一個(gè)信息補(bǔ)充助手,任務(wù)是分析用戶問題是否完善"),
("human", "{history}"), # 歷史消息
("human", "{input}")
]
)
# 補(bǔ)充消息鏈
info_chain = prompt | llm | StrOutputParser()
#自動(dòng)處理歷史記錄,將記錄注入輸入并在每次調(diào)用后更新它
with_message_history = RunnableWithMessageHistory(
info_chain,
lambda session_id:chat_history,
input_messages_key="input",
history_messages_key="history"
)
# 判斷問題是否完整,如果不完整則返回引導(dǎo)信息
info_request = with_message_history.invoke({"input":info_prompt},config={"configurable":{"session_id":"unused"}})
parser = JsonOutputParser()
json_data = parser.parse(info_request)
print(json_data)
# 循環(huán)判斷是否完整,并提交用戶補(bǔ)充信息
while json_data.get("isComplete", False) is False:
try:
# 顯示引導(dǎo)信息并等待用戶輸入,用\033[1;33m和\033[0m設(shè)置和重置文本顏色及樣式(黃色加粗)
user_answer = input(f"\033[1;33m{json_data['content']}\033[0m\n請補(bǔ)充:")
info_request = with_message_history.invoke(
input={"input":user_answer},
config={"configurable":{"session_id":"unused"}}
)
# 解析結(jié)果
json_data = parser.parse(info_request)
except json.JSONDecodeError as e:
print("\033[1;31m[錯(cuò)誤] AI返回了無效的JSON格式,請重試\033[0m")
continue
except KeyError as e:
print("\033[1;31m[錯(cuò)誤] 響應(yīng)格式異常,正在終止流程\033[0m")
break
# 輸出最終結(jié)果
print(f"\033[1;32m[最終查詢] {info_request}\033[0m")

輸出結(jié)果