|
| 1 | +====================== |
| 2 | +LangChain |
| 3 | +====================== |
| 4 | + |
| 5 | +Here we have some code snippets that help compare a vanilla code implementation |
| 6 | +with LangChain and Hamilton. |
| 7 | + |
| 8 | +LangChain's focus is on hiding details and making code terse. |
| 9 | + |
| 10 | +Hamilton's focus instead is on making code more readable, maintainable, and importantly customizeable. |
| 11 | + |
| 12 | + |
| 13 | +So don't be surprised that Hamilton's code is "longer" - that's by design. There is |
| 14 | +also little abstraction between you, and the underlying libraries with Hamilton. |
| 15 | +With LangChain they're abstracted away, so you can't really see easily what's going on |
| 16 | +underneath. |
| 17 | + |
| 18 | +*Rhetorical question*: which code would you rather maintain, change, and update? |
| 19 | + |
| 20 | +---------------------- |
| 21 | +A simple joke example |
| 22 | +---------------------- |
| 23 | + |
| 24 | +.. table:: Simple Invocation |
| 25 | + :align: left |
| 26 | + |
| 27 | + +-----------------------------------------------------------+----------------------------------------------------------+-------------------------------------------------------------+ |
| 28 | + | Hamilton | Vanilla | LangChain | |
| 29 | + +===========================================================+==========================================================+=============================================================+ |
| 30 | + | .. literalinclude:: langchain_snippets/hamilton_invoke.py | .. literalinclude:: langchain_snippets/vanilla_invoke.py | .. literalinclude:: langchain_snippets/lcel_invoke.py | |
| 31 | + | | | | |
| 32 | + +-----------------------------------------------------------+----------------------------------------------------------+-------------------------------------------------------------+ |
| 33 | + |
| 34 | + |
| 35 | +.. figure:: langchain_snippets/hamilton-invoke.png |
| 36 | + :alt: Structure of the Hamilton DAG |
| 37 | + :align: center |
| 38 | + :width: 50% |
| 39 | + |
| 40 | + The Hamilton DAG visualized. |
| 41 | + |
| 42 | +----------------------- |
| 43 | +A streamed joke example |
| 44 | +----------------------- |
| 45 | +With Hamilton we can just swap the call function to return a streamed response. |
| 46 | +Note: you could use @config.when to include both streamed and non-streamed versions in the same DAG. |
| 47 | + |
| 48 | +.. table:: Streamed Version |
| 49 | + :align: left |
| 50 | + |
| 51 | + +-------------------------------------------------------------+------------------------------------------------------------+---------------------------------------------------------------+ |
| 52 | + | Hamilton | Vanilla | LangChain | |
| 53 | + +=============================================================+============================================================+===============================================================+ |
| 54 | + | .. literalinclude:: langchain_snippets/hamilton_streamed.py | .. literalinclude:: langchain_snippets/vanilla_streamed.py | .. literalinclude:: langchain_snippets/lcel_streamed.py | |
| 55 | + | | | | |
| 56 | + +-------------------------------------------------------------+------------------------------------------------------------+---------------------------------------------------------------+ |
| 57 | + |
| 58 | + |
| 59 | +.. figure:: langchain_snippets/hamilton-streamed.png |
| 60 | + :alt: Structure of the Hamilton DAG |
| 61 | + :align: center |
| 62 | + :width: 50% |
| 63 | + |
| 64 | + The Hamilton DAG visualized. |
| 65 | + |
| 66 | +------------------------------- |
| 67 | +A "batch" parallel joke example |
| 68 | +------------------------------- |
| 69 | +In this batch example, the joke requests are parallelized. |
| 70 | +Note: with Hamilton you can delegate to many different backends for parallelization, |
| 71 | +e.g. Ray, Dask, etc. We use multi-threading here. |
| 72 | + |
| 73 | +.. table:: Batch Parallel Version |
| 74 | + :align: left |
| 75 | + |
| 76 | + +-------------------------------------------------------------+------------------------------------------------------------+---------------------------------------------------------------+ |
| 77 | + | Hamilton | Vanilla | LangChain | |
| 78 | + +=============================================================+============================================================+===============================================================+ |
| 79 | + | .. literalinclude:: langchain_snippets/hamilton_batch.py | .. literalinclude:: langchain_snippets/vanilla_batch.py | .. literalinclude:: langchain_snippets/lcel_batch.py | |
| 80 | + | | | | |
| 81 | + +-------------------------------------------------------------+------------------------------------------------------------+---------------------------------------------------------------+ |
| 82 | + |
| 83 | + |
| 84 | +.. figure:: langchain_snippets/hamilton-batch.png |
| 85 | + :alt: Structure of the Hamilton DAG |
| 86 | + :align: center |
| 87 | + :width: 75% |
| 88 | + |
| 89 | + The Hamilton DAG visualized. |
| 90 | + |
| 91 | +---------------------- |
| 92 | +A "async" joke example |
| 93 | +---------------------- |
| 94 | +Here we show how to make the joke using async constructs. With Hamilton |
| 95 | +you can mix and match async and regular functions, the only change |
| 96 | +is that you need to use the async Hamilton Driver. |
| 97 | + |
| 98 | +.. table:: Async Version |
| 99 | + :align: left |
| 100 | + |
| 101 | + +-------------------------------------------------------------+------------------------------------------------------------+---------------------------------------------------------------+ |
| 102 | + | Hamilton | Vanilla | LangChain | |
| 103 | + +=============================================================+============================================================+===============================================================+ |
| 104 | + | .. literalinclude:: langchain_snippets/hamilton_async.py | .. literalinclude:: langchain_snippets/vanilla_async.py | .. literalinclude:: langchain_snippets/lcel_async.py | |
| 105 | + | | | | |
| 106 | + +-------------------------------------------------------------+------------------------------------------------------------+---------------------------------------------------------------+ |
| 107 | + |
| 108 | + |
| 109 | +.. figure:: langchain_snippets/hamilton-async.png |
| 110 | + :alt: Structure of the Hamilton DAG |
| 111 | + :align: center |
| 112 | + :width: 50% |
| 113 | + |
| 114 | + The Hamilton DAG visualized. |
| 115 | + |
| 116 | + |
| 117 | +--------------------------------- |
| 118 | +Switch LLM to completion for joke |
| 119 | +--------------------------------- |
| 120 | +Here we show how to make the joke switching to a different openAI model that is for completion. |
| 121 | +Note: we use the @config.when construct to augment the original DAG and add a new function |
| 122 | +that uses the different OpenAI model. |
| 123 | + |
| 124 | +.. table:: Completion Version |
| 125 | + :align: left |
| 126 | + |
| 127 | + +------------------------------------------------------------------+-----------------------------------------------------------------+---------------------------------------------------------------+ |
| 128 | + | Hamilton | Vanilla | LangChain | |
| 129 | + +==================================================================+=================================================================+===============================================================+ |
| 130 | + | .. literalinclude:: langchain_snippets/hamilton_completion.py | .. literalinclude:: langchain_snippets/vanilla_completion.py | .. literalinclude:: langchain_snippets/lcel_completion.py | |
| 131 | + | | | | |
| 132 | + +------------------------------------------------------------------+-----------------------------------------------------------------+---------------------------------------------------------------+ |
| 133 | + |
| 134 | + |
| 135 | +.. figure:: langchain_snippets/hamilton-completion.png |
| 136 | + :alt: Structure of the Hamilton DAG |
| 137 | + :align: center |
| 138 | + :width: 50% |
| 139 | + |
| 140 | + The Hamilton DAG visualized with configuration provided for the completion path. Note the dangling node - that's normal, it's not used in the completion path. |
| 141 | + |
| 142 | + |
| 143 | +--------------------------------- |
| 144 | +Switch to using Anthropic |
| 145 | +--------------------------------- |
| 146 | +Here we show how to make the joke switching to use a different model provider, in this case |
| 147 | +it's Anthropic. |
| 148 | +Note: we use the @config.when construct to augment the original DAG and add a new functions |
| 149 | +to use Anthropic. |
| 150 | + |
| 151 | +.. table:: Anthropic Version |
| 152 | + :align: left |
| 153 | + |
| 154 | + +------------------------------------------------------------------+-----------------------------------------------------------------+---------------------------------------------------------------+ |
| 155 | + | Hamilton | Vanilla | LangChain | |
| 156 | + +==================================================================+=================================================================+===============================================================+ |
| 157 | + | .. literalinclude:: langchain_snippets/hamilton_anthropic.py | .. literalinclude:: langchain_snippets/vanilla_anthropic.py | .. literalinclude:: langchain_snippets/lcel_anthropic.py | |
| 158 | + | | | | |
| 159 | + +------------------------------------------------------------------+-----------------------------------------------------------------+---------------------------------------------------------------+ |
| 160 | + |
| 161 | + |
| 162 | +.. figure:: langchain_snippets/hamilton-anthropic.png |
| 163 | + :alt: Structure of the Hamilton DAG |
| 164 | + :align: center |
| 165 | + :width: 50% |
| 166 | + |
| 167 | + The Hamilton DAG visualized with configuration provided to use Anthropic. |
| 168 | + |
| 169 | + |
| 170 | +--------------------------------- |
| 171 | +Logging |
| 172 | +--------------------------------- |
| 173 | +Here we show how to log more information about the joke request. Hamilton has |
| 174 | +lots of customization options, and one out of the box is to log more information via |
| 175 | +printing. |
| 176 | + |
| 177 | +.. table:: Logging |
| 178 | + :align: left |
| 179 | + |
| 180 | + +------------------------------------------------------------------+-----------------------------------------------------------------+---------------------------------------------------------------+ |
| 181 | + | Hamilton | Vanilla | LangChain | |
| 182 | + +==================================================================+=================================================================+===============================================================+ |
| 183 | + | .. literalinclude:: langchain_snippets/hamilton_logging.py | .. literalinclude:: langchain_snippets/vanilla_logging.py | .. literalinclude:: langchain_snippets/lcel_logging.py | |
| 184 | + | | | | |
| 185 | + +------------------------------------------------------------------+-----------------------------------------------------------------+---------------------------------------------------------------+ |
| 186 | + |
| 187 | + |
| 188 | +--------------------------------- |
| 189 | +Fallbacks |
| 190 | +--------------------------------- |
| 191 | +Fallbacks are pretty situation and context dependent. It's not that |
| 192 | +hard to wrap a function in a try/except block. The key is to make sure |
| 193 | +you know what's going on, and that a fallback was triggered. So in our |
| 194 | +opinion it's better to be explicit about it. |
| 195 | + |
| 196 | +.. table:: Logging |
| 197 | + :align: left |
| 198 | + |
| 199 | + +------------------------------------------------------------------+-----------------------------------------------------------------+---------------------------------------------------------------+ |
| 200 | + | Hamilton | Vanilla | LangChain | |
| 201 | + +==================================================================+=================================================================+===============================================================+ |
| 202 | + | .. literalinclude:: langchain_snippets/hamilton_fallbacks.py | .. literalinclude:: langchain_snippets/vanilla_fallbacks.py | .. literalinclude:: langchain_snippets/lcel_fallbacks.py | |
| 203 | + | | | | |
| 204 | + +------------------------------------------------------------------+-----------------------------------------------------------------+---------------------------------------------------------------+ |
0 commit comments