YAML Pipeline Deployment¶
Hayhooks supports deploying Haystack pipelines directly from YAML definitions. This approach builds request/response schemas automatically from the YAML-declared inputs and outputs.
Overview¶
YAML pipeline deployment is ideal for:
- Simple pipelines with clear inputs and outputs
- Quick deployment without wrapper code
- Automatic schema generation
- CI/CD pipeline deployments
Converting Existing Pipelines
If you already have a Haystack Pipeline instance, you can serialize it with pipeline.dumps() and then manually add the required inputs and outputs sections before deploying.
Requirements¶
YAML Structure¶
Your YAML file must include both inputs and outputs sections:
components:
fetcher:
type: haystack.components.fetchers.LinkContentFetcher
prompt_builder:
type: haystack.components.builders.PromptBuilder
init_parameters:
template: "Answer this question: {{query}} based on this content: {{documents}}"
llm:
type: haystack.components.generators.OpenAIGenerator
connections:
- sender: fetcher.content
receiver: prompt_builder.documents
- sender: prompt_builder
receiver: llm
inputs:
urls: fetcher.urls
query: prompt_builder.query
outputs:
replies: llm.replies
Key Requirements¶
inputsSection: Maps friendly names to pipeline component fieldsoutputsSection: Maps pipeline outputs to response fields- Valid Components: All components must be properly defined
- Valid Connections: All connections must reference existing components
Deployment Methods¶
# Deploy with default settings
hayhooks pipeline deploy-yaml pipelines/chat_pipeline.yml
# Deploy with custom name
hayhooks pipeline deploy-yaml -n my_chat_pipeline pipelines/chat_pipeline.yml
# Deploy with description
hayhooks pipeline deploy-yaml -n my_chat_pipeline --description "Chat pipeline for Q&A" pipelines/chat_pipeline.yml
# Overwrite existing pipeline
hayhooks pipeline deploy-yaml -n my_chat_pipeline --overwrite pipelines/chat_pipeline.yml
curl -X POST \
http://localhost:1416/deploy-yaml \
-H 'Content-Type: application/json' \
-d '{
"name": "my_chat_pipeline",
"description": "Chat pipeline for Q&A",
"yaml_content": "...",
"overwrite": false
}'
import requests
response = requests.post(
"http://localhost:1416/deploy-yaml",
json={
"name": "my_chat_pipeline",
"description": "Chat pipeline for Q&A",
"yaml_content": "...", # Your YAML content as string
"overwrite": False
}
)
print(response.json())
CLI Options¶
| Option | Short | Description | Default |
|---|---|---|---|
--name |
-n |
Override the pipeline name | YAML file stem |
--description |
Human-readable description | Pipeline name | |
--overwrite |
-o |
Overwrite if pipeline exists | false |
--skip-mcp |
Skip MCP tool registration | false |
|
--save-file |
Save YAML to server | true |
|
--no-save-file |
Don't save YAML to server | false |
Input/Output Mapping¶
Input Mapping¶
The inputs section maps friendly names to pipeline component fields:
inputs:
# friendly_name: component.field
urls: fetcher.urls
query: prompt_builder.query
Mapping rules:
- Use
component.fieldsyntax - Field must exist in the component
- Multiple inputs can map to the same component field
- Input names become API parameters
Output Mapping¶
The outputs section maps pipeline outputs to response fields:
outputs:
# response_field: component.field
replies: llm.replies
documents: fetcher.documents
metadata: prompt_builder.metadata
Mapping rules:
- Use
component.fieldsyntax - Field must exist in the component
- Response fields are serialized to JSON
- Complex objects are automatically serialized
Haystack Output Behavior
By default, Haystack only returns outputs from leaf components (components with no outgoing connections).
Hayhooks automatically extracts component names from your outputs mapping and passes them to Haystack's include_outputs_from parameter.
This ensures you get outputs from all declared components, including intermediate ones like retrievers.
Example:
outputs:
answers: llm.replies # Get LLM outputs
documents: retriever.documents # Also get retriever outputs (intermediate component)
Without this automatic behavior, you would only get llm.replies since the LLM is the leaf component. With it, you get both llm and retriever outputs as declared.
API Usage¶
After Deployment¶
Once deployed, your pipeline is available at:
- Run Endpoint:
/{pipeline_name}/run - Schema:
/{pipeline_name}/schema - OpenAPI:
/openapi.json
Example Request¶
curl -X POST \
http://localhost:1416/my_chat_pipeline/run \
-H 'Content-Type: application/json' \
-d '{
"urls": ["https://haystack.deepset.ai"],
"query": "What is Haystack?"
}'
Example Response¶
{
"replies": ["Haystack is an open source framework..."],
"documents": [...],
"metadata": {...}
}
Schema Generation¶
Hayhooks automatically generates:
Request Schema¶
{
"type": "object",
"properties": {
"urls": {
"type": "array",
"items": {"type": "string"}
},
"query": {"type": "string"}
},
"required": ["urls", "query"]
}
Response Schema¶
{
"type": "object",
"properties": {
"replies": {"type": "array"},
"documents": {"type": "array"},
"metadata": {"type": "object"}
}
}
Obtaining YAML from Existing Pipelines¶
You can obtain YAML from existing Haystack pipelines:
from haystack import Pipeline
# Create or load your pipeline
pipeline = Pipeline()
# ... add components and connections ...
# Get YAML representation
yaml_content = pipeline.dumps()
# Save to file
with open("pipeline.yml", "w") as f:
f.write(yaml_content)
Note
You'll need to manually add the inputs and outputs sections to the generated YAML.
Limitations¶
YAML Pipeline Limitations
YAML-deployed pipelines have the following limitations:
- No OpenAI Compatibility: Don't support OpenAI-compatible chat endpoints
- No Streaming: Streaming responses are not supported
- No File Uploads: File upload handling is not available
- Async Only: Pipelines are run as
AsyncPipelineinstances
Using PipelineWrapper for Advanced Features
For advanced features, use PipelineWrapper instead:
# For OpenAI compatibility
class PipelineWrapper(BasePipelineWrapper):
def run_chat_completion(self, model: str, messages: List[dict], body: dict) -> Union[str, Generator]:
...
# For file uploads
class PipelineWrapper(BasePipelineWrapper):
def run_api(self, files: Optional[List[UploadFile]] = None, query: str = "") -> str:
...
# For streaming
class PipelineWrapper(BasePipelineWrapper):
def run_chat_completion_async(self, model: str, messages: List[dict], body: dict) -> AsyncGenerator:
...
Example¶
For a complete working example of a YAML pipeline with proper inputs and outputs, see:
This example demonstrates:
- Complete pipeline structure with components and connections
- Proper
inputsmapping to component fields - Proper
outputsmapping from component results - Real-world usage with
LinkContentFetcher,HTMLToDocument,PromptBuilder, andOpenAIGenerator
Next Steps¶
- PipelineWrapper - For advanced features like streaming and chat completion
- Examples - See working examples