	{"id":94492,"date":"2024-01-31T09:19:18","date_gmt":"2024-01-31T09:19:18","guid":{"rendered":"https:\/\/www.artefact.com\/?post_type=blog&#038;p=94492"},"modified":"2024-09-20T17:46:02","modified_gmt":"2024-09-20T16:46:02","slug":"unleashing-the-power-of-langchain-expression-language-lcel-from-proof-of-concept-to-production","status":"publish","type":"blog","link":"https:\/\/www.artefact.com\/de\/blog\/unleashing-the-power-of-langchain-expression-language-lcel-from-proof-of-concept-to-production\/","title":{"rendered":"Entfesseln der Kraft der LangChain Expression Language (LCEL): vom Proof of Concept zur Produktion"},"content":{"rendered":"<p><div class=\"fusion-fullwidth fullwidth-box fusion-builder-row-1 fusion-flex-container nonhundred-percent-fullwidth non-hundred-percent-height-scrolling article-author\" style=\"--awb-border-radius-top-left:0px;--awb-border-radius-top-right:0px;--awb-border-radius-bottom-right:0px;--awb-border-radius-bottom-left:0px;--awb-background-color:#ffffff;--awb-flex-wrap:wrap;\" ><div class=\"fusion-builder-row fusion-row fusion-flex-align-items-flex-start fusion-flex-content-wrap\" style=\"max-width:calc( 1440px + 20px );margin-left: calc(-20px \/ 2 );margin-right: calc(-20px \/ 2 );\"><div class=\"fusion-layout-column fusion_builder_column fusion-builder-column-0 fusion_builder_column_1_2 1_2 fusion-flex-column\" style=\"--awb-bg-size:cover;--awb-width-large:50%;--awb-margin-top-large:0px;--awb-spacing-right-large:10px;--awb-margin-bottom-large:0px;--awb-spacing-left-large:10px;--awb-width-medium:50%;--awb-order-medium:0;--awb-spacing-right-medium:10px;--awb-spacing-left-medium:10px;--awb-width-small:100%;--awb-order-small:0;--awb-spacing-right-small:10px;--awb-spacing-left-small:10px;\"><div class=\"fusion-column-wrapper fusion-column-has-shadow fusion-flex-justify-content-flex-start fusion-content-layout-column\"><div class=\"fusion-title title fusion-title-1 fusion-sep-none fusion-title-text fusion-title-size-two\" style=\"--awb-margin-bottom-small:8px;\"><h2 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:50;line-height:1.2;\">Author<\/h2><\/div><img decoding=\"async\" src=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%27150%27%20height%3D%270%27%20viewBox%3D%270%200%20150%200%27%3E%3Crect%20width%3D%27150%27%20height%3D%270%27%20fill-opacity%3D%220%22%2F%3E%3C%2Fsvg%3E\" data-orig-src=\"https:\/\/www.artefact.com\/\/wp-content\/uploads\/2023\/02\/Tom-Darmon-300x300.jpeg\" alt=\"Image\" class=\"lazyload artefact-elegant-image align-left article-author-image\" style=\"width: 150px; border-radius: 54% 46% 77% 23% \/ 74% 40% 60% 26%; overflow: hidden;\" width=\"150\" height=\"auto\" \/><div class=\"fusion-title title fusion-title-2 fusion-sep-none fusion-title-text fusion-title-size-three article-author-name-title\" style=\"--awb-text-color:var(--awb-color7);--awb-margin-bottom-small:8px;--awb-font-size:18px;\"><h3 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"font-family:&quot;Josefin Sans&quot;;font-style:normal;font-weight:600;margin:0;font-size:1em;--fontSize:18;line-height:1.5;\">Tom Darmon<\/h3><\/div><div class=\"fusion-text fusion-text-1 article-author-description\" style=\"--awb-font-size:14px;--awb-line-height:1.6;--awb-letter-spacing:2px;--awb-text-transform:uppercase;--awb-text-color:var(--awb-color7);--awb-text-font-family:&quot;Roboto&quot;;--awb-text-font-style:normal;--awb-text-font-weight:400;\"><p>Senior Data Scientist at Artefact France<\/p>\n<\/div><\/div><\/div><\/div><\/div><article class=\"fusion-fullwidth fullwidth-box fusion-builder-row-2 fusion-flex-container nonhundred-percent-fullwidth non-hundred-percent-height-scrolling\" style=\"--link_color: var(--awb-color6);--awb-border-radius-top-left:0px;--awb-border-radius-top-right:0px;--awb-border-radius-bottom-right:0px;--awb-border-radius-bottom-left:0px;--awb-background-color:var(--awb-color1);--awb-flex-wrap:wrap;\" ><div class=\"fusion-builder-row fusion-row fusion-flex-align-items-flex-start fusion-flex-justify-content-center fusion-flex-content-wrap\" style=\"max-width:calc( 1440px + 20px );margin-left: calc(-20px \/ 2 );margin-right: calc(-20px \/ 2 );\"><div class=\"fusion-layout-column fusion_builder_column fusion-builder-column-1 fusion_builder_column_1_1 1_1 fusion-flex-column\" style=\"--awb-bg-size:cover;--awb-width-large:100%;--awb-margin-top-large:0px;--awb-spacing-right-large:10px;--awb-margin-bottom-large:0px;--awb-spacing-left-large:10px;--awb-width-medium:100%;--awb-order-medium:0;--awb-spacing-right-medium:10px;--awb-spacing-left-medium:10px;--awb-width-small:100%;--awb-order-small:0;--awb-spacing-right-small:10px;--awb-spacing-left-small:10px;\"><div class=\"fusion-column-wrapper fusion-column-has-shadow fusion-flex-justify-content-flex-start fusion-content-layout-column\"><div class=\"fusion-title title fusion-title-3 fusion-sep-none fusion-title-text fusion-title-size-two\" style=\"--awb-text-color:var(--awb-color6);--awb-margin-bottom-small:8px;\"><h2 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:50;line-height:1.2;\">TL;DR<\/h2><\/div><ul style=\"--awb-iconcolor:#000000;--awb-textcolor:#000000;--awb-line-height:27.2px;--awb-icon-width:27.2px;--awb-icon-height:27.2px;--awb-icon-margin:11.2px;--awb-content-margin:38.4px;\" class=\"fusion-checklist fusion-checklist-1 fusion-checklist-default type-icons paddingList dark-text\"><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p><strong>Faster POC to prod<\/strong>: As langchain documentation describes it, &#8220;LCEL is a declarative way to easily compose chains together. LCEL was designed from day 1 to support putting prototypes in production, with no code change&#8221;.<\/p>\n<\/div><\/li><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p><strong>Custom chain creation<\/strong>: LCEL simplifies the process of creating custom chains with a new syntax.<\/p>\n<\/div><\/li><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p><strong>Out of the box streaming and batch<\/strong>: LCEL gives you batch, streaming and async capabilities for free.<\/p>\n<\/div><\/li><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p><strong>Unified interface<\/strong>: It offers automatic parallelization, typing capabilities, and any future feature LangChain might develop.<\/p>\n<\/div><\/li><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p><strong>LCEL is the future of LangChain<\/strong>: LCEL provides a fresh perspective on LLM-based application development. I highly recommended using it for your next LLM project.<\/p>\n<\/div><\/li><\/ul><div class=\"fusion-text fusion-text-2\" style=\"--awb-font-size:20px;--awb-line-height:1.6;--awb-letter-spacing:var(--awb-typography4-letter-spacing);--awb-text-transform:var(--awb-typography4-text-transform);--awb-text-color:var(--awb-color5);--awb-text-font-family:var(--awb-typography4-font-family);--awb-text-font-weight:var(--awb-typography4-font-weight);--awb-text-font-style:var(--awb-typography4-font-style);\"><p><strong>LangChain<\/strong> has become one of the most used <strong>Python library<\/strong> to interact with <strong>LLMs<\/strong> in less than a year, but LangChain was mostly a library for <strong>POCs<\/strong> as it lacked the ability to create <strong>complex and scalable applications<\/strong>.<br \/>\nEverything changed in August 2023 when they released <strong>LangChain Expression Language (LCEL)<\/strong>, a new syntax that bridges the gap from <strong>POC to production<\/strong>. This article will guide you through the ins and outs of LCEL, showing you how it simplifies the <strong>creation of custom chains<\/strong> and why you must learn it if you are building <strong>LLM applications<\/strong>!<\/p>\n<\/div><div class=\"fusion-title title fusion-title-4 fusion-sep-none fusion-title-text fusion-title-size-two\" style=\"--awb-text-color:var(--awb-color6);--awb-margin-bottom-small:8px;\"><h2 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:50;line-height:1.2;\">Prompts, LLM and chains, let\u2019s refresh our memory<\/h2><\/div><div class=\"fusion-text fusion-text-3\" style=\"--awb-font-size:20px;--awb-line-height:1.6;--awb-letter-spacing:var(--awb-typography4-letter-spacing);--awb-text-transform:var(--awb-typography4-text-transform);--awb-text-color:var(--awb-color5);--awb-text-font-family:var(--awb-typography4-font-family);--awb-text-font-weight:var(--awb-typography4-font-weight);--awb-text-font-style:var(--awb-typography4-font-style);\"><p>Before diving into the LCEL syntax, I think it is beneficial to refresh our memory on LangChain concepts such as LLM and Prompt or even a Chain.<\/p>\n<\/div><div class=\"fusion-text fusion-text-4\" style=\"--awb-font-size:20px;--awb-line-height:1.6;--awb-letter-spacing:var(--awb-typography4-letter-spacing);--awb-text-transform:var(--awb-typography4-text-transform);--awb-text-color:var(--awb-color5);--awb-text-font-family:var(--awb-typography4-font-family);--awb-text-font-weight:var(--awb-typography4-font-weight);--awb-text-font-style:var(--awb-typography4-font-style);\"><p><strong>LLM<\/strong>: In langchain, llm is an abstraction around the model used to make the completions such as openai gpt3.5, claude, etc\u2026<\/p>\n<\/div><div class=\"fusion-text fusion-text-5\" style=\"--awb-font-size:20px;--awb-line-height:1.6;--awb-letter-spacing:var(--awb-typography4-letter-spacing);--awb-text-transform:var(--awb-typography4-text-transform);--awb-text-color:var(--awb-color5);--awb-text-font-family:var(--awb-typography4-font-family);--awb-text-font-weight:var(--awb-typography4-font-weight);--awb-text-font-style:var(--awb-typography4-font-style);\"><p><strong>Prompt<\/strong>: This is the input of the LLM object, which will ask the LLM questions and give its objectives.<\/p>\n<\/div><div class=\"fusion-text fusion-text-6\" style=\"--awb-font-size:20px;--awb-line-height:1.6;--awb-letter-spacing:var(--awb-typography4-letter-spacing);--awb-text-transform:var(--awb-typography4-text-transform);--awb-text-color:var(--awb-color5);--awb-text-font-family:var(--awb-typography4-font-family);--awb-text-font-weight:var(--awb-typography4-font-weight);--awb-text-font-style:var(--awb-typography4-font-style);\"><p><strong>Chain<\/strong>: This refers to a sequence of calls to an LLM, or any data processing step.<\/p>\n<\/div><div class=\"fusion-image-element\" style=\"text-align:center;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);\"><span class=\" fusion-imageframe imageframe-none imageframe-1 hover-type-none\"><img decoding=\"async\" width=\"1270\" height=\"523\" title=\"visuel 1 article medium langchain\" src=\"https:\/\/www.artefact.com\/\/wp-content\/uploads\/2024\/01\/visuel-1-article-medium-langchain.png\" data-orig-src=\"https:\/\/www.artefact.com\/\/wp-content\/uploads\/2024\/01\/visuel-1-article-medium-langchain.png\" alt class=\"lazyload img-responsive wp-image-94493\" srcset=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%271270%27%20height%3D%27523%27%20viewBox%3D%270%200%201270%20523%27%3E%3Crect%20width%3D%271270%27%20height%3D%27523%27%20fill-opacity%3D%220%22%2F%3E%3C%2Fsvg%3E\" data-srcset=\"https:\/\/www.artefact.com\/\/wp-content\/uploads\/2024\/01\/visuel-1-article-medium-langchain-200x82.png 200w, https:\/\/www.artefact.com\/\/wp-content\/uploads\/2024\/01\/visuel-1-article-medium-langchain-400x165.png 400w, https:\/\/www.artefact.com\/\/wp-content\/uploads\/2024\/01\/visuel-1-article-medium-langchain-600x247.png 600w, https:\/\/www.artefact.com\/\/wp-content\/uploads\/2024\/01\/visuel-1-article-medium-langchain-800x329.png 800w, https:\/\/www.artefact.com\/\/wp-content\/uploads\/2024\/01\/visuel-1-article-medium-langchain-1200x494.png 1200w, https:\/\/www.artefact.com\/\/wp-content\/uploads\/2024\/01\/visuel-1-article-medium-langchain.png 1270w\" data-sizes=\"auto\" data-orig-sizes=\"(max-width: 640px) 100vw, 1270px\" \/><\/span><\/div><div class=\"fusion-text fusion-text-7\" style=\"--awb-font-size:20px;--awb-line-height:1.6;--awb-letter-spacing:var(--awb-typography4-letter-spacing);--awb-text-transform:var(--awb-typography4-text-transform);--awb-text-color:var(--awb-color5);--awb-text-font-family:var(--awb-typography4-font-family);--awb-text-font-weight:var(--awb-typography4-font-weight);--awb-text-font-style:var(--awb-typography4-font-style);\"><p>Now that definitions are out of the way, let\u2019s suppose we want to create a company! We need a really cool and catchy name and a business model to make some money!<\/p>\n<\/div><div class=\"fusion-title title fusion-title-5 fusion-sep-none fusion-title-text fusion-title-size-three\" style=\"--awb-text-color:var(--awb-color6);--awb-margin-bottom-small:8px;\"><h3 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:20;line-height:1.2;\">Example \u2014 Company name &amp; Business model with Old Chains<\/h3><\/div><div class=\"fusion-text fusion-text-8\"><div class=\"code\">\n<p>from langchain.chains import LLMChain<br \/>\nfrom langchain.prompts import PromptTemplate<br \/>\nfrom langchain_community.llms import OpenAI<\/p>\n<p>USER_INPUT = \"colorful socks\"<br \/>\nllm = OpenAI(temperature=0)<\/p>\n<p>prompt_template_product = \"What is a good name for a company that makes ?\"<br \/>\ncompany_name_chain = LLMChain(llm=llm, prompt=PromptTemplate.from_template(prompt_template_product))<br \/>\ncompany_name_output = company_name_chain(USER_INPUT)<\/p>\n<p>prompt_template_business = \"Give me the best business model idea for my company named: \"<br \/>\nbusiness_model_chain = LLMChain(llm=llm, prompt=PromptTemplate.from_template(prompt_template_business))<br \/>\nbusiness_model_output = business_model_chain(company_name_output[\"text\"])<\/p>\n<p>print(company_name_output)<br \/>\nprint(business_model_output)<\/p>\n<p>>>> <br \/>\n>>> <\/p>\n<\/div>\n<\/div><div class=\"fusion-text fusion-text-9\"><p>This is quite easy to follow, we can see a bit of redundancy, but it is manageable.<\/p>\n<\/div><div class=\"fusion-text fusion-text-10\"><p>Let\u2019s add some customization by handling the cases where the user is not using our chain as expected.<br \/>\nMaybe the user will input something completely unrelated to the goal of our chain? In that case, we want to detect it and respond appropriately.<\/p>\n<\/div><div class=\"fusion-title title fusion-title-6 fusion-sep-none fusion-title-text fusion-title-size-three\" style=\"--awb-text-color:var(--awb-color6);--awb-margin-bottom-small:8px;\"><h3 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:20;line-height:1.2;\">Example \u2014 Customization &amp; Routing with Old Chains<\/h3><\/div><div class=\"fusion-text fusion-text-11\"><div class=\"code\">\n<p>from langchain.chains import LLMChain<br \/>\nfrom langchain.prompts import PromptTemplate<br \/>\nfrom langchain_community.llms import OpenAI<br \/>\nimport ast<\/p>\n<p>USER_INPUT = \"Harrison Chase\"<br \/>\nllm = OpenAI(temperature=0)<\/p>\n<p># \u2014- Same code as before<br \/>\nprompt_template_product = \"What is a good name for a company that makes ?\"<br \/>\ncompany_name_chain = LLMChain(llm=llm, prompt=PromptTemplate.from_template(prompt_template_product))<\/p>\n<p>prompt_template_business = \"Give me the best business model idea for my company named: \"<br \/>\nbusiness_model_chain = LLMChain(llm=llm, prompt=PromptTemplate.from_template(prompt_template_business))<\/p>\n<p># \u2014- New code<\/p>\n<p>prompt_template_is_product = (<br \/>\n\"Your goal is to find if the input of the user is a plausible product namen\"<br \/>\n\"Questions, greetings, long sentences, celebrities or other non relevant inputs are not considered productsn\"<br \/>\n\"input: n\"<br \/>\n\"Answer only by 'True' or 'False' and nothing moren\"<br \/>\n)<\/p>\n<p>prompt_template_cannot_respond = (<br \/>\n\"You cannot respond to the user input: n\"<br \/>\n\"Ask the user to input the name of a product in order for you to make a company out of it.n\"<br \/>\n)<\/p>\n<p>cannot_respond_chain = LLMChain(llm=llm, prompt=PromptTemplate.from_template(prompt_template_cannot_respond))<br \/>\ncompany_name_chain = LLMChain(llm=llm, prompt=PromptTemplate.from_template(prompt_template_product))<br \/>\nbusiness_model_chain = LLMChain(llm=llm, prompt=PromptTemplate.from_template(prompt_template_business))<br \/>\nis_a_product_chain = LLMChain(llm=llm, prompt=PromptTemplate.from_template(prompt_template_is_product))<\/p>\n<p># If we use bool on a non empty str it will be True, so we need `literal_eval`<br \/>\nis_a_product = ast.literal_eval(is_a_product_chain(USER_INPUT)[\"text\"])<br \/>\nif is_a_product:<br \/>\ncompany_name_output = company_name_chain(USER_INPUT)<br \/>\nbusiness_model_output = business_model_chain(company_name_output[\"text\"])<br \/>\nprint(business_model_output)<br \/>\nelse:<br \/>\nprint(cannot_respond_chain(USER_INPUT))<\/p>\n<\/div>\n<\/div><div class=\"fusion-text fusion-text-12\"><p>This becomes a bit harder to understand, let\u2019s summarize:<\/p>\n<\/div><ul style=\"--awb-iconcolor:#000000;--awb-textcolor:#000000;--awb-line-height:27.2px;--awb-icon-width:27.2px;--awb-icon-height:27.2px;--awb-icon-margin:11.2px;--awb-content-margin:38.4px;\" class=\"fusion-checklist fusion-checklist-2 fusion-checklist-default type-icons paddingList dark-text\"><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p>We created a new chain is_real_product_chain() that detects if the user input can be considered a product.<\/p>\n<\/div><\/li><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p>We implement if\/else conditions to branch between the chains.<\/p>\n<\/div><\/li><\/ul><div class=\"fusion-text fusion-text-13\"><p>There are multiple problems that start to arise:<\/p>\n<\/div><ul style=\"--awb-iconcolor:#000000;--awb-textcolor:#000000;--awb-line-height:27.2px;--awb-icon-width:27.2px;--awb-icon-height:27.2px;--awb-icon-margin:11.2px;--awb-content-margin:38.4px;\" class=\"fusion-checklist fusion-checklist-3 fusion-checklist-default type-icons paddingList dark-text\"><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p>The code is a bit redundant as there is a lot of boilerplate.<\/p>\n<\/div><\/li><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p>It&#8217;s hard to distinguish what LLMChain is link to which LLMChain, we need to trace the inputs and outputs to understand it.<\/p>\n<\/div><\/li><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p>We can easily make errors on the output types of the chains, for example, the output of is_a_product_chain() is a str that should be later evaluated as bool.<\/p>\n<\/div><\/li><\/ul><div class=\"fusion-title title fusion-title-7 fusion-sep-none fusion-title-text fusion-title-size-two\" style=\"--awb-text-color:var(--awb-color6);--awb-margin-bottom-small:8px;\"><h2 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:50;line-height:1.2;\">What is LangChain Expression Language (LCEL)?<\/h2><\/div><div class=\"fusion-text fusion-text-14\"><p>LCEL is a unified interface and syntax to write composable production ready chains, there is a lot to unpack to understand what it means.<\/p>\n<p>We will first try to understand the new syntax by rewriting the chain from earlier.<\/p>\n<\/div><div class=\"fusion-title title fusion-title-8 fusion-sep-none fusion-title-text fusion-title-size-three\" style=\"--awb-text-color:var(--awb-color6);--awb-margin-bottom-small:8px;\"><h3 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:20;line-height:1.2;\">Example \u2014 Company name &amp; Business model with LCEL<\/h3><\/div><div class=\"fusion-text fusion-text-15\"><div class=\"code\">\n<p>from langchain_core.runnables import RunnablePassthrough<br \/>\nfrom langchain.prompts import PromptTemplate<br \/>\nfrom langchain_community.llms import OpenAI<\/p>\n<p>USER_INPUT = \"colorful socks\"<br \/>\nllm = OpenAI(temperature=0)<\/p>\n<p>prompt_template_product = \"What is a good name for a company that makes ?\"<br \/>\nprompt_template_business = \"Give me the best business model idea for my company named: \"<\/p>\n<p>chain = (<br \/>\nPromptTemplate.from_template(prompt_template_product)<br \/>\n| llm<br \/>\n| <br \/>\n| PromptTemplate.from_template(prompt_template_business)<br \/>\n| llm<br \/>\n)<\/p>\n<p>business_model_output = chain.invoke()<\/p>\n<\/div>\n<\/div><div class=\"fusion-text fusion-text-16\"><p>A lot of unusual code, in just a few lines :<\/p>\n<\/div><ul style=\"--awb-iconcolor:#000000;--awb-textcolor:#000000;--awb-line-height:27.2px;--awb-icon-width:27.2px;--awb-icon-height:27.2px;--awb-icon-margin:11.2px;--awb-content-margin:38.4px;\" class=\"fusion-checklist fusion-checklist-4 fusion-checklist-default type-icons paddingList dark-text\"><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p><strong>There is a weird | operator between a PromptTemplate, an llm and a dictionnary?!<\/strong> The | operator is simply here to say: &#8220;take the dictionnary on the left and pass it as input of the object on the right&#8221;.<\/p>\n<\/div><\/li><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p><strong>Why are we passing the variable product inside a dictionnary instead of a string like before?<\/strong> If you&#8217;ve read #1 you know that the | operator expects the inputs as dictionnary, therefore we give the product argument product inside a dictionnary.<\/p>\n<\/div><\/li><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p><strong>Why is there a function name RunnablePassthrough() instead of the company name?<\/strong> The RunnablePassthrough() is a placeholder to say: &#8220;we don&#8217;t have the company name for now, but when we have it, place it here&#8221;. I&#8217;ll explain what the &#8220;Runnable&#8221; term means in the next parts, for now it is ok to ignore it.<\/p>\n<\/div><\/li><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p><strong>Why do we need a specific method .invoke() instead of writing chain() ?<\/strong>We will understand this in the next part, but it is a sneak peek to why LCEL makes industrialization easier!<\/p>\n<\/div><\/li><\/ul><div class=\"fusion-text fusion-text-17\"><p><strong>But is it really more composable to create chains this way ?<br \/>\n<\/strong>Let\u2019s put it to the test by adding the is_a_product_chain() and the branching if the user input is not correct. We can even type the chain with Python Typing, let\u2019s do this as a good practice.<\/p>\n<\/div><div class=\"fusion-title title fusion-title-9 fusion-sep-none fusion-title-text fusion-title-size-three\" style=\"--awb-text-color:var(--awb-color6);--awb-margin-bottom-small:8px;\"><h3 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:20;line-height:1.2;\">Example \u2014 Customisation &amp; Routing with LCEL<\/h3><\/div><div class=\"fusion-text fusion-text-18\"><div class=\"code\">\n<p>from typing import Dict<br \/>\nfrom langchain_core.runnables import RunnablePassthrough, RunnableBranch<br \/>\nfrom langchain.prompts import PromptTemplate<br \/>\nfrom langchain_core.output_parsers import StrOutputParser<br \/>\nfrom langchain.output_parsers import BooleanOutputParser<br \/>\nfrom langchain_community.llms import OpenAI<\/p>\n<p>USER_INPUT = \"Harrrison Chase\"<br \/>\nllm = OpenAI(temperature=0)<\/p>\n<p>prompt_template_product = \"What is a good name for a company that makes ?\"<br \/>\nprompt_template_cannot_respond = (<br \/>\n\"You cannot respond to the user input: n\"<br \/>\n\"Ask the user to input the name of a product in order for you to make a company out of it.n\"<br \/>\n)<br \/>\nprompt_template_business = \"Give me the best business model idea for my company named: \"<br \/>\nprompt_template_is_product = (<br \/>\n\"Your goal is to find if the input of the user is a plausible product namen\"<br \/>\n\"Questions, greetings, long sentences, celebrities or other non relevant inputs are not considered productsn\"<br \/>\n\"input: n\"<br \/>\n\"Answer only by 'True' or 'False' and nothing moren\"<br \/>\n)<\/p>\n<p>answer_user_chain = (<br \/>\nPromptTemplate.from_template(prompt_template_product)<br \/>\n| llm<br \/>\n| <br \/>\n| PromptTemplate.from_template(prompt_template_business)<br \/>\n| llm<br \/>\n).with_types(input_type=Dict[str, str], output_type=str)<\/p>\n<p>is_product_chain = (<br \/>\nPromptTemplate.from_template(prompt_template_is_product)<br \/>\n| llm<br \/>\n| BooleanOutputParser(true_val='True', false_val='False')<br \/>\n).with_types(input_type=Dict[str, str], output_type=bool)<\/p>\n<p>cannot_respond_chain = (<br \/>\nPromptTemplate.from_template(prompt_template_cannot_respond) | llm<br \/>\n).with_types(input_type=Dict[str, str], output_type=str)<\/p>\n<p>full_chain = RunnableBranch(<br \/>\n(is_product_chain, answer_user_chain),<br \/>\ncannot_respond_chain<br \/>\n).with_types(input_type=Dict[str, str], output_type=str)<\/p>\n<p>print(full_chain.invoke())<\/p>\n<\/div>\n<\/div><div class=\"fusion-text fusion-text-19\"><p>Let\u2019s list the differences:<\/p>\n<\/div><ul style=\"--awb-iconcolor:#000000;--awb-textcolor:#000000;--awb-line-height:27.2px;--awb-icon-width:27.2px;--awb-icon-height:27.2px;--awb-icon-margin:11.2px;--awb-content-margin:38.4px;\" class=\"fusion-checklist fusion-checklist-5 fusion-checklist-default type-icons paddingList dark-text\"><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p>The syntax is different, ok that&#8217;s a given.<\/p>\n<\/div><\/li><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p>There are intermediary chains defined and called in a bigger chain, almost like functions.<\/p>\n<\/div><\/li><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p>Inputs and outputs are typed, almost like functions.<\/p>\n<\/div><\/li><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p>This doesn&#8217;t feel like python.<\/p>\n<\/div><\/li><\/ul><div class=\"fusion-title title fusion-title-10 fusion-sep-none fusion-title-text fusion-title-size-two\" style=\"--awb-text-color:var(--awb-color6);--awb-margin-bottom-small:8px;\"><h2 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:50;line-height:1.2;\">Why is LCEL better for industrialization?<\/h2><\/div><div class=\"fusion-text fusion-text-20\"><p>If I was reading this article until this exact point, and someone asked me if I was convinced about LCEL, I would probably say no. The syntax is too different, and I can probably organize my code into functions to get almost the exact same code. But I\u2019m here, writing this article, so there must be something more.<\/p>\n<\/div><div class=\"fusion-title title fusion-title-11 fusion-sep-none fusion-title-text fusion-title-size-three\" style=\"--awb-text-color:var(--awb-color6);--awb-margin-bottom-small:8px;\"><h3 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:20;line-height:1.2;\">Out of the box invoke, stream and batch<\/h3><\/div><div class=\"fusion-text fusion-text-21\"><p>By using LCEL your chain automatically has:<\/p>\n<\/div><ul style=\"--awb-iconcolor:#000000;--awb-textcolor:#000000;--awb-line-height:27.2px;--awb-icon-width:27.2px;--awb-icon-height:27.2px;--awb-icon-margin:11.2px;--awb-content-margin:38.4px;\" class=\"fusion-checklist fusion-checklist-6 fusion-checklist-default type-icons paddingList dark-text\"><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p><strong>.invoke()<\/strong>: You want to pass your input and get the output, nothing more, nothing less.<\/p>\n<\/div><\/li><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p><strong>.batch()<\/strong>: You want to pass multiple inputs to obtain multiple outputs, the parallelization is handled for you (faster than calling invoke 3 times).<\/p>\n<\/div><\/li><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p><strong>.stream()<\/strong>: This allows you to start printing the beginning of the completion before the full completion is finished.<\/p>\n<\/div><\/li><\/ul><div class=\"fusion-text fusion-text-22\"><div class=\"code\">\n<p>my_chain = prompt | llm<\/p>\n<p># &#8212;&#8212;&#8212;invoke&#8212;&#8212;&#8212; #<br \/>\nresult_with_invoke = my_chain.invoke(&#8220;hello world!&#8221;)<\/p>\n<p># &#8212;&#8212;&#8212;batch&#8212;&#8212;&#8212; #<br \/>\nresult_with_batch = my_chain.batch([&#8220;hello&#8221;, &#8220;world&#8221;, &#8220;!&#8221;])<\/p>\n<p># &#8212;&#8212;&#8212;stream&#8212;&#8212;&#8212; #<br \/>\nfor chunk in my_chain.stream(&#8220;hello world!&#8221;):<br \/>\nprint(chunk, flush=True, end=&#8221;&#8221;)<\/p>\n<\/div>\n<\/div><div class=\"fusion-text fusion-text-23\"><p>When you iterate, you can use the invoke method to ease the development process. But when showing the output of your chain in a UI, you want to stream the response. You can now use the stream method without rewriting anything.<\/p>\n<\/div><div class=\"fusion-title title fusion-title-12 fusion-sep-none fusion-title-text fusion-title-size-three\" style=\"--awb-text-color:var(--awb-color6);--awb-margin-bottom-small:8px;\"><h3 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:20;line-height:1.2;\">Out of the box async methods<\/h3><\/div><div class=\"fusion-text fusion-text-24\"><p>Most of the time, the frontend and backend of your application will be separated, meaning the frontend will make a request to the backend. If you have multiple users, you might need to handle multiple request on your backend at the same time.<\/p>\n<p><strong>Since most of the code in LangChain is just waiting between API calls, we can leverage asynchronous code to improve API scalability, if you want to understand why it is important I recommend reading the <a href=\"https:\/\/fastapi.tiangolo.com\/async\/#concurrent-burgers\" target=\"_blank\" rel=\"noopener\">concurrent burgers story of the FastAPI documentation<\/a>.<\/strong><br \/>\nThere is no need to worry about the implementation, because async methods are already available if you use LCEL:<\/p>\n<p><strong>.ainvoke() \/ .abatch() \/ .astream<\/strong>: asynchronous versions of invoke, batch and stream.<\/p>\n<p>I also recommend reading the <a href=\"https:\/\/python.langchain.com\/docs\/expression_language\/why\" target=\"_blank\" rel=\"noopener\">Why use LCEL page from LangChain documentation<\/a> with examples for each sync \/ async method.<\/p>\n<p>Langchain achieved those \u201cout of the box\u201d features by creating a unified interface called <strong>\u201cRunnable\u201d<\/strong>. Now, to leverage LCEL fully, we need to dive into what is this new Runnable interface.<\/p>\n<\/div><div class=\"fusion-title title fusion-title-13 fusion-sep-none fusion-title-text fusion-title-size-two\" style=\"--awb-text-color:var(--awb-color6);--awb-margin-bottom-small:8px;\"><h2 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:50;line-height:1.2;\">The Runnable interface<\/h2><\/div><div class=\"fusion-text fusion-text-25\"><p>Every object we\u2019ve used in the LCEL syntax so far are Runnables. It is a python Object created by LangChain, this object automatically inherits every feature we talked about before and a lot more. By using the LCEL syntax, we compose a new Runnable at each step, meaning that the final object created will also be a Runnable. <a href=\"https:\/\/python.langchain.com\/docs\/expression_language\/interface\" target=\"_blank\" rel=\"noopener\">You can learn more about the interface in the official documentation<\/a>.<\/p>\n<p>All the objects from the code below are either Runnable or dictionaries that are automatically converted to a Runnable :<\/p>\n<\/div><div class=\"fusion-text fusion-text-26\"><div class=\"code\">\n<p>from langchain_core.runnables import RunnablePassthrough, RunnableParallel<br \/>\nfrom langchain.prompts import PromptTemplate<br \/>\nfrom langchain_community.llms import OpenAI<\/p>\n<p>chain_number_one = (<br \/>\nPromptTemplate.from_template(prompt_template_product)<br \/>\n| llm<br \/>\n|  # <\u2014 THIS WILL CHANGE<br \/>\n| PromptTemplate.from_template(prompt_template_business)<br \/>\n| llm<br \/>\n)<\/p>\n<p>chain_number_two = (<br \/>\nPromptTemplate.from_template(prompt_template_product)<br \/>\n| llm<br \/>\n| RunnableParallel(company=RunnablePassthrough()) # <\u2014 THIS CHANGED<br \/>\n| PromptTemplate.from_template(prompt_template_business)<br \/>\n| llm<br \/>\n)<\/p>\n<p>print(chain_number_one == chain_number_two)<br \/>\n>>> True<\/p>\n<\/div>\n<\/div><div class=\"fusion-text fusion-text-27\"><p><strong>Why do we use RunnableParallel() and not simply Runnable() ?<\/strong><\/p>\n<p>Because, every Runnable inside a RunnableParallel is executed in parallel. This means that if you have 3 independent steps in your Runnable, they will run at the same time on different threads of your machine, improving the speed of your chain for free!<\/p>\n<\/div><div class=\"fusion-title title fusion-title-14 fusion-sep-none fusion-title-text fusion-title-size-two\" style=\"--awb-text-color:var(--awb-color6);--awb-margin-bottom-small:8px;\"><h2 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:50;line-height:1.2;\">Drawbacks of LCEL<\/h2><\/div><div class=\"fusion-text fusion-text-28\"><p>Despite its advantages, LCEL does have some potential drawbacks:<\/p>\n<\/div><ul style=\"--awb-iconcolor:#000000;--awb-textcolor:#000000;--awb-line-height:27.2px;--awb-icon-width:27.2px;--awb-icon-height:27.2px;--awb-icon-margin:11.2px;--awb-content-margin:38.4px;\" class=\"fusion-checklist fusion-checklist-7 fusion-checklist-default type-icons paddingList dark-text\"><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p><strong>Not fully PEP compliant<\/strong>: LCEL does not fully respect PEP20, the Zen of Python, which states that &#8220;explicit is better than implicit&#8221;. (To check PEP20 you can run import this in Python.) Additionally, LCEL&#8217;s syntax is not considered &#8220;Pythonic&#8221; as it feels like a different language, this could make LCEL less intuitive for some Pyhton developers that might refuse to use it.<\/p>\n<\/div><\/li><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p><strong>LCEL is a Domain-Specific Language (DSL)<\/strong>: Users are expected to have some understanding of prompts, chains or LLMs in order to leverage the syntax efficiently.<\/p>\n<\/div><\/li><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p><strong>Input \/ Output dependencies<\/strong>: Intermediary inputs and final outputs must be passed down from the start to the end. For instance, if you want to use the output of an intermediate step as the final output, you must carry it through all subsequent steps. This can lead to extra arguments in most of your chains, which may not be used but are necessary if you want to acces them through the output.<\/p>\n<\/div><\/li><\/ul><div class=\"fusion-title title fusion-title-15 fusion-sep-none fusion-title-text fusion-title-size-two\" style=\"--awb-text-color:var(--awb-color6);--awb-margin-bottom-small:8px;\"><h2 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:50;line-height:1.2;\">Conclusion<\/h2><\/div><div class=\"fusion-text fusion-text-29\"><p>In conclusion, LangChain Expression Language (LCEL) is a powerful tool that brings a fresh perspective to building Python applications. Despite its unconventional syntax, I highly recommend using LCEL for the following reasons :<\/p>\n<\/div><ul style=\"--awb-iconcolor:#000000;--awb-textcolor:#000000;--awb-line-height:27.2px;--awb-icon-width:27.2px;--awb-icon-height:27.2px;--awb-icon-margin:11.2px;--awb-content-margin:38.4px;\" class=\"fusion-checklist fusion-checklist-8 fusion-checklist-default type-icons paddingList dark-text\"><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p><strong>Unified Interface<\/strong>: Provides a consistent interface for all chains, making it easier to industrialize your code with out of the box stream, async, fallback models, typing, run time configurations, etc&#8230;<\/p>\n<\/div><\/li><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p><strong>Automatic Parallelization<\/strong>: Automatically run multiple tasks in parallel, improving the execution speed of your chains and improving the user experience.<\/p>\n<\/div><\/li><li class=\"fusion-li-item\" style=\"\"><span class=\"icon-wrapper circle-no\"><i class=\"fusion-li-icon awb-icon-check\" aria-hidden=\"true\"><\/i><\/span><div class=\"fusion-li-item-content\">\n<p><strong>Composability<\/strong>: It allows you to easily compose and modify chains, making your code more flexible and adaptable.<\/p>\n<\/div><\/li><\/ul><div class=\"fusion-title title fusion-title-16 fusion-sep-none fusion-title-text fusion-title-size-two\" style=\"--awb-text-color:var(--awb-color6);--awb-margin-bottom-small:8px;\"><h2 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:50;line-height:1.2;\">To Go Further&#8230;<\/h2><\/div><div class=\"fusion-title title fusion-title-17 fusion-sep-none fusion-title-text fusion-title-size-three\" style=\"--awb-text-color:var(--awb-color6);--awb-margin-bottom-small:8px;\"><h3 class=\"fusion-title-heading title-heading-left fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:20;line-height:1.2;\">The runnable abstraction<\/h3><\/div><div class=\"fusion-text fusion-text-30\"><p>In some cases, I believe it\u2019s important to understand the abstraction that LangChain has implemented to make the LCEL syntax work.<\/p>\n<p>You can re-implement the basic functionalities of Runnable easily as follows:<\/p>\n<\/div><div class=\"fusion-text fusion-text-31\"><div class=\"code\">\n<p>class Runnable:<br \/>\ndef __init__(self, func):<br \/>\nself.func = func<\/p>\n<p>def __or__(self, other):<br \/>\ndef chained_func(*args, **kwargs):<br \/>\n# self.func is on the left, other is on the right<br \/>\nreturn other(self.func(*args, **kwargs))<br \/>\nreturn Runnable(chained_func)<\/p>\n<p>def __call__(self, *args, **kwargs):<br \/>\nreturn self.func(*args, **kwargs)<\/p>\n<p>def add_ten(x):<br \/>\nreturn x + 10<\/p>\n<p>def divide_by_two(x):<br \/>\nreturn x \/ 2<\/p>\n<p>runnable_add_ten = Runnable(add_ten)<br \/>\nrunnable_divide_by_two = Runnable(divide_by_two)<br \/>\nchain = runnable_add_ten | runnable_divide_by_two<br \/>\nresult = chain(8) # (8+10) \/ 2 = 9.0 should be the answer<br \/>\nprint(result)<br \/>\n&gt;&gt;&gt; 9.0<\/p>\n<\/div>\n<\/div><div class=\"fusion-text fusion-text-32\"><p>A Runnable is simply a python object in which the .__or__() method has been overwritten.<br \/>\nIn practice, LangChain has added a lot of functionalities such as converting dictionaries to Runnable, typings capabilities, configurability capabilities, and invoke, batch, stream and async methods!<\/p>\n<\/div><div class=\"fusion-text fusion-text-33\"><p>So, why not give LCEL a try in your next project?<\/p>\n<p>If you want to learn more, I highly recommend browsing <a href=\"https:\/\/python.langchain.com\/docs\/expression_language\/cookbook\" target=\"_blank\" rel=\"noopener\">LangChain cookbook on LCEL<\/a>.<\/p>\n<\/div><\/div><\/div><\/div><\/article><div class=\"fusion-fullwidth fullwidth-box fusion-builder-row-3 fusion-flex-container nonhundred-percent-fullwidth non-hundred-percent-height-scrolling\" style=\"--awb-border-radius-top-left:0px;--awb-border-radius-top-right:0px;--awb-border-radius-bottom-right:0px;--awb-border-radius-bottom-left:0px;--awb-margin-top:40px;--awb-margin-bottom:40px;--awb-background-color:var(--awb-color1);--awb-flex-wrap:wrap;\" ><div class=\"fusion-builder-row fusion-row fusion-flex-align-items-center fusion-flex-justify-content-center fusion-flex-content-wrap\" style=\"max-width:calc( 1440px + 20px );margin-left: calc(-20px \/ 2 );margin-right: calc(-20px \/ 2 );\"><div class=\"fusion-layout-column fusion_builder_column fusion-builder-column-2 fusion_builder_column_1_1 1_1 fusion-flex-column fusion-flex-align-self-center\" style=\"--awb-padding-top:40px;--awb-padding-right:40px;--awb-padding-bottom:40px;--awb-padding-left:40px;--awb-overflow:hidden;--awb-bg-position:left center;--awb-bg-size:cover;--awb-border-color:rgba(10,17,40,0.1);--awb-border-style:solid;--awb-border-radius:4px 4px 4px 4px;--awb-width-large:100%;--awb-margin-top-large:0px;--awb-spacing-right-large:10px;--awb-margin-bottom-large:0px;--awb-spacing-left-large:10px;--awb-width-medium:100%;--awb-order-medium:0;--awb-spacing-right-medium:10px;--awb-spacing-left-medium:10px;--awb-width-small:100%;--awb-order-small:0;--awb-spacing-right-small:10px;--awb-spacing-left-small:10px;\"><div class=\"fusion-column-wrapper lazyload fusion-column-has-shadow fusion-flex-justify-content-center fusion-content-layout-column fusion-column-has-bg-image\" data-bg-url=\"https:\/\/artefact.com\/\/wp-content\/uploads\/2021\/03\/background.jpg\" data-bg=\"https:\/\/artefact.com\/\/wp-content\/uploads\/2021\/03\/background.jpg\"><div class=\"fusion-image-element\" style=\"text-align:center;--awb-margin-right:20px;--awb-margin-left:20px;--awb-max-width:150px;--awb-caption-title-font-family:var(--h2_typography-font-family);--awb-caption-title-font-weight:var(--h2_typography-font-weight);--awb-caption-title-font-style:var(--h2_typography-font-style);--awb-caption-title-size:var(--h2_typography-font-size);--awb-caption-title-transform:var(--h2_typography-text-transform);--awb-caption-title-line-height:var(--h2_typography-line-height);--awb-caption-title-letter-spacing:var(--h2_typography-letter-spacing);\"><span class=\" fusion-imageframe imageframe-none imageframe-2 hover-type-none\"><img decoding=\"async\" width=\"72\" height=\"41\" title=\"medium\" src=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%2772%27%20height%3D%2741%27%20viewBox%3D%270%200%2072%2041%27%3E%3Crect%20width%3D%2772%27%20height%3D%2741%27%20fill-opacity%3D%220%22%2F%3E%3C%2Fsvg%3E\" data-orig-src=\"https:\/\/artefact.com\/\/wp-content\/uploads\/2021\/03\/medium.png\" alt class=\"lazyload img-responsive wp-image-60927\"\/><\/span><\/div><div class=\"fusion-title title fusion-title-18 fusion-sep-none fusion-title-center fusion-title-text fusion-title-size-three\" style=\"--awb-margin-top:20px;--awb-margin-bottom:0px;--awb-margin-bottom-small:8px;\"><h3 class=\"fusion-title-heading title-heading-center fusion-responsive-typography-calculated\" style=\"margin:0;--fontSize:20;line-height:1.2;\">Medium Blog by Artefact.<\/h3><\/div><div class=\"fusion-text fusion-text-34\" style=\"--awb-content-alignment:center;\"><p>This article was initially published on Medium.com.<br \/>\nFollow us on our Medium Blog !<\/p>\n<\/div><div style=\"text-align:center;\"><a class=\"fusion-button button-flat button-medium button-default fusion-button-default button-1 fusion-button-default-span fusion-button-default-type\" style=\"--button_text_transform:var(--awb-custom_typography_2-text-transform);--button_typography-letter-spacing:var(--awb-custom_typography_2-letter-spacing);--button_typography-font-family:var(--awb-custom_typography_2-font-family);--button_typography-font-weight:var(--awb-custom_typography_2-font-weight);--button_typography-font-style:var(--awb-custom_typography_2-font-style);\" target=\"_blank\" rel=\"noopener noreferrer\" data-hover=\"text_slide_down\" href=\"https:\/\/medium.com\/artefact-engineering-and-data-science\/unleashing-the-power-of-langchain-expression-language-lcel-from-proof-of-concept-to-production-8ad8eebdcb1d\"><div class=\"awb-button-text-transition  awb-button__hover-content--centered\"><span class=\"fusion-button-text awb-button__text awb-button__text--default\">Read Our Article<\/span><span class=\"fusion-button-text awb-button__text awb-button__text--default\">Read Our Article<\/span><\/div><\/a><\/div><\/div><\/div><\/div><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>LangChain hat sich in weniger als einem Jahr zu einer der meistgenutzten Python-Bibliotheken f\u00fcr die Interaktion mit LLMs entwickelt. LangChain war jedoch haupts\u00e4chlich eine Bibliothek f\u00fcr POCs, da ihr die F\u00e4higkeit fehlte, komplexe und skalierbare Anwendungen zu erstellen.<\/p>","protected":false},"featured_media":94497,"parent":0,"template":"","meta":{"_acf_changed":false,"ep_exclude_from_search":false},"blog-category":[21939],"blog-language":[2991],"class_list":["post-94492","blog","type-blog","status-publish","has-post-thumbnail","hentry","blog-category-medium","blog-language-en"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.artefact.com\/de\/wp-json\/wp\/v2\/blog\/94492","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.artefact.com\/de\/wp-json\/wp\/v2\/blog"}],"about":[{"href":"https:\/\/www.artefact.com\/de\/wp-json\/wp\/v2\/types\/blog"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.artefact.com\/de\/wp-json\/wp\/v2\/media\/94497"}],"wp:attachment":[{"href":"https:\/\/www.artefact.com\/de\/wp-json\/wp\/v2\/media?parent=94492"}],"wp:term":[{"taxonomy":"blog-category","embeddable":true,"href":"https:\/\/www.artefact.com\/de\/wp-json\/wp\/v2\/blog-category?post=94492"},{"taxonomy":"blog-language","embeddable":true,"href":"https:\/\/www.artefact.com\/de\/wp-json\/wp\/v2\/blog-language?post=94492"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}