In the "agent chat" mode, if a knowledge base is configured, if I ask a question unrelated to the knowledge base such as "hello", then I don't see the knowledge base tool in the code. I have already configured the knowledge base #15214

Closed
opened 2026-02-21 19:20:41 -05:00 by yindo · 2 comments
Owner

Originally created by @orcharddd2024 on GitHub (Jul 9, 2025).

Self Checks

  • I have searched for existing issues search for existing issues, including closed ones.
  • I confirm that I am using English to submit report (我已阅读并同意 Language Policy).
  • [FOR CHINESE USERS] 请务必使用英文提交 Issue,否则会被关闭。谢谢!:)
  • Please do not modify this template :) and fill in all the required fields.

Provide a description of requested docs changes

In the "agent chat" mode, if a knowledge base is configured, if I ask a question unrelated to the knowledge base such as "hello", then I don't see the knowledge base tool in the code. However, why does the knowledge base tool automatically display when the problem involves knowledge base content?

Image Image

for dataset_tool in self.dataset_tools:
Here, when I ask the agent a question that is unrelated to the content of the knowledge base, such as "hello", it will display that dataset_tools is empty, but in fact, I have already configured the knowledge base before and there is data in the table; But when the questions I ask are related to the content of the knowledge base, and even actively ask the agent to answer based on the knowledge base, this self.dataset_tools will not be empty

Image Image

The configured knowledge base is shown in the table as shown in the figure

The key code is as follows
Image

Image

`class BaseAgentRunner(AppRunner):
def init(
self,
*,
tenant_id: str,
application_generate_entity: AgentChatAppGenerateEntity,
conversation: Conversation,
app_config: AgentChatAppConfig,
model_config: ModelConfigWithCredentialsEntity,
config: AgentEntity,
queue_manager: AppQueueManager,
message: Message,
user_id: str,
memory: Optional[TokenBufferMemory] = None,
prompt_messages: Optional[list[PromptMessage]] = None,
variables_pool: Optional[ToolRuntimeVariablePool] = None,
db_variables: Optional[ToolConversationVariables] = None,
model_instance: ModelInstance,
) -> None:
self.tenant_id = tenant_id
self.application_generate_entity = application_generate_entity
self.conversation = conversation
self.app_config = app_config
self.model_config = model_config
self.config = config
self.queue_manager = queue_manager
self.message = message
self.user_id = user_id
self.memory = memory
self.history_prompt_messages = self.organize_agent_history(prompt_messages=prompt_messages or [])
self.variables_pool = variables_pool
self.db_variables_pool = db_variables
self.model_instance = model_instance

    # init callback
    self.agent_callback = DifyAgentCallbackHandler()
    # init dataset tools
    hit_callback = DatasetIndexToolCallbackHandler(
        queue_manager=queue_manager,
        app_id=self.app_config.app_id,
        message_id=message.id,
        user_id=user_id,
        invoke_from=self.application_generate_entity.invoke_from,
    )
    self.dataset_tools = DatasetRetrieverTool.get_dataset_tools(
        tenant_id=tenant_id,
        dataset_ids=app_config.dataset.dataset_ids if app_config.dataset else [],
        retrieve_config=app_config.dataset.retrieve_config if app_config.dataset else None,
        return_resource=app_config.additional_features.show_retrieve_source,
        invoke_from=application_generate_entity.invoke_from,
        hit_callback=hit_callback,
    )
    # get how many agent thoughts have been created
    self.agent_thought_count = (
        db.session.query(MessageAgentThought)
        .filter(
            MessageAgentThought.message_id == self.message.id,
        )
        .count()
    )
    db.session.close()

    # check if model supports stream tool call
    llm_model = cast(LargeLanguageModel, model_instance.model_type_instance)
    model_schema = llm_model.get_model_schema(model_instance.model, model_instance.credentials)
    features = model_schema.features if model_schema and model_schema.features else []
    self.stream_tool_call = ModelFeature.STREAM_TOOL_CALL in features
    self.files = application_generate_entity.files if ModelFeature.VISION in features else []
    self.query: Optional[str] = ""
    self._current_thoughts: list[PromptMessage] = []

`

