update
This commit is contained in:
@@ -500,16 +500,24 @@ function extractWineAttributes_1(a::T1, input::T2; maxattempt=10
|
||||
# responsedict = GeneralUtils.textToDict(response, header;
|
||||
# dictKey=dictkey, symbolkey=true)
|
||||
|
||||
removekeys = [:thought, :tasting_notes, :occasion, :food_to_be_paired_with_wine, :vintage]
|
||||
for i in removekeys
|
||||
delete!(responsedict, i)
|
||||
end
|
||||
|
||||
|
||||
|
||||
delete!(responsedict, :thought)
|
||||
delete!(responsedict, :tasting_notes)
|
||||
delete!(responsedict, :occasion)
|
||||
delete!(responsedict, :food_to_be_paired_with_wine)
|
||||
delete!(responsedict, :vintage)
|
||||
|
||||
# check if winery, wine_name, region, country, wine_type, grape_varietal's value are in the query because sometime AI halucinates
|
||||
checkFlag = false
|
||||
for i in requiredKeys
|
||||
j = Symbol(i)
|
||||
if j ∉ [:thought, :tasting_notes, :occasion, :food_to_be_paired_with_wine]
|
||||
if j ∉ removekeys
|
||||
# in case j is wine_price it needs to be checked differently because its value is ranged
|
||||
if j == :wine_price
|
||||
if responsedict[:wine_price] != "N/A"
|
||||
@@ -592,7 +600,7 @@ function extractWineAttributes_2(a::T1, input::T2)::String where {T1<:agent, T2<
|
||||
|
||||
conversiontable =
|
||||
"""
|
||||
<Conversion Table>
|
||||
<conversion_table>
|
||||
Intensity level:
|
||||
1 to 2: May correspond to "light-bodied" or a similar description.
|
||||
2 to 3: May correspond to "med light bodied", "medium light" or a similar description.
|
||||
@@ -617,16 +625,16 @@ function extractWineAttributes_2(a::T1, input::T2)::String where {T1<:agent, T2<
|
||||
3 to 4: May correspond to "medium acidity" or a similar description.
|
||||
4 to 5: May correspond to "semi high acidity" or a similar description.
|
||||
4 to 5: May correspond to "high acidity" or a similar description.
|
||||
</Conversion Table>
|
||||
</conversion_table>
|
||||
"""
|
||||
|
||||
systemmsg =
|
||||
"""
|
||||
As an helpful sommelier, your task is to fill out the user's preference form based on the corresponding words from the user's query.
|
||||
|
||||
At each round of conversation, the user will give you the current situation:
|
||||
Conversion Table: ...
|
||||
User's query: ...
|
||||
At each round of conversation, you will be given the following information:
|
||||
conversion_table: a conversion table that maps descriptive words to their corresponding integer levels
|
||||
query: the words from the user's query that describe their preferences
|
||||
|
||||
The preference form requires the following information:
|
||||
sweetness, acidity, tannin, intensity
|
||||
@@ -637,86 +645,109 @@ function extractWineAttributes_2(a::T1, input::T2)::String where {T1<:agent, T2<
|
||||
2) Use the conversion table to convert the descriptive word level of sweetness, intensity, tannin, and acidity into a corresponding integer.
|
||||
3) Do not generate other comments.
|
||||
You should then respond to the user with:
|
||||
Sweetness_keyword: The exact keywords in the user's query describing the sweetness level of the wine.
|
||||
Sweetness: ( S ), where ( S ) represents integers indicating the range of sweetness levels. Example: 1-2
|
||||
Acidity_keyword: The exact keywords in the user's query describing the acidity level of the wine.
|
||||
Acidity: ( A ), where ( A ) represents integers indicating the range of acidity level. Example: 3-5
|
||||
Tannin_keyword: The exact keywords in the user's query describing the tannin level of the wine.
|
||||
Tannin: ( T ), where ( T ) represents integers indicating the range of tannin level. Example: 1-3
|
||||
Intensity_keyword: The exact keywords in the user's query describing the intensity level of the wine.
|
||||
Intensity: ( I ), where ( I ) represents integers indicating the range of intensity level. Example: 2-4
|
||||
You should only respond in format as described below:
|
||||
Sweetness_keyword: ...
|
||||
Sweetness: ...
|
||||
Acidity_keyword: ...
|
||||
Acidity: ...
|
||||
Tannin_keyword: ...
|
||||
Tannin: ...
|
||||
Intensity_keyword: ...
|
||||
Intensity: ...
|
||||
sweetness_keyword: The exact keywords in the user's query describing the sweetness level of the wine.
|
||||
sweetness: ( S ), where ( S ) represents integers indicating the range of sweetness levels. Example: 1-2
|
||||
acidity_keyword: The exact keywords in the user's query describing the acidity level of the wine.
|
||||
acidity: ( A ), where ( A ) represents integers indicating the range of acidity level. Example: 3-5
|
||||
tannin_keyword: The exact keywords in the user's query describing the tannin level of the wine.
|
||||
tannin: ( T ), where ( T ) represents integers indicating the range of tannin level. Example: 1-3
|
||||
intensity_keyword: The exact keywords in the user's query describing the intensity level of the wine.
|
||||
intensity: ( I ), where ( I ) represents integers indicating the range of intensity level. Example: 2-4
|
||||
You should only respond in JSON format as described below:
|
||||
{
|
||||
"sweetness_keyword": "...",
|
||||
"sweetness": "...",
|
||||
"acidity_keyword": "...",
|
||||
"acidity": "...",
|
||||
"tannin_keyword": "...",
|
||||
"tannin": "...",
|
||||
"intensity_keyword": "...",
|
||||
"intensity": "..."
|
||||
}
|
||||
|
||||
Here are some examples:
|
||||
User's query: I want a wine with a medium-bodied, low acidity, medium tannin.
|
||||
Sweetness_keyword: N/A
|
||||
Sweetness: N/A
|
||||
Acidity_keyword: low acidity
|
||||
Acidity: 1-2
|
||||
Tannin_keyword: medium tannin
|
||||
Tannin: 3-4
|
||||
Intensity_keyword: medium-bodied
|
||||
Intensity: 3-4
|
||||
{
|
||||
"sweetness_keyword": "N/A",
|
||||
"sweetness": "N/A",
|
||||
"acidity_keyword": "low acidity",
|
||||
"acidity": 1-2,
|
||||
"tannin_keyword": "medium tannin",
|
||||
"tannin": 3-4,
|
||||
"intensity_keyword": "medium-bodied",
|
||||
"intensity": 3-4
|
||||
}
|
||||
|
||||
User's query: German red wine, under 100, pairs with spicy food
|
||||
Sweetness_keyword: N/A
|
||||
Sweetness: N/A
|
||||
Acidity_keyword: N/A
|
||||
Acidity: N/A
|
||||
Tannin_keyword: N/A
|
||||
Tannin: N/A
|
||||
Intensity_keyword: N/A
|
||||
Intensity: N/A
|
||||
{
|
||||
"sweetness_keyword": "N/A",
|
||||
"sweetness": "N/A",
|
||||
"acidity_keyword": "N/A",
|
||||
"acidity": "N/A",
|
||||
"tannin_keyword": "N/A",
|
||||
"tannin": "N/A",
|
||||
"intensity_keyword": "N/A",
|
||||
"intensity": "N/A"
|
||||
}
|
||||
|
||||
Let's begin!
|
||||
"""
|
||||
header = ["Sweetness_keyword:", "Sweetness:", "Acidity_keyword:", "Acidity:", "Tannin_keyword:", "Tannin:", "Intensity_keyword:", "Intensity:"]
|
||||
dictkey = ["sweetness_keyword", "sweetness", "acidity_keyword", "acidity", "tannin_keyword", "tannin", "intensity_keyword", "intensity"]
|
||||
requiredKeys = [:sweetness_keyword, :sweetness, :acidity_keyword, :acidity, :tannin_keyword, :tannin, :intensity_keyword, :intensity]
|
||||
|
||||
# header = ["Sweetness_keyword:", "Sweetness:", "Acidity_keyword:", "Acidity:", "Tannin_keyword:", "Tannin:", "Intensity_keyword:", "Intensity:"]
|
||||
# dictkey = ["sweetness_keyword", "sweetness", "acidity_keyword", "acidity", "tannin_keyword", "tannin", "intensity_keyword", "intensity"]
|
||||
errornote = "N/A"
|
||||
|
||||
for attempt in 1:10
|
||||
usermsg =
|
||||
context =
|
||||
"""
|
||||
$conversiontable
|
||||
User's query: $input
|
||||
<query>
|
||||
$input
|
||||
</query>
|
||||
P.S. $errornote
|
||||
/no_think
|
||||
"""
|
||||
|
||||
_prompt =
|
||||
unformatPrompt =
|
||||
[
|
||||
Dict(:name=> "system", :text=> systemmsg),
|
||||
Dict(:name=> "user", :text=> usermsg)
|
||||
]
|
||||
|
||||
# put in model format
|
||||
prompt = GeneralUtils.formatLLMtext(_prompt, a.llmFormatName)
|
||||
prompt = GeneralUtils.formatLLMtext(unformatPrompt, a.llmFormatName)
|
||||
# add info
|
||||
prompt = prompt * context
|
||||
|
||||
response = a.func[:text2textInstructLLM](prompt)
|
||||
response = a.func[:text2textInstructLLM](prompt; modelsize="medium", senderId=a.id)
|
||||
response = GeneralUtils.deFormatLLMtext(response, a.llmFormatName)
|
||||
response = GeneralUtils.remove_french_accents(response)
|
||||
think, response = GeneralUtils.extractthink(response)
|
||||
|
||||
# check whether response has all answer's key points
|
||||
detected_kw = GeneralUtils.detect_keyword(header, response)
|
||||
if 0 ∈ values(detected_kw)
|
||||
errornote = "In your previous attempt does not have all answer's key points"
|
||||
println("\nERROR YiemAgent extractWineAttributes_2() Attempt $attempt $errornote ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
continue
|
||||
elseif sum(values(detected_kw)) > length(header)
|
||||
errornote = "In your previous attempt has duplicated answer's key points"
|
||||
println("\nERROR YiemAgent extractWineAttributes_2() Attempt $attempt $errornote ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
|
||||
responsedict = nothing
|
||||
try
|
||||
responsedict = copy(JSON3.read(response))
|
||||
catch
|
||||
println("\nERROR YiemAgent extractWineAttributes_2() failed to parse response: $response ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
continue
|
||||
end
|
||||
|
||||
responsedict = GeneralUtils.textToDict(response, header;
|
||||
dictKey=dictkey, symbolkey=true)
|
||||
# check whether all answer's key points are in responsedict
|
||||
_responsedictKey = keys(responsedict)
|
||||
responsedictKey = [i for i in _responsedictKey] # convert into a list
|
||||
is_requiredKeys_in_responsedictKey = [i ∈ responsedictKey for i in requiredKeys]
|
||||
|
||||
if length(is_requiredKeys_in_responsedictKey) > length(requiredKeys)
|
||||
errornote = "Your previous attempt has more key points than answer's required key points."
|
||||
println("\nERROR YiemAgent extractWineAttributes_2() $errornote --> $response ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
continue
|
||||
elseif !all(is_requiredKeys_in_responsedictKey)
|
||||
zeroind = findall(x -> x == 0, is_requiredKeys_in_responsedictKey)
|
||||
missingkeys = [requiredKeys[i] for i in zeroind]
|
||||
errornote = "$missingkeys are missing from your previous response"
|
||||
println("\nERROR YiemAgent extractWineAttributes_2() $errornote --> $response ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
continue
|
||||
end
|
||||
|
||||
# check whether each describing keyword is in the input to prevent halucination
|
||||
for i in ["sweetness", "acidity", "tannin", "intensity"]
|
||||
|
||||
Reference in New Issue
Block a user