Repository navigation
LangChain Coding 1 · Agents and pipes: composing runnables that earn their place #11
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 1: Agents and Pipes
Language: Python Topics: create_agent, tools, LCEL pipes (
prompt | model | parser), debugging, porting from Strands Level: IntermediateTarget time: about 20 minutes. You write and run real code against Bedrock.
There are two ways to run a model in LangChain, and this exercise builds both:
prompt | model | parser, for when there are no tools and you just want a clean answerKnowing which to reach for is half the skill. An agent loop is overhead when a pipe would do.
Setup (run once)
You need AWS credentials with Bedrock access (your lab account). The
us.prefix is the inference-profile routing label and is required.Part 1 · Build a tool and an agent
Goal: wire TravelMind's booking lookup into an agent and run one turn.
The loop you are building:
flowchart TD U[user: is JX48Q2 cancelled?] --> M[model] M -->|call lookup_pnr| T[tool reads the record] T --> M2[model writes the grounded answer] M2 --> A[final answer]Starter code:
Your task:
create_agent(model, tools=[...], system_prompt=...).result["messages"][-1].content.Done when: the printout names the cancelled BLR-DEL segment and the Gold tier, and it came from the tool, not from the model guessing.
Hint:
toolsmust be a list even for one tool.agent.invoke({"messages": [{"role": "user", "content": "..."}]}).Part 2 · Convert a diagram into an LCEL pipe
Goal: implement this pipeline exactly as drawn. No tools, no loop, just composition.
flowchart LR IN[input dict] --> P[ChatPromptTemplate] --> M[model] --> O[StrOutputParser] --> S[plain string]Read the diagram left to right. The prompt turns your input into messages, the model answers, the parser strips the
AIMessagedown to a plain string.Starter code:
Your task:
ChatPromptTemplate.from_messages([...])with a("system", ...)and a("human", ...)tuple. Put{pnr}in the human line.invoketakes the dict of template variables, not a bare string.Done when: the printout is a one-sentence string (not an
AIMessage, not a dict). If you seecontent=...wrapping it, the parser is missing.Hint: the whole pipe is three objects joined by
|. The parser isStrOutputParser().Why it matters: Part 1 spun up a full agent loop. Part 2 answered with three composed objects. Same model, far less machinery. Reach for the pipe when nothing needs fetching.
Part 3 · Debug and fix a broken agent
Goal: this agent should look up a booking, but it will not run. Find the bugs and write the corrected lines.
Your task: three things are wrong. For each, name the line and give the corrected version.
Done when: you have three corrected lines and the agent runs, printing a grounded answer. Bonus: line L13 prints the whole state dict, so also show how to print just the final text.
Hint: the correct import path for the agent constructor, the shape
toolsexpects, and the shapeinvokeexpects are all in Part 1.Part 4 · Port a Strands agent to LangChain
Goal: you already know this in Strands. Rebuild it in LangChain, part for part.
Strands (works):
Your task: write the LangChain version. Four things change:
BedrockModel(model_id=..., region_name=...)ChatBedrockConverse(model=..., region_name=...)Agent(model=, system_prompt=, tools=[...])create_agent(model, tools=[...], system_prompt=)agent("...")agent.invoke({"messages": [...]})str(result)result["messages"][-1].contentDone when: your LangChain agent prints the same kind of grounded answer about the delay. The
@tooland its docstring do not change at all.Hint: the tool definition ports unchanged. Only the model constructor, the agent constructor, and the run-and-read lines differ.
Part 5 · Stretch: feed a pipe's output into the agent
Goal: compose the two halves. Use a pipe to build a clean instruction, then hand it to the agent from Part 1.
Starter code:
Your task:
build_questionformats the PNR into the instruction string.ask_agentrunsagent.invoke({"messages": [{"role": "user", "content": <the string>}]})and returns["messages"][-1].content.|and invoke.Done when: one
invokeon{"pnr": "JX48Q2"}produces the grounded booking answer, with the pipe and the agent working as one chain.Hint: a
RunnableLambdawraps any function into a pipe step, so an agent can live inside an LCEL chain.What you practised
All reactions