How is the knowledge base tool automatically called in "agent chat" mode? It seems like we haven't reached LLM yet, so we decided whether to use the knowledge base tool or not

Originally created by @orcharddd2024 on GitHub (Jul 9, 2025). ### Self Checks - [x] I have searched for existing issues [search for existing issues](https://github.com/langgenius/dify/issues), including closed ones. - [x] I confirm that I am using English to submit report (我已阅读并同意 [Language Policy](https://github.com/langgenius/dify/issues/1542)). - [x] [FOR CHINESE USERS] 请务必使用英文提交 Issue,否则会被关闭。谢谢!:) - [x] Please do not modify this template :) and fill in all the required fields. ### Provide a description of requested docs changes In the "agent chat" mode, if a knowledge base is configured, if I ask a question unrelated to the knowledge base such as "hello", then I don't see the knowledge base tool in the code. However, why does the knowledge base tool automatically display when the problem involves knowledge base content? <img width="1181" height="516" alt="Image" src="https://github.com/user-attachments/assets/7ff09d1f-73e2-42a5-8a18-5004d91af13b" /> <img width="1114" height="589" alt="Image" src="https://github.com/user-attachments/assets/4dc77688-748f-4610-a9ad-39b84a29fcae" /> for dataset_tool in self.dataset_tools: Here, when I ask the agent a question that is unrelated to the content of the knowledge base, such as "hello", it will display that dataset_tools is empty, but in fact, I have already configured the knowledge base before and there is data in the table; But when the questions I ask are related to the content of the knowledge base, and even actively ask the agent to answer based on the knowledge base, this self.dataset_tools will not be empty <img width="1019" height="724" alt="Image" src="https://github.com/user-attachments/assets/f34a8c47-354f-4510-ad64-ce5f9b82c443" /> <img width="499" height="427" alt="Image" src="https://github.com/user-attachments/assets/622fbe1b-a258-4e3f-869d-1ec8c8ad1cef" /> The configured knowledge base is shown in the table as shown in the figure The key code is as follows <img width="913" height="517" alt="Image" src="https://github.com/user-attachments/assets/13f137e7-ec5e-4677-9eee-dc1ec1ee8a09" /> <img width="1149" height="443" alt="Image" src="https://github.com/user-attachments/assets/851fffde-acbd-4dae-aa44-8d70e02287e6" /> `class BaseAgentRunner(AppRunner): def __init__( self, *, tenant_id: str, application_generate_entity: AgentChatAppGenerateEntity, conversation: Conversation, app_config: AgentChatAppConfig, model_config: ModelConfigWithCredentialsEntity, config: AgentEntity, queue_manager: AppQueueManager, message: Message, user_id: str, memory: Optional[TokenBufferMemory] = None, prompt_messages: Optional[list[PromptMessage]] = None, variables_pool: Optional[ToolRuntimeVariablePool] = None, db_variables: Optional[ToolConversationVariables] = None, model_instance: ModelInstance, ) -> None: self.tenant_id = tenant_id self.application_generate_entity = application_generate_entity self.conversation = conversation self.app_config = app_config self.model_config = model_config self.config = config self.queue_manager = queue_manager self.message = message self.user_id = user_id self.memory = memory self.history_prompt_messages = self.organize_agent_history(prompt_messages=prompt_messages or []) self.variables_pool = variables_pool self.db_variables_pool = db_variables self.model_instance = model_instance # init callback self.agent_callback = DifyAgentCallbackHandler() # init dataset tools hit_callback = DatasetIndexToolCallbackHandler( queue_manager=queue_manager, app_id=self.app_config.app_id, message_id=message.id, user_id=user_id, invoke_from=self.application_generate_entity.invoke_from, ) self.dataset_tools = DatasetRetrieverTool.get_dataset_tools( tenant_id=tenant_id, dataset_ids=app_config.dataset.dataset_ids if app_config.dataset else [], retrieve_config=app_config.dataset.retrieve_config if app_config.dataset else None, return_resource=app_config.additional_features.show_retrieve_source, invoke_from=application_generate_entity.invoke_from, hit_callback=hit_callback, ) # get how many agent thoughts have been created self.agent_thought_count = ( db.session.query(MessageAgentThought) .filter( MessageAgentThought.message_id == self.message.id, ) .count() ) db.session.close() # check if model supports stream tool call llm_model = cast(LargeLanguageModel, model_instance.model_type_instance) model_schema = llm_model.get_model_schema(model_instance.model, model_instance.credentials) features = model_schema.features if model_schema and model_schema.features else [] self.stream_tool_call = ModelFeature.STREAM_TOOL_CALL in features self.files = application_generate_entity.files if ModelFeature.VISION in features else [] self.query: Optional[str] = "" self._current_thoughts: list[PromptMessage] = [] ` How is the knowledge base tool automatically called in "agent chat" mode? It seems like we haven't reached LLM yet, so we decided whether to use the knowledge base tool or not
yindo added the 🐞 bug label 2026-02-21 19:20:41 -05:00
yindo closed this issue 2026-02-21 19:20:41 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Jul 9, 2025):

