Skip to content

Commit

Permalink
fix: LLM hallucinations answer "content=I understood..."
Browse files Browse the repository at this point in the history
  • Loading branch information
clemlesne committed Dec 11, 2024
1 parent 854f165 commit 9e24660
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 9 deletions.
3 changes: 1 addition & 2 deletions app/helpers/call_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
MessageModel,
PersonaEnum as MessagePersonaEnum,
extract_message_style,
remove_message_action,
)
from app.models.next import NextModel
from app.models.synthesis import SynthesisModel
Expand Down Expand Up @@ -636,7 +635,7 @@ def _validate(req: str | None) -> tuple[bool, str | None, str | None]:
)

# Delete action and style from the message as they are in the history and LLM hallucinates them
_, content = extract_message_style(remove_message_action(content or ""))
_, content = extract_message_style(content or "")

if not content:
logger.warning("Error generating SMS report")
Expand Down
7 changes: 2 additions & 5 deletions app/helpers/call_llm.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
StyleEnum as MessageStyleEnum,
ToolModel as MessageToolModel,
extract_message_style,
remove_message_action,
)

_db = CONFIG.database.instance()
Expand Down Expand Up @@ -454,7 +453,7 @@ async def _plugin_tts_callback(text: str) -> None:

async def _content_callback(buffer: str) -> None:
# Remove tool calls from buffer content and detect style
style, local_content = extract_message_style(remove_message_action(buffer))
style, local_content = extract_message_style(buffer)
await tts_callback(local_content, style)

# Build RAG
Expand Down Expand Up @@ -543,9 +542,7 @@ async def _content_callback(buffer: str) -> None:
tool_calls = [tool_call for _, tool_call in tool_calls_buffer.items()]

# Delete action and style from the message as they are in the history and LLM hallucinates them
last_style, content_full = extract_message_style(
remove_message_action(content_full)
)
last_style, content_full = extract_message_style(content_full)

logger.debug("Completion response: %s", content_full)
logger.debug("Completion tools: %s", tool_calls)
Expand Down
25 changes: 23 additions & 2 deletions app/models/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,11 @@ def to_openai(
return res


def remove_message_action(text: str) -> str:
def _filter_action(text: str) -> str:
"""
Remove action from content. AI often adds it by mistake event if explicitly asked not to.
Remove action from content.
AI often adds it by mistake event if explicitly asked not to.
Example:
- Input: "action=talk Hello!"
Expand All @@ -182,6 +184,19 @@ def remove_message_action(text: str) -> str:
return text


def _filter_content(text: str) -> str:
"""
Remove content from text.
AI often adds it by mistake event if explicitly asked not to.
Example:
- Input: "content=Hello!"
- Output: "Hello!"
"""
return text.replace("content=", "")


def extract_message_style(text: str) -> tuple[StyleEnum, str]:
"""
Detect the style of a message and extract it from the text.
Expand All @@ -190,6 +205,11 @@ def extract_message_style(text: str) -> tuple[StyleEnum, str]:
- Input: "style=cheerful Hello!"
- Output: (StyleEnum.CHEERFUL, "Hello!")
"""
# Apply hallucination filters
text = _filter_action(text)
text = _filter_content(text)

# Extract style
default_style = StyleEnum.NONE
res = re.match(_MESSAGE_STYLE_R, text)
if not res:
Expand All @@ -199,6 +219,7 @@ def extract_message_style(text: str) -> tuple[StyleEnum, str]:
StyleEnum(res.group(1)), # style
(res.group(2) or ""), # content
)

# Regex failed, return original text
except ValueError:
return default_style, text

0 comments on commit 9e24660

Please sign in to comment.