Repository navigation
LangChain Coding 2 · Composition and control flow you can test #14
akash-coded
started this conversation in
Exercises
Replies: 1 comment
0 replies
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.
LangChain Coding · Exercise 2: Composition and Control
Language: Python Topics: LCEL composition (
RunnableParallel,RunnableLambda), structured output withresponse_format, debugging a chain, porting from Strands Level: IntermediateTarget time: about 20 minutes. You write and run real code against Bedrock.
Exercise 1 built a straight pipe. This one bends it. Two ideas:
Both are about control: shaping exactly what flows through, and what comes out.
Setup (run once)
AWS credentials with Bedrock access required (your lab account).
Part 1 · Convert a diagram into a parallel pipe
Goal: implement this fan-out. The same input feeds two branches, the results merge into a dict, and a final step formats one line.
flowchart TD IN[pnr] --> S[status branch] IN --> T[tier branch] S --> MERGE[merge into a dict] T --> MERGE MERGE --> F[format one line]RunnableParallelruns the branches on the same input and returns a dict keyed by branch name.RunnableLambdawraps any function into a pipe step.Starter code:
Your task:
status_branchreadsBOOKINGS[d["pnr"]]["status"].tier_branchreads the tier the same way.RunnableParallel(status=status_branch, tier=tier_branch)gives you the merged dict.format_stepreadsd["status"]andd["tier"]and builds the sentence. Gold tier means no fee.|and invoke on the dict.Done when: the printout is the one-line briefing string, assembled from two branches that ran on the same input.
Hint: the fan-out output is a dict, so
format_stepreceives a dict, not a string. There is no model in this pipe at all, it is pure composition.Why it matters: fan-out is how you gather several facts about one thing without three sequential round trips. It is the parallelization pattern, in three lines.
Part 2 · Build an agent with structured output
Goal: return a validated object your code can branch on, not a paragraph you have to parse.
flowchart LR U[status of JX48Q2?] --> AG[agent with response_format] --> OBJ[validated Disruption object]Starter code:
Your task:
response_format=Disruptiontocreate_agent.result["structured_response"]is a validatedDisruptioninstance.print("no fee" if obj.rebook_fee_waived else "fee applies").Done when: you print typed fields and branch on a real Python
bool, not on the string"true".Hint: the difference between this and "reply in JSON" is validation. A missing or wrong-typed field fails at the boundary instead of corrupting a later step.
Part 3 · Debug and fix a broken pipe
Goal: this briefing pipe will not run. Find the bugs and write the corrected lines.
Your task: two things are wrong. For each, name the line and give the corrected version.
invoke.Done when: the pipe runs and prints a one-line string. Explain in your head why order matters here: what does each stage expect as its input?
Hint: LCEL flows left to right, and the prompt has to run first because the model needs messages, not a template. The template variable
{pnr}is filled from a dict.Part 4 · Port a Strands structured-output call to LangChain
Goal: rebuild this Strands snippet in LangChain, keeping the typed result.
Strands (works):
Your task: write the LangChain version. The mapping:
Agent(model=, system_prompt=)create_agent(model, tools=[], system_prompt=)agent.structured_output(Rebooking, "...")response_format=Rebooking, thenresult["structured_response"]result.new_flightobj.new_flighton the returned objectDone when: your LangChain code prints the same
new_flightvalue from a validatedRebookingobject. The Pydantic model does not change.Hint: Strands exposes structured output as a separate method call. LangChain folds it into the agent result under
structured_response.Part 5 · Stretch: put an agent inside a pipe
Goal: wrap the Part 2 agent as a pipe step so it composes with the fan-out from Part 1.
flowchart LR IN[pnr] --> Q[build a question string] --> AG[agent step] --> TXT[final text]Starter code:
Your task:
build_questionformats the PNR into the question.ask_agentcallsagent.invoke({"messages": [{"role": "user", "content": <string>}]})and returns the final text. (Use an agent with tools or a plain prompt-answer agent, either runs.)Done when: a single
invokeon{"pnr": "JX48Q2"}runs the whole chain, with the agent living inside the pipe as just another step.Hint: anything wrapped in
RunnableLambdabecomes composable, which is why an agent, a model, and a plain function can all sit in the same|chain.What you practised
RunnableParallelAll reactions