Skip to content

fix: skip KB retrieval for blank prompts#8073

Merged
RC-CHN merged 1 commit into
AstrBotDevs:masterfrom
he-yufeng:fix/kb-blank-prompt-8070
May 8, 2026
Merged

fix: skip KB retrieval for blank prompts#8073
RC-CHN merged 1 commit into
AstrBotDevs:masterfrom
he-yufeng:fix/kb-blank-prompt-8070

Conversation

@he-yufeng
Copy link
Copy Markdown
Contributor

@he-yufeng he-yufeng commented May 7, 2026

Fixes #8070.

Summary

  • Skip non-agentic knowledge-base retrieval when the provider prompt is blank or whitespace-only.
  • Add a regression test so image-only or sticker messages do not send an empty query to retrieval.

To verify

  • python -m pytest tests\unit\test_astr_main_agent.py::TestApplyKb -q
  • python -m ruff check astrbot\core\astr_main_agent.py tests\unit\test_astr_main_agent.py
  • python -m ruff format --check astrbot\core\astr_main_agent.py tests\unit\test_astr_main_agent.py
  • python -m py_compile astrbot\core\astr_main_agent.py tests\unit\test_astr_main_agent.py

Summary by Sourcery

Skip non-agentic knowledge base retrieval when provider prompts are blank or whitespace-only and add regression coverage for this behavior.

Bug Fixes:

  • Prevent knowledge base retrieval from being invoked when the provider prompt is blank or contains only whitespace.

Tests:

  • Add async regression tests ensuring knowledge base retrieval is skipped and system prompts are unchanged for blank or whitespace-only prompts.

@auto-assign auto-assign Bot requested review from Soulter and anka-afk May 7, 2026 23:32
@dosubot dosubot Bot added size:XS This PR changes 0-9 lines, ignoring generated files. area:core The bug / feature is about astrbot's core, backend feature:knowledge-base The bug / feature is about knowledge base labels May 7, 2026
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="tests/unit/test_astr_main_agent.py" line_range="345-360" />
<code_context>

         assert req.system_prompt == "System"

+    @pytest.mark.asyncio
+    @pytest.mark.parametrize("prompt", ["", "   \n\t"])
+    async def test_apply_kb_blank_prompt(self, prompt, mock_event, mock_context):
+        """Test applying knowledge base when prompt is blank."""
+        module = ama
+        req = ProviderRequest(prompt=prompt, system_prompt="System")
+        config = module.MainAgentBuildConfig(
+            tool_call_timeout=60, kb_agentic_mode=False
+        )
+        retrieve = AsyncMock(return_value="KB result")
+
+        with patch("astrbot.core.astr_main_agent.retrieve_knowledge_base", retrieve):
+            await module._apply_kb(mock_event, req, mock_context, config)
+
+        retrieve.assert_not_awaited()
+        assert req.system_prompt == "System"
+
     @pytest.mark.asyncio
</code_context>
<issue_to_address>
**suggestion (testing):** Add a test case for prompts with surrounding whitespace that should still trigger KB retrieval

To fully exercise the new `strip()` condition, please add a case like `"  hello  "` where the prompt is non-empty after stripping. That test should assert `retrieve_knowledge_base` is awaited and receives the original prompt, confirming we don’t skip retrieval when only leading/trailing whitespace is present.

