[
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. 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.
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. 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)