This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch CAMEL-24330-improve-ai-docs
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 661f7a370ce5a126ef0110e57ef4c9dfd5e305d9
Author: Claus Ibsen <[email protected]>
AuthorDate: Mon Aug 3 17:06:08 2026 +0200

    CAMEL-24330: Improve AI component documentation based on user feedback
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../src/main/docs/langchain4j-chat-component.adoc  |   2 +
 .../src/main/docs/openai-component.adoc            | 167 +++++++++++++++++++++
 components/camel-ai/src/main/docs/ai-summary.adoc  |  47 ++++++
 3 files changed, 216 insertions(+)

diff --git 
a/components/camel-ai/camel-langchain4j-chat/src/main/docs/langchain4j-chat-component.adoc
 
b/components/camel-ai/camel-langchain4j-chat/src/main/docs/langchain4j-chat-component.adoc
index 50f9812ae7bb..9ef1978ab813 100644
--- 
a/components/camel-ai/camel-langchain4j-chat/src/main/docs/langchain4j-chat-component.adoc
+++ 
b/components/camel-ai/camel-langchain4j-chat/src/main/docs/langchain4j-chat-component.adoc
@@ -29,6 +29,8 @@ for this component:
 </dependency>
 ----
 
+TIP: For a comparison of `camel-langchain4j-chat` vs `camel-openai` and 
guidance on which to choose, see xref:others:ai-summary.adoc[Choosing the Right 
AI Component]. If you need streaming responses, structured output 
(`outputClass` / `jsonSchema`), or MCP tool calling, see the 
xref:openai-component.adoc[OpenAI] component.
+
 == URI format
 
 ----
