You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs-website/docs/concepts/concepts-overview.mdx
+1-4Lines changed: 1 addition & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -19,10 +19,7 @@ Working on this level with Haystack components is a hands-on approach. Component
19
19
20
20
#### Generators
21
21
22
-
[Generators](../pipeline-components/generators.mdx) are responsible for generating text responses after you give them a prompt. They are specific for each LLM technology (OpenAI, Cohere, local models, and others). There are two types of Generators: chat and non-chat:
23
-
24
-
- The chat ones enable chat completion and are designed for conversational contexts. It expects a list of messages to interact with the user.
25
-
- The non-chat Generators use LLMs for simpler text generation (for example, translating or summarizing text).
22
+
[Generators](../pipeline-components/generators.mdx) are responsible for generating text responses after you give them a prompt. They are specific for each LLM technology (OpenAI, Cohere, local models, and others). Haystack core ships ChatGenerators: they enable chat completion and are designed for conversational contexts, expecting a list of Chat Messages to interact with the user. For simpler text generation (for example, translating or summarizing text), they also accept a plain string prompt.
26
23
27
24
Read more about various Generators in our [guides](../pipeline-components/generators/guides-to-generators/choosing-the-right-generator.mdx).
Copy file name to clipboardExpand all lines: docs-website/docs/concepts/pipelines.mdx
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -44,7 +44,7 @@ See [Pipeline Loops](pipelines/pipeline-loops.mdx) for a deeper explanation of h
44
44
45
45
### Async Execution and Streaming
46
46
47
-
Pipelines execute components in parallel when their dependencies allow it. This improves performance in complex pipelines with independent operations. For example, a pipeline can run multiple Retrievers or LLM calls simultaneously, execute independent pipeline branches in parallel, and efficiently handle I/O-bound operations that would otherwise cause delays. You can cap the number of components running at the same time with the `concurrency_limit`init parameter.
47
+
When run asynchronously, pipelines execute components in parallel when their dependencies allow it. This improves performance in complex pipelines with independent operations. For example, a pipeline can run multiple Retrievers or LLM calls simultaneously, execute independent pipeline branches in parallel, and efficiently handle I/O-bound operations that would otherwise cause delays. You can cap the number of components running at the same time with the `concurrency_limit`argument of the async run methods (`run_async`, `run_async_generator`, and `stream`). The synchronous `run` method executes components sequentially.
48
48
49
49
Besides the blocking `run` method, every pipeline offers three ways to run asynchronously:
Copy file name to clipboardExpand all lines: docs-website/docs/development/logging.mdx
+19-2Lines changed: 19 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -74,7 +74,24 @@ Here’s what the resulting log would look like when a pipeline is run:
74
74
75
75
Haystack leverages the [structlog library](https://www.structlog.org/en/stable/) to provide structured key-value logs. This provides additional metadata with each log message and is especially useful if you archive your logs with tools like [ELK](https://www.elastic.co/de/elastic-stack), [Grafana](https://grafana.com/oss/agent/?plcmt=footer), or [Datadog](https://www.datadoghq.com/).
76
76
77
-
If Haystack detects a [structlog installation](https://www.structlog.org/en/stable/) on your system, it will automatically switch to structlog for logging.
77
+
If Haystack detects a [structlog installation](https://www.structlog.org/en/stable/) on your system, it installs a structlog-based formatting handler on import - but only for Haystack's own logger namespaces (`haystack`, `haystack_integrations`, and `haystack_experimental`). The root logger and the process-global structlog configuration are left untouched, so importing Haystack does not change how your application or other libraries log.
78
+
79
+
### Scoping and Duplicate Log Lines
80
+
81
+
You can adjust this behavior with an explicit `configure_logging` call:
82
+
83
+
-`configure_logging(logger_name="")` attaches the formatting handler to the root logger instead, restoring the legacy behavior of formatting every log record in the process.
84
+
-`configure_logging(propagate=False)` stops Haystack's log records from propagating to ancestor loggers. Use this to avoid duplicate log lines when your application also configures a handler on the root logger.
85
+
86
+
```python
87
+
from haystack.logging import configure_logging
88
+
89
+
# Format all log records in the process (legacy behavior)
90
+
configure_logging(logger_name="")
91
+
92
+
# Avoid duplicate log lines when the host app configures the root logger
93
+
configure_logging(propagate=False)
94
+
```
78
95
79
96
### Console Rendering
80
97
@@ -102,4 +119,4 @@ We recommend JSON logging when deploying Haystack to production. Haystack will a
102
119
103
120
### Disabling Structured Logging
104
121
105
-
To disable structured logging despite an existing installation of structlog, set the environment variable `HAYSTACK_LOGGING_IGNORE_STRUCTLOG_ENV_VAR` to `true` when running Haystack.
122
+
To disable structured logging despite an existing installation of structlog, set the environment variable `HAYSTACK_LOGGING_IGNORE_STRUCTLOG` to `true` when running Haystack.
Copy file name to clipboardExpand all lines: docs-website/docs/development/tracing/opentelemetry.mdx
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -28,8 +28,8 @@ Learn how to trace your Haystack pipelines with OpenTelemetry.
28
28
29
29
[OpenTelemetry](https://opentelemetry.io/) is an open-source observability framework for collecting traces, metrics, and logs. Haystack integrates with OpenTelemetry, so you can send traces of your pipeline runs to any OpenTelemetry-compatible backend.
30
30
31
-
:::info[Moving to an integration]
32
-
`OpenTelemetryTracer`is deprecated in Haystack core and is moving to the `opentelemetry-haystack` package. Starting with Haystack 3.0, OpenTelemetry tracing is no longer auto-enabled when `opentelemetry-sdk` is installed. Install the integration and either enable the `OpenTelemetryTracer` directly or add the `OpenTelemetryConnector` component to your pipeline.
31
+
:::info[Provided by an integration]
32
+
`OpenTelemetryTracer`lives in the `opentelemetry-haystack` package and is not part of Haystack core. Since Haystack 3.0, OpenTelemetry tracing is no longer auto-enabled when `opentelemetry-sdk` is installed. Install the integration and either enable the `OpenTelemetryTracer` directly or add the `OpenTelemetryConnector` component to your pipeline.
Copy file name to clipboardExpand all lines: docs-website/docs/overview/faq.mdx
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -41,4 +41,4 @@ The ZIP file contains documentation for all minor releases from version 1.0 to 1
41
41
42
42
To download documentation for a specific release, replace the version number in the following URL: `https://core-engineering.s3.eu-central-1.amazonaws.com/public/docs/v1.26.zip`.
43
43
44
-
Learn how to migrate to Haystack version 2.x with our [migration guide](migration.mdx).
44
+
Learn how to migrate to Haystack 3.x with our [migration guide](migration.mdx).
Both frameworks connect tools to the LLM, but with different APIs. In Haystack, tools are passed directly to the `ChatGenerator` component during initialization. In LangGraph, you first initialize the model, then bind tools using `.bind_tools()` to create a tool-enabled LLM instance.
152
+
The frameworks connect tools to the LLM differently. In Haystack, you only initialize the `ChatGenerator` component here: the tools are passed to the `Agent` in Step 3, which forwards them to the LLM. In LangGraph, you first initialize the model, then bind tools using `.bind_tools()` to create a tool-enabled LLM instance.
**Step 3: Set up message handling and LLM invocation**
179
+
**Step 3: Assemble the agent**
181
180
182
-
This is where the frameworks diverge more significantly. In Haystack you'll use a custom component (`MessageCollector`) to accumulate conversation history across the agentic loop. LangGraph instead defines a node function (`llm_call`) that operates on `MessagesState` - a built-in state container that automatically manages message history.
181
+
This is where the frameworks diverge most. In Haystack, you create the `Agent` component from the chat generator and tools - the agentic loop is built in. The Agent accumulates the conversation (LLM replies and tool results) internally, executes the tool calls prepared by the LLM, and iterates until an exit condition is met. The default `exit_conditions=["text"]` stops the loop as soon as the LLM replies without tool calls; tool names can also be used to exit after a specific tool runs.
182
+
183
+
In LangGraph, you build the loop explicitly: a node function (`llm_call`) that invokes the LLM on the accumulated `MessagesState`, a node function (`tool_node`) that executes tool calls and wraps the results in `ToolMessage` objects, and a conditional edge function (`should_continue`) that decides whether to continue the loop or finish. You then wire nodes and edges together in a `StateGraph` and compile the graph into an executable agent.
183
184
184
185
<divclassName="code-comparison">
185
186
<divclassName="code-comparison__column">
186
-
<CodeBlocklanguage="python"title="Haystack">{`from typing import Any, Dict, List
187
-
188
-
from haystack import component
189
-
from haystack.core.component.types import Variadic
190
-
from haystack.dataclasses import ChatMessage
191
-
192
-
# Components
193
-
194
-
# Custom component to temporarily store the messages
When the LLM decides to use a tool, it must be invoked and its result returned. Haystack provides a built-in `ToolInvoker` component that handles this automatically. LangGraph requires you to define a custom node function that iterates over tool calls, invokes each tool, and wraps the results in `ToolMessage` objects.
After the LLM responds, we need to decide whether to continue the loop (if tools were called) or finish (if the LLM provided a final answer). Haystack uses a `ConditionalRouter` component with declarative route conditions written in Jinja2 templates. LangGraph uses a conditional edge function (`should_continue`) that inspects the state and returns the next node or `END`.
# Decide if we should continue the loop or stop based upon whether the LLM made a tool call
288
-
289
-
messages = state["messages"]
290
-
last_message = messages[-1]
291
-
292
-
# If the LLM makes a tool call, then perform an action
230
+
last_message = state["messages"][-1]
293
231
if last_message.tool_calls:
294
232
return "tool_node"
295
-
296
-
# Otherwise, we stop (reply to the user)
297
-
return END`}</CodeBlock>
298
-
</div>
299
-
</div>
300
-
301
-
**Step 6: Assemble the workflow**
302
-
303
-
This is where you wire together all the components or nodes. Haystack uses a `Pipeline` where you explicitly add components and connect their inputs and outputs, creating a directed graph with loops. LangGraph uses a `StateGraph` where you add nodes and edges, then compile the graph into an executable agent. Both approaches achieve the same agentic loop, but with different levels of explicitness.
Finally, we execute the agent with a user message. Haystack calls `.run()` on the pipeline with initial messages, while LangGraph calls `.invoke()` on the compiled agent. Both return the conversation history.
258
+
Finally, we execute the agent with a user message. Haystack calls `.run()` on the Agent with initial messages, while LangGraph calls `.invoke()` on the compiled agent. Both return the conversation history.
352
259
353
260
<divclassName="code-comparison">
354
261
<divclassName="code-comparison__column">
355
-
<CodeBlocklanguage="python"title="Haystack">{`# Run the pipeline
356
-
messages = [
357
-
ChatMessage.from_system(text="You are a helpful assistant tasked with performing arithmetic on a set of inputs."),
@@ -375,7 +282,7 @@ for m in messages["messages"]:
375
282
376
283
### Creating Agents
377
284
378
-
The [Agentic Flows](#agentic-flows-with-haystack-vs-langgraph) walkthrough above showed how to assemble an agent loop manually from pipeline primitives. Haystack also provides a high-level `Agent` class that wraps the full loop - LLM calls, tool invocation, and iteration - into a single component. LangGraph offers an equivalent shortcut through `create_react_agent` in `langgraph.prebuilt`. Both produce a ReAct-style agent that handles tool calling and multi-step reasoning automatically.
285
+
The [Agentic Flows](#agentic-flows-with-haystack-vs-langgraph) walkthrough above stepped through the agent loop piece by piece. In Haystack, the high-level `Agent` class wraps the full loop - LLM calls, tool invocation, and iteration - into a single component. LangGraph offers an equivalent shortcut through `create_react_agent` in `langgraph.prebuilt`. Both produce a ReAct-style agent that handles tool calling and multi-step reasoning automatically. Here are the complete examples side by side:
0 commit comments