Federico Mariani created CAMEL-24767:
----------------------------------------

             Summary: 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


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)

Reply via email to