[ 
https://issues.apache.org/jira/browse/CAMEL-21916?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Zineb Bendhiba updated CAMEL-21916:
-----------------------------------
    Description: 
LangChain4j [AI Services|https://docs.langchain4j.dev/tutorials/ai-services/] 
are the highest-level API of LangChain4j: one user-defined interface carrying 
the full feature set.
 
h3. Why this matters

The motivation is a component that supports everything LangChain4j offers, 
present and future, without wrapping it feature by feature. It also makes 
custom AiService interfaces easy to use from Camel, compared to the 
{{camel-langchain4j-agent}} component, whose contract is fixed by the component 
(an {{AgentFactory}} hook allows customization, at the price of extra 
complexity): here users bring their own domain interface, with their own method 
names, parameters and return types, and a route calls it as-is.

The existing {{camel-langchain4j-agent}} component builds the AI service 
internally: model, memory, tools and guardrails are configured through Camel 
options, so the component has to chase the {{AiServices}} builder surface 
option by option (see CAMEL-23950).

This feature inverts the ownership. The user defines the AiService the standard 
LangChain4j way (plain {{AiServices}} builder, or Quarkus 
{{{}@RegisterAiService{}}}), and LangChain4j deals with all the rest: the 
model, the system and user messages, chat memory, RAG (retrieval augmentors), 
tools and agentic behavior, guardrails, structured output. Whatever the user 
configures on the AiService works, with no Camel option needed for any of it, 
including LangChain4j features that do not exist yet. Camel just invokes it 
from a route:

 
{code:java}
from("kafka:inbox") 
    .to("langchain4j-ai-service:myAssistant?method=chat") 
    .to("kafka:ai-responses");{code}
 

The route is the orchestrator: messages arrive through any of Camel's 300+ 
connectors, the AI Service reasons, the route pushes the result onward. 
LangChain4j does the AI, Camel does the integration.

 
This works in both directions. Camel users get the full LangChain4j feature 
set. And LangChain4j AiService users get a new way to integrate the services 
they already have: Camel's 300+ connectors and enterprise integration patterns 
drive their existing interfaces, unchanged.
 
h3. Why not the bean component?

The generic {{bean}} component can also invoke a registered AiService, so the 
question is fair. But bean binding is AI-agnostic. A dedicated component brings 
what bean cannot:
 * AI-shaped invocation: the body maps to the user message, headers to the 
remaining parameters, memory id conventions.
 * Observability that follows the ownership: model-level GenAI telemetry 
(tokens, model, latency) comes from LangChain4j and its integrations (e.g. 
quarkus-langchain4j OpenTelemetry, LangFuse...), while the component tags the 
route-side span with the AI service name and the resolved method, so AI calls 
are recognizable in route traces. The bean component tags nothing AI-aware.
 * A natural home for AI-specific behavior: guardrail error mapping, 
moderation, streaming later.
 * A naming convention known in the LangChain4j space: "AI Service" is 
LangChain4j's own term for this API. A route reading 
{{langchain4j-ai-service:myAssistant?method=chat}} tells any LangChain4j user 
exactly what happens; {{bean:myAssistant}} says nothing.
 * Discoverability: it shows up as an AI component in the catalog, the docs and 
the tooling.
h3.  

 
h3. Decision

A new dedicated component, {{camel-langchain4j-ai-service}} (under 
{{{}components/camel-ai{}}}), rather than new options.

  was:
LangChain4j [AI Services|https://docs.langchain4j.dev/tutorials/ai-services/] 
are the highest-level API of LangChain4j: one user-defined interface carrying 
the full feature set.
 
h3. Why this matters

The motivation is a component that supports everything LangChain4j offers, 
present and future, without wrapping it feature by feature. It also makes 
custom AiService interfaces easy to use from Camel, compared to the 
{{camel-langchain4j-agent}} component, whose contract is fixed by the component 
(an {{AgentFactory}} hook allows customization, at the price of extra 
complexity): here users bring their own domain interface, with their own method 
names, parameters and return types, and a route calls it as-is.

The existing {{camel-langchain4j-agent}} component builds the AI service 
internally: model, memory, tools and guardrails are configured through Camel 
options, so the component has to chase the {{AiServices}} builder surface 
option by option (see CAMEL-23950).

This feature inverts the ownership. The user defines the AiService the standard 
LangChain4j way (plain {{AiServices}} builder, or Quarkus 
{{{}@RegisterAiService{}}}), and LangChain4j deals with all the rest: the 
model, the system and user messages, chat memory, RAG (retrieval augmentors), 
tools and agentic behavior, guardrails, structured output. Whatever the user 
configures on the AiService works, with no Camel option needed for any of it, 
including LangChain4j features that do not exist yet. Camel just invokes it 
from a route:

 
{code:java}
from("kafka:inbox") 
    .to("langchain4j-ai-service:myAssistant?method=chat") 
    .to("kafka:ai-responses");{code}
 

The route is the orchestrator: messages arrive through any of Camel's 300+ 
connectors, the AI Service reasons, the route pushes the result onward. 
LangChain4j does the AI, Camel does the integration.

 
This works in both directions. Camel users get the full LangChain4j feature 
set. And LangChain4j AiService users get a new way to integrate the services 
they already have: Camel's 300+ connectors and enterprise integration patterns 
drive their existing interfaces, unchanged.
 
h3. Why not the bean component?


The generic \{{bean}} component can also invoke a registered AiService, so the 
question is fair. But bean binding is AI-agnostic. A dedicated component brings 
what bean cannot:

* AI-shaped invocation: the body maps to the user message, headers to the 
remaining parameters, memory id conventions.
* Observability that follows the ownership: model-level GenAI telemetry 
(tokens, model, latency) comes from LangChain4j and its integrations (e.g. 
quarkus-langchain4j OpenTelemetry, LangFuse...), while the component tags the 
route-side span with the AI service name and the resolved method, so AI calls 
are recognizable in route traces. The bean component tags nothing AI-aware.
* A natural home for AI-specific behavior: guardrail error mapping, moderation, 
streaming later.
* A naming convention known in the LangChain4j space: "AI Service" is 
LangChain4j's own term for this API. A route reading 
\{{langchain4j-ai-service:myAssistant?method=chat}} tells any LangChain4j user 
exactly what happens; \{{bean:myAssistant}} says nothing.
* Discoverability: it shows up as an AI component in the catalog, the docs and 
the tooling.
h3. Decision

A new dedicated component, {{camel-langchain4j-ai-service}} (under 
{{{}components/camel-ai{}}}), rather than new options.


> camel-langchain4j - Add support for AI Services
> -----------------------------------------------
>
>                 Key: CAMEL-21916
>                 URL: https://issues.apache.org/jira/browse/CAMEL-21916
>             Project: Camel
>          Issue Type: New Feature
>          Components: camel-ai, camel-langchain4j
>    Affects Versions: 4.11.0
>            Reporter: Tadayoshi Sato
>            Assignee: Zineb Bendhiba
>            Priority: Major
>
> LangChain4j [AI Services|https://docs.langchain4j.dev/tutorials/ai-services/] 
> are the highest-level API of LangChain4j: one user-defined interface carrying 
> the full feature set.
>  
> h3. Why this matters
> The motivation is a component that supports everything LangChain4j offers, 
> present and future, without wrapping it feature by feature. It also makes 
> custom AiService interfaces easy to use from Camel, compared to the 
> {{camel-langchain4j-agent}} component, whose contract is fixed by the 
> component (an {{AgentFactory}} hook allows customization, at the price of 
> extra complexity): here users bring their own domain interface, with their 
> own method names, parameters and return types, and a route calls it as-is.
> The existing {{camel-langchain4j-agent}} component builds the AI service 
> internally: model, memory, tools and guardrails are configured through Camel 
> options, so the component has to chase the {{AiServices}} builder surface 
> option by option (see CAMEL-23950).
> This feature inverts the ownership. The user defines the AiService the 
> standard LangChain4j way (plain {{AiServices}} builder, or Quarkus 
> {{{}@RegisterAiService{}}}), and LangChain4j deals with all the rest: the 
> model, the system and user messages, chat memory, RAG (retrieval augmentors), 
> tools and agentic behavior, guardrails, structured output. Whatever the user 
> configures on the AiService works, with no Camel option needed for any of it, 
> including LangChain4j features that do not exist yet. Camel just invokes it 
> from a route:
>  
> {code:java}
> from("kafka:inbox") 
>     .to("langchain4j-ai-service:myAssistant?method=chat") 
>     .to("kafka:ai-responses");{code}
>  
> The route is the orchestrator: messages arrive through any of Camel's 300+ 
> connectors, the AI Service reasons, the route pushes the result onward. 
> LangChain4j does the AI, Camel does the integration.
>  
> This works in both directions. Camel users get the full LangChain4j feature 
> set. And LangChain4j AiService users get a new way to integrate the services 
> they already have: Camel's 300+ connectors and enterprise integration 
> patterns drive their existing interfaces, unchanged.
>  
> h3. Why not the bean component?
> The generic {{bean}} component can also invoke a registered AiService, so the 
> question is fair. But bean binding is AI-agnostic. A dedicated component 
> brings what bean cannot:
>  * AI-shaped invocation: the body maps to the user message, headers to the 
> remaining parameters, memory id conventions.
>  * Observability that follows the ownership: model-level GenAI telemetry 
> (tokens, model, latency) comes from LangChain4j and its integrations (e.g. 
> quarkus-langchain4j OpenTelemetry, LangFuse...), while the component tags the 
> route-side span with the AI service name and the resolved method, so AI calls 
> are recognizable in route traces. The bean component tags nothing AI-aware.
>  * A natural home for AI-specific behavior: guardrail error mapping, 
> moderation, streaming later.
>  * A naming convention known in the LangChain4j space: "AI Service" is 
> LangChain4j's own term for this API. A route reading 
> {{langchain4j-ai-service:myAssistant?method=chat}} tells any LangChain4j user 
> exactly what happens; {{bean:myAssistant}} says nothing.
>  * Discoverability: it shows up as an AI component in the catalog, the docs 
> and the tooling.
> h3.  
>  
> h3. Decision
> A new dedicated component, {{camel-langchain4j-ai-service}} (under 
> {{{}components/camel-ai{}}}), rather than new options.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to