Saving pipelines as YAML
dumps writes a pipeline's components, settings and connections as YAML; loads rebuilds it. Loading refuses classes from modules you have not allowed.
yaml_text = pipeline.dumps()
print(yaml_text)Each component is saved as its class path and its __init__ parameters, and connections as sender and receiver socket names. Custom components get this without extra code when their __init__ arguments are simple values.
saved = rag.dumps()
loaded = Pipeline.loads(saved)Rebuilding a pipeline imports and creates the classes named in the file, so a YAML file from someone else could run any code. Haystack only loads classes from its own modules unless you allow more. shop_chat is your module, so name it:
loaded = Pipeline.loads(rag.dumps(), allowed_modules=["shop_chat"])
print(list(loaded.graph.nodes))
question = "When do parcels ship?"
print(loaded.run({"retriever": {"query": question}, "prompt": {"question": question}, "answer": {"query": question}})["answer"]["answers"][0].data)The loaded pipeline has the same components and answers the same way. The documents are not in the YAML: the retriever's store is saved as its settings and its index id. An InMemoryDocumentStore keeps documents in memory shared by index for the whole process, so the loaded store found them. In a new process the same YAML gives an empty store; a database-backed store would still have them.
unsafe=True turns the check off. Keep it off for files from users or the internet.- Save to a file with
pipeline.dump(open("rag.yaml", "w"))and read it back withPipeline.load. - Add a parameter to
ShopChat.__init__and look for it in the YAML. - Set the
HAYSTACK_DESERIALIZATION_ALLOWLISTenvironment variable instead ofallowed_modules.
Every expert started right here.