[
https://issues.apache.org/jira/browse/CAMEL-24767?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18115934#comment-18115934
]
Federico Mariani commented on CAMEL-24767:
------------------------------------------
h3. Tool search and remote MCP tools
Checked whether tools hosted on remote MCP servers are searchable, since Camel
wires MCP tools differently from {{ai-tool:}} route tools in all three
components. They are, in both frameworks, but for different reasons and with
one shared caveat.
*LangChain4j* - {{ToolService#createContext}} expands every non-dynamic
{{ToolProvider}} into {{availableTools}} first, then applies the search
service, then refreshes dynamic providers. {{McpToolProvider}} does not
override {{ToolProvider#isDynamic()}} (default {{false}}), so MCP tools are
expanded before the search gate and become searchable alongside route tools.
Note the ordering dependency: a provider returning {{isDynamic() == true}} is
refreshed *after* {{ToolSearchService#adjust}}, so its tools bypass the search
gate entirely and go straight into {{effectiveTools}}. Anything Camel adds as a
dynamic provider later would silently opt out of tool search.
*Spring AI* - {{ToolSearchToolCallingAdvisor}} indexes from
{{toolCallingManager.resolveToolDefinitions(toolOptions)}}, i.e. only what is
reachable through {{ToolCallingChatOptions}}. Camel registers MCP tools as a
{{ToolCallbackProvider}} on the request spec ({{SpringAiChatProducer}}), not on
the options builder - but {{DefaultChatClientUtils}} expands all request-level
providers into {{toolCallbacks}} before the advisor chain runs, so they are
indexed. The advisor also fingerprints the tool set per session and re-indexes
when it changes, which handles a remote server whose tool list changes between
requests.
*camel-openai* - MCP tools are pre-fetched into {{McpToolState}} and added to
the request alongside route tools, so a Camel-owned index can cover both by
construction.
*Caveat that applies to all three:* tool search reduces the tools sent to the
*model*, not the MCP {{tools/list}} round trip. Every MCP server is still
enumerated on each invocation so its tools can be indexed. Tool search saves
prompt tokens and improves selection accuracy; it does not reduce MCP
chattiness. For that, the existing {{mcpToolProviderFilter}} on the agent is
the right knob, and the two compose.
This strengthens the case for a shared index in {{camel-ai-tool}}: route tools
and MCP tools should rank against each other in one place, rather than route
tools being searchable while MCP tools are always-visible (or vice versa)
depending on which component is used.
_Claude Code on behalf of Croway_
> camel-ai-tool - reinstate tool search, shared by langchain4j-agent,
> spring-ai-chat and openai
> ---------------------------------------------------------------------------------------------
>
> Key: CAMEL-24767
> URL: https://issues.apache.org/jira/browse/CAMEL-24767
> Project: Camel
> Issue Type: Improvement
> Reporter: Federico Mariani
> Priority: Major
>
> h2. Context
> CAMEL-22851 added a native tool-search-tool to {{camel-langchain4j-tools}}
> (shipped in 4.18.0). It added an {{exposed}} URI option: with
> {{exposed=false}} a tool was not sent to the LLM on every request but placed
> in a searchable registry, and a {{toolSearchTool}} was auto-exposed so the
> LLM could discover it on demand.
> {{camel-langchain4j-tools}} was deprecated in 4.22 and removed in 4.23
> (commit 2a2b0e1bb71c), replaced by {{camel-ai-tool}} for tool definition and
> {{camel-langchain4j-agent}} for tool calling. The tool-search capability was
> *not* ported: {{AiToolConfiguration}} has no {{exposed}}/searchable
> equivalent, and none of the three AI producers that consume
> {{AiToolRegistry}} support tool search today.
> So the feature regressed out of the project as a side effect of the
> migration. The 4.22 and 4.23 upgrade guides document the
> {{langchain4j-tools:}} -> {{ai-tool:}} route migration but do not mention
> that {{exposed=false}} has no equivalent.
> h2. Why it matters
> All three producers select tools by {{tags}} and serialise every matching
> {{ai-tool:}} route into every request:
> * {{camel-langchain4j-agent}} - via {{AiToolSpecToLangChain4j}} /
> {{ToolProvider}}
> * {{camel-spring-ai-chat}} - {{SpringAiChatProducer#applyRequestOptions}}
> puts all tag-matched callbacks into {{ToolCallingChatOptions}}
> * {{camel-openai}} - {{OpenAIEndpoint}} lines 283/366
> With a broad tag over a large route catalogue this consumes a significant
> part of the context window on every call, and tool-selection accuracy
> degrades well before the context limit is reached.
> h2. Proposal
> Reinstate tool search in {{camel-ai-tool}}, which is the shared abstraction
> ({{AiToolRegistry}} / {{AiToolSpec}}), so the three consumers behave
> consistently rather than each inheriting whatever its upstream framework does:
> # Consumer side: an option on {{ai-tool:}} marking a tool searchable rather
> than always-visible (the {{exposed}} option from CAMEL-22851, or a clearer
> name).
> # Producer side: a {{toolSearch}} option on {{langchain4j-agent}},
> {{spring-ai-chat}} and {{openai}} enabling the search tool for that endpoint.
> # A scoring/index implementation over {{AiToolSpec}} in {{camel-ai-tool}}, so
> {{tags}} semantics and ranking are identical across the three.
> # Upgrade-guide entry noting the capability was absent between the removal
> and this change.
> h2. Framework support now available
> This did not exist when CAMEL-22851 was implemented (it was hand-rolled in
> Camel). Both frameworks now ship it, at versions Camel already depends on:
> * *LangChain4j 1.20.0* - {{dev.langchain4j.service.tool.search}}
> ({{@Experimental}}, since 1.12.0): {{ToolSearchStrategy}} with
> {{SimpleToolSearchStrategy}} (keyword) and {{VectorToolSearchStrategy}}
> (embeddings, needs only an {{EmbeddingModel}}), wired with
> {{AiServices.toolSearchStrategy(...)}}. Tools supplied through a
> {{ToolProvider}} - which is how Camel passes route tools - are searchable:
> {{ToolService#createContext}} builds {{availableTools}} from static tools and
> providers first, then applies the search service.
> {{AbstractAgent#configureBuilder}} already sets sibling options
> ({{maxToolCallingRoundTrips}}, {{hallucinatedToolNameStrategy}}), so this is
> a few lines. It is also reachable today without any Camel change through the
> existing {{AgentConfiguration#withAiServicesCustomizer}} escape hatch, which
> makes it easy to validate the behaviour before committing to an API.
> * *Spring AI 2.0.1* - {{spring-ai-tool-search-tool}} and
> {{spring-ai-tool-search-advisor}}: {{ToolIndex}} (regex, Lucene, vector
> store), {{ToolSearchToolCallingAdvisor}} with {{maxResults}} and
> session-scoped LRU/TTL eviction. Session scoping maps onto the existing
> {{CamelSpringAiChatConversationId}} header. Note this advisor extends
> {{ToolCallingAdvisor}}, which replaces the model-internal tool-calling loop -
> that is the main design consideration on this side.
> * *camel-openai* - no equivalent in the OpenAI Java SDK, but Camel owns the
> agentic loop already ({{maxToolIterations}}), so the search tool has to be
> driven directly. This is the strongest argument for putting the index in
> {{camel-ai-tool}}: it gives the OpenAI component an implementation to reuse
> instead of a bespoke one.
> h2. Open questions
> * Option naming, and whether searchable is opt-in on the tool
> ({{exposed=false}}, as in CAMEL-22851) or opt-in on the producer
> ({{toolSearch=true}}), or both.
> * Keyword matching (as the original implementation did, by tag) versus
> embedding-based semantic search, which both frameworks now offer.
> * Whether to delegate to each framework's native implementation, or keep a
> single Camel-owned index for consistent behaviour across the three
> components. The frameworks differ in how discovered tools persist:
> LangChain4j accumulates them through chat-memory message attributes, Spring
> AI through a session-scoped index with eviction.
> Prior art for the design is in commit 5ef1539bacbb (CAMEL-22851), in
> particular {{ToolSearchTool}} and the searchable registry in
> {{CamelToolExecutorCache}}.
> _Claude Code on behalf of Croway_
--
This message was sent by Atlassian Jira
(v8.20.10#820010)