The knowledge base tool (dataset_tools) is initialized based on your app's configuration—if you have linked a knowledge base, the tool is available to the agent. However, whether the tool is actually used for a given query depends on the agent's reasoning loop, which is driven by the LLM.

When you ask a question like "hello" (unrelated to the knowledge base), the LLM doesn't see a reason to call the knowledge base tool, so it doesn't invoke it. For questions that are relevant to the knowledge base, the LLM decides to use the tool, and you see it being called in the workflow. This decision happens after the LLM receives the user's query and considers the available tools—it is not a pre-LLM routing step, but part of the agent's tool-augmented reasoning process. The dataset_tools list itself is populated at initialization, but actual usage is determined dynamically by the LLM's reasoning during the chat session, not by static code before the LLM runs.

You can see this logic in the way DatasetRetrieverTool is set up and called: the tool is always available if configured, but only invoked if the LLM decides it's relevant to the user's question, as part of the agent's reasoning loop after the LLM is reached (source).

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Join Discord Share on X

@dosubot[bot] commented on GitHub (Jul 9, 2025): <!-- Answer --> The knowledge base tool (dataset_tools) is initialized based on your app's configuration—if you have linked a knowledge base, the tool is available to the agent. However, whether the tool is actually used for a given query depends on the agent's reasoning loop, which is driven by the LLM. When you ask a question like "hello" (unrelated to the knowledge base), the LLM doesn't see a reason to call the knowledge base tool, so it doesn't invoke it. For questions that are relevant to the knowledge base, the LLM decides to use the tool, and you see it being called in the workflow. This decision happens after the LLM receives the user's query and considers the available tools—it is not a pre-LLM routing step, but part of the agent's tool-augmented reasoning process. The dataset_tools list itself is populated at initialization, but actual usage is determined dynamically by the LLM's reasoning during the chat session, not by static code before the LLM runs. You can see this logic in the way DatasetRetrieverTool is set up and called: the tool is always available if configured, but only invoked if the LLM decides it's relevant to the user's question, as part of the agent's reasoning loop after the LLM is reached [(source)](https://github.com/langgenius/dify/blob/18854264217f66726e6335fc2a0192636eeed208/api/core/tools/utils/dataset_retriever/dataset_retriever_tool.py). <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/c7cec78d-f295-4ec6-ae8a-67e28f0e7158?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/c7cec78d-f295-4ec6-ae8a-67e28f0e7158?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/c7cec78d-f295-4ec6-ae8a-67e28f0e7158?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/c7cec78d-f295-4ec6-ae8a-67e28f0e7158?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/c7cec78d-f295-4ec6-ae8a-67e28f0e7158?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/c7cec78d-f295-4ec6-ae8a-67e28f0e7158?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/c7cec78d-f295-4ec6-ae8a-67e28f0e7158?feedback_type=other)</sup>&nbsp;&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/langgenius/dify/issues/22094)
Author
Owner

@orcharddd2024 commented on GitHub (Jul 9, 2025):

The knowledge base tool (dataset_tools) is initialized based on your app's configuration—if you have linked a knowledge base, the tool is available to the agent. However, whether the tool is actually used for a given query depends on the agent's reasoning loop, which is driven by the LLM.

When you ask a question like "hello" (unrelated to the knowledge base), the LLM doesn't see a reason to call the knowledge base tool, so it doesn't invoke it. For questions that are relevant to the knowledge base, the LLM decides to use the tool, and you see it being called in the workflow. This decision happens after the LLM receives the user's query and considers the available tools—it is not a pre-LLM routing step, but part of the agent's tool-augmented reasoning process. The dataset_tools list itself is populated at initialization, but actual usage is determined dynamically by the LLM's reasoning during the chat session, not by static code before the LLM runs.

You can see this logic in the way DatasetRetrieverTool is set up and called: the tool is always available if configured, but only invoked if the LLM decides it's relevant to the user's question, as part of the agent's reasoning loop after the LLM is reached (source).

To reply, just mention @dosu.

How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Join Discord Share on X

ok 3Q I'm debugging it myself

@orcharddd2024 commented on GitHub (Jul 9, 2025): > The knowledge base tool (dataset_tools) is initialized based on your app's configuration—if you have linked a knowledge base, the tool is available to the agent. However, whether the tool is actually used for a given query depends on the agent's reasoning loop, which is driven by the LLM. > > When you ask a question like "hello" (unrelated to the knowledge base), the LLM doesn't see a reason to call the knowledge base tool, so it doesn't invoke it. For questions that are relevant to the knowledge base, the LLM decides to use the tool, and you see it being called in the workflow. This decision happens after the LLM receives the user's query and considers the available tools—it is not a pre-LLM routing step, but part of the agent's tool-augmented reasoning process. The dataset_tools list itself is populated at initialization, but actual usage is determined dynamically by the LLM's reasoning during the chat session, not by static code before the LLM runs. > > You can see this logic in the way DatasetRetrieverTool is set up and called: the tool is always available if configured, but only invoked if the LLM decides it's relevant to the user's question, as part of the agent's reasoning loop after the LLM is reached [(source)](https://github.com/langgenius/dify/blob/18854264217f66726e6335fc2a0192636eeed208/api/core/tools/utils/dataset_retriever/dataset_retriever_tool.py). > > _To reply, just mention [@dosu](https://go.dosu.dev/dosubot)._ > > How did I do? [Good](https://app.dosu.dev/response-feedback/c7cec78d-f295-4ec6-ae8a-67e28f0e7158?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/c7cec78d-f295-4ec6-ae8a-67e28f0e7158?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/c7cec78d-f295-4ec6-ae8a-67e28f0e7158?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/c7cec78d-f295-4ec6-ae8a-67e28f0e7158?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/c7cec78d-f295-4ec6-ae8a-67e28f0e7158?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/c7cec78d-f295-4ec6-ae8a-67e28f0e7158?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/c7cec78d-f295-4ec6-ae8a-67e28f0e7158?feedback_type=other)  [![Join Discord](https://camo.githubusercontent.com/d562c2df5e4567ea41d37f1d91a4da0839d8341037045b103b2da268998de17f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6a6f696e2d3538363546323f6c6f676f3d646973636f7264266c6f676f436f6c6f723d7768697465266c6162656c3d)](https://go.dosu.dev/discord-bot) [![Share on X](https://camo.githubusercontent.com/4649f705e2396d6f328dbc8e800a0509c9c17b3b20253b36706c393df124b93d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f582d73686172652d626c61636b)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/langgenius/dify/issues/22094) ok 3Q I'm debugging it myself
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langgenius/dify#15214