```suggestion
    @pytest.mark.asyncio
    @pytest.mark.parametrize("prompt", ["", "   \n\t"])
    async def test_apply_kb_blank_prompt(self, prompt, mock_event, mock_context):
        """Test applying knowledge base when prompt is blank."""
        module = ama
        req = ProviderRequest(prompt=prompt, system_prompt="System")
        config = module.MainAgentBuildConfig(
            tool_call_timeout=60, kb_agentic_mode=False
        )
        retrieve = AsyncMock(return_value="KB result")

        with patch("astrbot.core.astr_main_agent.retrieve_knowledge_base", retrieve):
            await module._apply_kb(mock_event, req, mock_context, config)

        retrieve.assert_not_awaited()
        assert req.system_prompt == "System"

    @pytest.mark.asyncio
    async def test_apply_kb_prompt_with_surrounding_whitespace(
        self, mock_event, mock_context
    ):
        """Test applying knowledge base when prompt has surrounding whitespace but is non-empty."""
        module = ama
        prompt = "  hello  "
        req = ProviderRequest(prompt=prompt, system_prompt="System")
        config = module.MainAgentBuildConfig(
            tool_call_timeout=60, kb_agentic_mode=False
        )
        retrieve = AsyncMock(return_value="KB result")

        with patch("astrbot.core.astr_main_agent.retrieve_knowledge_base", retrieve):
            await module._apply_kb(mock_event, req, mock_context, config)

        retrieve.assert_awaited_once_with(mock_event, req, mock_context, config)
        # Ensure we passed the original prompt object through to retrieval
        assert req.prompt == prompt
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +345 to +360
@pytest.mark.asyncio
@pytest.mark.parametrize("prompt", ["", " \n\t"])
async def test_apply_kb_blank_prompt(self, prompt, mock_event, mock_context):
"""Test applying knowledge base when prompt is blank."""
module = ama
req = ProviderRequest(prompt=prompt, system_prompt="System")
config = module.MainAgentBuildConfig(
tool_call_timeout=60, kb_agentic_mode=False
)
retrieve = AsyncMock(return_value="KB result")

with patch("astrbot.core.astr_main_agent.retrieve_knowledge_base", retrieve):
await module._apply_kb(mock_event, req, mock_context, config)

retrieve.assert_not_awaited()
assert req.system_prompt == "System"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Add a test case for prompts with surrounding whitespace that should still trigger KB retrieval

To fully exercise the new strip() condition, please add a case like " hello " where the prompt is non-empty after stripping. That test should assert retrieve_knowledge_base is awaited and receives the original prompt, confirming we don’t skip retrieval when only leading/trailing whitespace is present.

Suggested change
@pytest.mark.asyncio
@pytest.mark.parametrize("prompt", ["", " \n\t"])
async def test_apply_kb_blank_prompt(self, prompt, mock_event, mock_context):
"""Test applying knowledge base when prompt is blank."""
module = ama
req = ProviderRequest(prompt=prompt, system_prompt="System")
config = module.MainAgentBuildConfig(
tool_call_timeout=60, kb_agentic_mode=False
)
retrieve = AsyncMock(return_value="KB result")
with patch("astrbot.core.astr_main_agent.retrieve_knowledge_base", retrieve):
await module._apply_kb(mock_event, req, mock_context, config)
retrieve.assert_not_awaited()
assert req.system_prompt == "System"
@pytest.mark.asyncio
@pytest.mark.parametrize("prompt", ["", " \n\t"])
async def test_apply_kb_blank_prompt(self, prompt, mock_event, mock_context):
"""Test applying knowledge base when prompt is blank."""
module = ama
req = ProviderRequest(prompt=prompt, system_prompt="System")
config = module.MainAgentBuildConfig(
tool_call_timeout=60, kb_agentic_mode=False
)
retrieve = AsyncMock(return_value="KB result")
with patch("astrbot.core.astr_main_agent.retrieve_knowledge_base", retrieve):
await module._apply_kb(mock_event, req, mock_context, config)
retrieve.assert_not_awaited()
assert req.system_prompt == "System"
@pytest.mark.asyncio
async def test_apply_kb_prompt_with_surrounding_whitespace(
self, mock_event, mock_context
):
"""Test applying knowledge base when prompt has surrounding whitespace but is non-empty."""
module = ama
prompt = " hello "
req = ProviderRequest(prompt=prompt, system_prompt="System")
config = module.MainAgentBuildConfig(
tool_call_timeout=60, kb_agentic_mode=False
)
retrieve = AsyncMock(return_value="KB result")
with patch("astrbot.core.astr_main_agent.retrieve_knowledge_base", retrieve):
await module._apply_kb(mock_event, req, mock_context, config)
retrieve.assert_awaited_once_with(mock_event, req, mock_context, config)
# Ensure we passed the original prompt object through to retrieval
assert req.prompt == prompt

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a check to skip knowledge base retrieval when the prompt is empty or contains only whitespace, along with a new unit test to verify this behavior. A review comment suggests that because this check is performed after prompt decoration, it might still trigger retrieval if a prefix or default summary prompt has been added, recommending that the check be performed on the original user prompt instead.

) -> None:
if not config.kb_agentic_mode:
if req.prompt is None:
if req.prompt is None or not req.prompt.strip():
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The check for blank prompts is a valid improvement to avoid unnecessary knowledge base queries. However, it's worth noting that _apply_kb is called after _decorate_llm_request in build_main_agent. If a prompt_prefix is configured or if _apply_file_extract has set a default summary prompt (e.g., "总结一下文件里面讲了什么?"), req.prompt will no longer be blank or whitespace-only at this point. This means KB retrieval might still be triggered with these placeholder or prefix strings. Consider if the check should ideally happen against the original user prompt before decoration.

@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label May 8, 2026
@RC-CHN RC-CHN merged commit 116c66b into AstrBotDevs:master May 8, 2026
21 checks passed
murphys7017 pushed a commit to murphys7017/AstrBot that referenced this pull request May 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:core The bug / feature is about astrbot's core, backend feature:knowledge-base The bug / feature is about knowledge base lgtm This PR has been approved by a maintainer size:XS This PR changes 0-9 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] 开启知识库后,发送纯图片/表情包会导致 Embedding 接口报错 400 (The parameter is invalid)

2 participants