diff --git 
a/components/camel-ai/camel-openai/src/main/docs/openai-component.adoc 
b/components/camel-ai/camel-openai/src/main/docs/openai-component.adoc
index d95cf54ce139..928fbb335d93 100644
--- a/components/camel-ai/camel-openai/src/main/docs/openai-component.adoc
+++ b/components/camel-ai/camel-openai/src/main/docs/openai-component.adoc
@@ -1008,6 +1008,173 @@ String-valued fields are set directly. Non-string 
fields (numbers, booleans, obj
 
 NOTE: This maps fields from the response message's additional properties 
(fields not part of the standard schema). Standard response fields like 
`content`, `role`, and `tool_calls` are not accessible through this option.
 
+== Tips for Production Use
+
+This section covers practical advice for using the OpenAI component in 
production routes, based on common patterns and pitfalls.
+
+=== Temperature and Model Parameters
+
+The `temperature` endpoint option controls how deterministic the model's 
output is. Lower values produce more consistent, predictable responses; higher 
values produce more varied, creative output.
+
+For structured extraction tasks (JSON parsing, data extraction, 
classification), use a low temperature such as `0.1` to reduce the chance of 
the model adding unexpected commentary or formatting around the structured 
output:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:extract-skills")
+    
.to("openai:chat-completion?temperature=0.1&outputClass=com.example.SkillList")
+    .log("Extracted: ${body}");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:extract-skills
+      steps:
+        - to:
+            uri: openai:chat-completion
+            parameters:
+              temperature: 0.1
+              outputClass: com.example.SkillList
+        - log:
+            message: "Extracted: ${body}"
+----
+====
+
+Temperature can also be set per-exchange via the `CamelOpenAITemperature` 
header. Other tuning options include `topP` (nucleus sampling) and `maxTokens` 
(response length limit).
+
+=== Dynamic Prompts
+
+The `CamelOpenAIUserMessage` header is evaluated per-exchange, so you can 
construct prompts dynamically using Camel's Simple language or any other 
expression:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("direct:summarize")
+    .setHeader("CamelOpenAIUserMessage",
+        simple("Summarize this ${header.documentType} in 3 bullet points: 
${body}"))
+    .to("openai:chat-completion")
+    .log("Summary: ${body}");
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: direct:summarize
+      steps:
+        - setHeader:
+            name: CamelOpenAIUserMessage
+            simple: "Summarize this ${header.documentType} in 3 bullet points: 
${body}"
+        - to:
+            uri: openai:chat-completion
+        - log:
+            message: "Summary: ${body}"
+----
+====
+
+This is useful when chaining multiple enrichment steps where each step needs a 
different instruction based on the current exchange state.
+
+=== Use Structured Output for JSON Extraction
+
+When you need the model to return structured data (JSON objects, arrays, typed 
fields), prefer the built-in `outputClass` or `jsonSchema` options over 
manually parsing the model's text output. These options instruct the model to 
produce valid JSON matching your schema, which significantly reduces parsing 
failures:
+
+[source,java]
+----
+// Recommended — structured output handles JSON formatting:
+from("direct:extract")
+    .to("openai:chat-completion?outputClass=com.example.Skills")
+    .log("${body}");
+
+// Avoid — manual JSON parsing is fragile:
+from("direct:extract")
+    .setHeader("CamelOpenAIUserMessage",
+        constant("Extract skills as a JSON array. Respond with valid JSON 
only."))
+    .to("openai:chat-completion")
+    .process(exchange -> {
+        // This breaks when the model adds commentary around the JSON
+        String json = exchange.getIn().getBody(String.class);
+        List<String> skills = objectMapper.readValue(json, new 
TypeReference<>() {});
+        exchange.getIn().setBody(skills);
+    });
+----
+
+See the <<Structured Output with outputClass>> and <<Structured Output with 
JSON Schema>> sections above for full examples. For additional validation, pipe 
the response through the `camel-json-validator` component.
+
+=== Handling Model Output Errors
+
+A successful HTTP 200 response from the model does not guarantee the content 
is usable. The model may ignore formatting instructions, return truncated 
output, or produce content that does not match your expected shape. These are 
not Camel exceptions — they appear as downstream parsing failures in your own 
processors.
+
+For production routes, add a lightweight validation step after the model call:
+
+[source,java]
+----
+from("direct:extract")
+    .to("openai:chat-completion?outputClass=com.example.Result")
+    .process(exchange -> {
+        String response = exchange.getIn().getBody(String.class);
+        if (response == null || response.isBlank()) {
+            throw new IllegalStateException("Empty model response");
+        }
+    })
+    .to("direct:downstream");
+----
+
+Using `outputClass` or `jsonSchema` already reduces this risk substantially by 
constraining the model's output format at the API level.
+
+=== Prompt Management
+
+When your project grows beyond a few routes, keeping prompt strings inline in 
route definitions becomes hard to maintain. Consider these approaches:
+
+*Load prompts from resource files:*
+
+[source,java]
+----
+from("direct:analyze")
+    .setHeader("CamelOpenAISystemMessage",
+        constant("resource:classpath:prompts/system-analyst.txt"))
+    .to("openai:chat-completion");
+----
+
+*Use Camel property placeholders for reusable fragments:*
+
+[source,properties]
+----
+# application.properties
+prompt.system.analyst=You are a technical analyst. Be concise and factual.
+prompt.output.json=Respond with valid JSON only, no commentary.
+----
+
+[source,java]
+----
+from("direct:analyze")
+    .setHeader("CamelOpenAISystemMessage", 
constant("{{prompt.system.analyst}}"))
+    .setHeader("CamelOpenAIUserMessage",
+        simple("{{prompt.output.json}} Analyze: ${body}"))
+    .to("openai:chat-completion");
+----
+
+TIP: For prompt templates with named variables (e.g., `{{dishType}}`), the 
xref:langchain4j-chat-component.adoc[LangChain4j Chat] component offers 
built-in template support via the `CHAT_SINGLE_MESSAGE_WITH_PROMPT` operation.
+
+=== Streaming Considerations
+
+The `streaming=true` option returns an `Iterator<ChatCompletionChunk>` that 
can be consumed with Camel's Split EIP (see the <<Streaming Response>> section 
above). This works well for pipeline-style processing where each chunk is 
handled as part of a longer integration flow.
+
+For user-facing scenarios that require Server-Sent Events (SSE) or WebSocket 
delivery to a browser, consider whether the Camel route is the right place to 
handle the streaming lifecycle. In some cases, a dedicated async handler with 
SSE transport provides tighter control over connection management and 
backpressure. Camel can still orchestrate the overall pipeline while delegating 
the streaming-to-client step to purpose-built infrastructure.
+
+NOTE: When MCP tools with `autoToolExecution` are active, streaming 
automatically falls back to non-streaming to allow the agentic tool-calling 
loop to function. See xref:others:openai-mcp.adoc[MCP Tool Calling] for details.
+
 == Sub-Pages
 
 For more details on specific features, see:
diff --git a/components/camel-ai/src/main/docs/ai-summary.adoc 
b/components/camel-ai/src/main/docs/ai-summary.adoc
index 678447db0eba..9ee37f057dca 100644
--- a/components/camel-ai/src/main/docs/ai-summary.adoc
+++ b/components/camel-ai/src/main/docs/ai-summary.adoc
@@ -4,6 +4,53 @@
 The Camel AI components are a group of components for applying Apache Camel to
 various AI-related technologies.
 
+== Choosing the Right AI Component
+
+Camel offers two main paths for integrating Large Language Models (LLMs) into 
routes:
+
+* **xref:openai-component.adoc[OpenAI]** — talks directly to OpenAI and any 
OpenAI-compatible API (OpenRouter, Ollama, vLLM, LM Studio). Native support for 
streaming, structured output (`outputClass` / `jsonSchema`), MCP tool calling, 
conversation memory, and the Responses API. Best when you are committed to the 
OpenAI ecosystem or using an OpenAI-compatible gateway.
+
+* **xref:langchain4j-chat-component.adoc[LangChain4j Chat]** — abstracts 
through https://github.com/langchain4j/langchain4j[LangChain4j] so you can 
switch LLM providers (OpenAI, Anthropic, Google Gemini, Mistral, Ollama, and 
others) by swapping a dependency. Also provides prompt templates with 
variables, RAG integration via the Content Enricher pattern, and multi-message 
conversation history.
+
+[cols="2,1,1"]
+|===
+| Need | camel-openai | camel-langchain4j-chat
+
+| OpenAI or compatible API (OpenRouter, Ollama, vLLM)
+| Yes
+| Via LangChain4j provider
+
+| Switch providers without code changes
+| No (OpenAI-compatible only)
+| Yes
+
+| MCP tool calling / agentic loops
+| Yes
+| No (use xref:langchain4j-tools-component.adoc[langchain4j-tools] instead)
+
+| Streaming responses
+| Yes
+| Manual (via `StreamingChatLanguageModel`)
+
+| Structured output (JSON schema)
+| Yes (`outputClass`, `jsonSchema`)
+| No
+
+| Prompt templates with variables
+| No (use Simple expressions)
+| Yes (built-in `{{variable}}` syntax)
+
+| RAG pipelines
+| Manual
+| Yes (with `LangChain4jRagAggregatorStrategy`)
+
+| Embeddings
+| Yes
+| Via 
xref:langchain4j-embeddingstore-component.adoc[langchain4j-embeddingstore]
+|===
+
+TIP: If you already use an OpenAI-compatible API and want the richest feature 
set (streaming, MCP, structured output), start with `camel-openai`. If 
multi-provider flexibility is a hard requirement, use `camel-langchain4j-chat`. 
Both can coexist in the same project.
+
 == {doctitle} components
 
 See the following for usage of each component:

Reply via email to