Repository navigation
LangChain Applied · A triage pipeline that routes before it reasons #12
akash-coded
started this conversation in
Exercises
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Exercise 1 - TravelMind Triage Pipeline
Language: Python 3.11+
Level: Intermediate
Topics: LCEL pipe,
RunnablePassthrough.assign,RunnableParallel,RunnableLambda, structured output, debugging, plain-Python to LCEL conversionYou are wiring the intake path for TravelMind, an airline support assistant. A passenger message comes in, you enrich it, gather facts in parallel, and produce one reply. Every task below builds one piece of that path.
Run this once so every snippet works:
The anchor booking for every part: PNR
JX48Q2, passenger Rao, Gold tier, the BLR to DEL leg cancelled.Part A - Trace it (~4 min)
Read this chain. Do not run it yet.
A1. Fill the trace table. What keys exist, and what is in
issue, after each stage?issuevalue.assign(words=...)A2. Write the exact dict that gets printed.
A3. The lambda inside
{"issue": ...}readsx["complaint"]. Explain in one line whyxis the whole input dict and not just the string.Part B - Debug and fix (~5 min)
Each snippet has exactly one bug. Name the broken line, then give a one-line fix.
B1.
B2.
B3.
For B3, there are two defects. State both, then write the corrected
returnline.Part C - Diagram to code (~5 min)
This is the parallel fact-gathering stage. Turn the diagram into working code by filling the
TODOlines.graph TD IN["brief"] --> P["fan out"] P --> A["policy in 2 lines"] P --> B["fare handling in 2 lines"] P --> C["two rebooking options"] A --> S["synthesize one reply"] B --> S C --> S S --> OUT["reply"]Boilerplate:
The connection in the last
TODOis the whole point. Look at whatgatheroutputs and whatsynthneeds as input, then ask yourself why no glue code is required between them.Part D - Convert plain Python to LCEL (~4 min)
Here is a naive sequential version using raw boto3. It works, but it is three hand-rolled calls with string glue.
Task. Rewrite
triageas a single LCEL chain that produces the same three-stage flow. UseChatPromptTemplatefor each stage andRunnablePassthrough.assignto carryissueandurgencyforward.Constraint: the finished chain must accept
{"complaint": ...}and return the reply string, with no intermediate print statements.Part E - Build the front door (~4 min)
Cheap requests should not pay for the full parallel gather from Part C. Add a router that classifies first, runs the expensive
pipelineonly forrebookingorrefund, and short-circuits everything else to a one-line acknowledgement.Boilerplate:
Both
pipeline,quick, andclassifierread the same{"brief": ...}input, so the branches stay interchangeable.Definition of done
rebookingandrefundbriefs hit the full pipeline,otherbriefs return one lineAnswer key (instructor)
Part A
A1.
issuevalueissuebag lost at del.assign(words=...)issue,wordsbag lost at del,words=4A2.
{'issue': 'bag lost at del', 'words': 4}A3. In an LCEL sequence a plain dict becomes a
RunnableParallel, and each value runnable receives the sequence's current input, which here is the whole{"complaint": ...}dict.Skeptic. The dict-map stage raises
KeyError: 'complaint'because the lambda still readsx["complaint"]while the input now has keytext.Part B
B1. Broken line:
... | StrOutputParser. It is the class, not an instance. Fix:StrOutputParser().B2. Broken line:
("human", "Fare handling for: {text}"). The branch needstext, but the input only carriesbrief, so it raisesKeyError: 'text'. Fix:("human", "Fare handling for: {brief}").B3. Two defects:
routes[category]raisesKeyErrorfor any category outside the dict, and it returns a runnable without running it. Corrected return line:(any sensible default chain works in place of
quick).Part C
Why no glue:
gatherreturns{"policy": ..., "fare": ..., "options": ...}, which is exactly the set of variablessynthexpects, so piping is enough.Part D
Skeptic. Free
batchconcurrency across many complaints, andstreamfor token-by-token output, both available on the LCEL chain with no extra code. Portability across providers is a third.Part E
All reactions