Week 1 ended with you pulling the top result's snippet out of search(). What is the smallest useful thing you can have an agent do with that snippet?
Summarize it? Feed the snippet in as a prompt and get a one-sentence version back?
Exactly the right move. Two function calls in sequence — search() gives you the raw snippet, then Agent(model).run_sync(...) compresses it. Here is the minimal shape:
results = search(query, count=5)
snippet = results[0]["snippet"]
result = Agent(model).run_sync(f"Summarize in one sentence: {snippet}")
print(result.output)The agent is the same Agent(model) you saw in ai-for-beginners — it doesn't care that the prompt came from a search result. To it, the snippet is just text.
So the agent has no idea there was a search step — it just reads what I give it. The composition happens entirely in my Python, not inside the agent.
Exactly the mental model. You are the glue. Search gets raw text; the agent reasons over it; your code decides which snippet gets summarized. Wrapped in a function:
def summarize_top_result(query: str) -> str:
results = search(query, count=5)
snippet = results[0]["snippet"]
prompt = f"Summarize in one sentence: {snippet}"
return Agent(model).run_sync(prompt).outputWhy use count=5 when I only read results[0]? Would count=1 be cheaper?
Slightly cheaper, but the engine ranks better when it has more candidates to sort through. count=5 gives the search a bigger pool, and you still only pay one agent call for the top one. The agent, not the search, is the expensive half of this function.
So every run gives me a live web snippet summarized by a live LLM — the numbers and wording change every time.
Exactly. Real retrieval, real generation. You've just written the smallest possible retrieval-augmented function — the foundation of every RAG pipeline you'll see in production.
TL;DR: search() retrieves text; Agent(model).run_sync(prompt) reasons over it; result.output is the plain string answer.
search() first — get the raw snippet.run_sync(prompt).output — chain the call and the field in one line| Step | Call | Returns |
|---|---|---|
| Retrieve | search(query, count=5) | list[dict] |
| Reason | Agent(model).run_sync(...) | result object |
| Extract | .output | str |
This is the RAG skeleton — retrieve, then reason. Every Week 2 lesson reuses it.
Week 1 ended with you pulling the top result's snippet out of search(). What is the smallest useful thing you can have an agent do with that snippet?
Summarize it? Feed the snippet in as a prompt and get a one-sentence version back?
Exactly the right move. Two function calls in sequence — search() gives you the raw snippet, then Agent(model).run_sync(...) compresses it. Here is the minimal shape:
results = search(query, count=5)
snippet = results[0]["snippet"]
result = Agent(model).run_sync(f"Summarize in one sentence: {snippet}")
print(result.output)The agent is the same Agent(model) you saw in ai-for-beginners — it doesn't care that the prompt came from a search result. To it, the snippet is just text.
So the agent has no idea there was a search step — it just reads what I give it. The composition happens entirely in my Python, not inside the agent.
Exactly the mental model. You are the glue. Search gets raw text; the agent reasons over it; your code decides which snippet gets summarized. Wrapped in a function:
def summarize_top_result(query: str) -> str:
results = search(query, count=5)
snippet = results[0]["snippet"]
prompt = f"Summarize in one sentence: {snippet}"
return Agent(model).run_sync(prompt).outputWhy use count=5 when I only read results[0]? Would count=1 be cheaper?
Slightly cheaper, but the engine ranks better when it has more candidates to sort through. count=5 gives the search a bigger pool, and you still only pay one agent call for the top one. The agent, not the search, is the expensive half of this function.
So every run gives me a live web snippet summarized by a live LLM — the numbers and wording change every time.
Exactly. Real retrieval, real generation. You've just written the smallest possible retrieval-augmented function — the foundation of every RAG pipeline you'll see in production.
TL;DR: search() retrieves text; Agent(model).run_sync(prompt) reasons over it; result.output is the plain string answer.
search() first — get the raw snippet.run_sync(prompt).output — chain the call and the field in one line| Step | Call | Returns |
|---|---|---|
| Retrieve | search(query, count=5) | list[dict] |
| Reason | Agent(model).run_sync(...) | result object |
| Extract | .output | str |
This is the RAG skeleton — retrieve, then reason. Every Week 2 lesson reuses it.
Create a free account to get started. Paid plans unlock all tracks.