Skip to content

Commit 379df4a

Browse files
authored
feat: Warn users if Agent is called with only system messages (#9514)
* Add warning message and raise error in agent run method * Add tests * Add reno * Updates * Updates
1 parent 580683b commit 379df4a

3 files changed

Lines changed: 35 additions & 2 deletions

File tree

haystack/components/agents/agent.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from haystack.core.pipeline.pipeline import Pipeline
1313
from haystack.core.pipeline.utils import _deepcopy_with_exceptions
1414
from haystack.core.serialization import component_to_dict
15-
from haystack.dataclasses import ChatMessage
15+
from haystack.dataclasses import ChatMessage, ChatRole
1616
from haystack.dataclasses.streaming_chunk import StreamingCallbackT, select_streaming_callback
1717
from haystack.tools import Tool, Toolset, deserialize_tools_or_toolset_inplace, serialize_tools_or_toolset
1818
from haystack.utils.callable_serialization import deserialize_callable, serialize_callable
@@ -69,7 +69,7 @@ def __init__(
6969
max_agent_steps: int = 100,
7070
raise_on_tool_invocation_failure: bool = False,
7171
streaming_callback: Optional[StreamingCallbackT] = None,
72-
):
72+
) -> None:
7373
"""
7474
Initialize the agent component.
7575
@@ -237,13 +237,20 @@ def run(
237237
- "messages": List of all messages exchanged during the agent's run.
238238
- "last_message": The last message exchanged during the agent's run.
239239
- Any additional keys defined in the `state_schema`.
240+
:raises RuntimeError: If the Agent component wasn't warmed up before calling `run()`.
240241
"""
241242
if not self._is_warmed_up and hasattr(self.chat_generator, "warm_up"):
242243
raise RuntimeError("The component Agent wasn't warmed up. Run 'warm_up()' before calling 'run()'.")
243244

244245
if self.system_prompt is not None:
245246
messages = [ChatMessage.from_system(self.system_prompt)] + messages
246247

248+
if all(m.is_from(ChatRole.SYSTEM) for m in messages):
249+
logger.warning(
250+
"All messages provided to the Agent component are system messages. This is not recommended as the "
251+
"Agent will not perform any actions specific to user input. Consider adding user messages to the input."
252+
)
253+
247254
state = State(schema=self.state_schema, data=kwargs)
248255
state.set("messages", messages)
249256
component_visits = dict.fromkeys(["chat_generator", "tool_invoker"], 0)
@@ -332,13 +339,20 @@ async def run_async(
332339
- "messages": List of all messages exchanged during the agent's run.
333340
- "last_message": The last message exchanged during the agent's run.
334341
- Any additional keys defined in the `state_schema`.
342+
:raises RuntimeError: If the Agent component wasn't warmed up before calling `run_async()`.
335343
"""
336344
if not self._is_warmed_up and hasattr(self.chat_generator, "warm_up"):
337345
raise RuntimeError("The component Agent wasn't warmed up. Run 'warm_up()' before calling 'run_async()'.")
338346

339347
if self.system_prompt is not None:
340348
messages = [ChatMessage.from_system(self.system_prompt)] + messages
341349

350+
if all(m.is_from(ChatRole.SYSTEM) for m in messages):
351+
logger.warning(
352+
"All messages provided to the Agent component are system messages. This is not recommended as the "
353+
"Agent will not perform any actions specific to user input. Consider adding user messages to the input."
354+
)
355+
342356
state = State(schema=self.state_schema, data=kwargs)
343357
state.set("messages", messages)
344358
component_visits = dict.fromkeys(["chat_generator", "tool_invoker"], 0)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
enhancements:
3+
- |
4+
- If only system messages are provided as input a warning will be logged to the user indicating that this likely not intended and that they should probably also provide user messages.

test/components/agents/test_agent.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,21 @@ def test_run_not_warmed_up(self, weather_tool):
719719
with pytest.raises(RuntimeError, match="The component Agent wasn't warmed up."):
720720
agent.run([ChatMessage.from_user("What is the weather in Berlin?")])
721721

722+
def test_run_no_messages(self, monkeypatch):
723+
monkeypatch.setenv("OPENAI_API_KEY", "fake-key")
724+
chat_generator = OpenAIChatGenerator()
725+
agent = Agent(chat_generator=chat_generator, tools=[])
726+
agent.warm_up()
727+
result = agent.run([])
728+
assert result["messages"] == []
729+
730+
def test_run_only_system_prompt(self, caplog):
731+
chat_generator = MockChatGeneratorWithoutRunAsync()
732+
agent = Agent(chat_generator=chat_generator, tools=[], system_prompt="This is a system prompt.")
733+
agent.warm_up()
734+
_ = agent.run([])
735+
assert "All messages provided to the Agent component are system messages." in caplog.text
736+
722737
@pytest.mark.skipif(not os.environ.get("OPENAI_API_KEY"), reason="OPENAI_API_KEY not set")
723738
@pytest.mark.integration
724739
def test_run(self, weather_tool):

0 commit comments

Comments
 (0)