Skip to content

Commit e62ee2c

Browse files
committed
init push
1 parent 97c20e8 commit e62ee2c

File tree

162 files changed

+42423
-11
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

162 files changed

+42423
-11
lines changed

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Zachary Huang
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
1-
<h1 align="center">Agentic Coding - Project Template</h1>
1+
<h1 align="center">Turns Codebase into Easy Tutorial</h1>
2+
3+
![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)
4+
5+
<p align="center">
6+
<i>Ever stared at a new codebase written by others feeling completely lost? This tutorial shows you how to build an AI agent that analyzes GitHub repositories and creates beginner-friendly tutorials explaining exactly how the code works.</i>
7+
</p>
28

39
<p align="center">
410
<a href="https://github.com/The-Pocket/PocketFlow" target="_blank">
511
<img
6-
src="./assets/banner.png" width="600"
12+
src="./assets/banner.png" width="800"
713
/>
814
</a>
915
</p>
1016

11-
12-
This is a project template for Agentic Coding with [Pocket Flow](https://github.com/The-Pocket/PocketFlow), a 100-line LLM framework, and Cursor.
17+
This project crawls GitHub repositories and build a knowledge base from the code:
18+
19+
- **Analyze entire codebases** to identify core abstractions and how they interact
20+
- **Transform complex code** into beginner-friendly tutorials with clear visualizations
21+
- **Build understanding systematically** from fundamentals to advanced concepts in logical steps
1322

14-
- We have included the [.cursorrules](.cursorrules) file to let Cursor AI help you build LLM projects.
15-
16-
- Want to learn how to build LLM projects with Agentic Coding?
17-
18-
- Check out the [Agentic Coding Guidance](https://the-pocket.github.io/PocketFlow/guide.html)
19-
20-
- Check out the [YouTube Tutorial](https://www.youtube.com/@ZacharyLLM?sub_confirmation=1)
23+
Built with [Pocket Flow](https://github.com/The-Pocket/PocketFlow), a 100-line LLM framework.

assets/banner.png

872 KB
Loading

output/AutoGen Core/01_agent.md

Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
# Chapter 1: Agent - The Workers of AutoGen
2+
3+
Welcome to the AutoGen Core tutorial! We're excited to guide you through building powerful applications with autonomous agents.
4+
5+
## Motivation: Why Do We Need Agents?
6+
7+
Imagine you want to build an automated system to write blog posts. You might need one part of the system to research a topic and another part to write the actual post based on the research. How do you represent these different "workers" and make them talk to each other?
8+
9+
This is where the concept of an **Agent** comes in. In AutoGen Core, an `Agent` is the fundamental building block representing an actor or worker in your system. Think of it like an employee in an office.
10+
11+
## Key Concepts: Understanding Agents
12+
13+
Let's break down what makes an Agent:
14+
15+
1. **It's a Worker:** An Agent is designed to *do* things. This could be running calculations, calling a Large Language Model (LLM) like ChatGPT, using a tool (like a search engine), or managing a piece of data.
16+
2. **It Has an Identity (`AgentId`):** Just like every employee has a name and a job title, every Agent needs a unique identity. This identity, called `AgentId`, has two parts:
17+
* `type`: What kind of role does the agent have? (e.g., "researcher", "writer", "coder"). This helps organize agents.
18+
* `key`: A unique name for this specific agent instance (e.g., "researcher-01", "amy-the-writer").
19+
20+
```python
21+
# From: _agent_id.py
22+
class AgentId:
23+
def __init__(self, type: str, key: str) -> None:
24+
# ... (validation checks omitted for brevity)
25+
self._type = type
26+
self._key = key
27+
28+
@property
29+
def type(self) -> str:
30+
return self._type
31+
32+
@property
33+
def key(self) -> str:
34+
return self._key
35+
36+
def __str__(self) -> str:
37+
# Creates an id like "researcher/amy-the-writer"
38+
return f"{self._type}/{self._key}"
39+
```
40+
This `AgentId` acts like the agent's address, allowing other agents (or the system) to send messages specifically to it.
41+
42+
3. **It Has Metadata (`AgentMetadata`):** Besides its core identity, an agent often has descriptive information.
43+
* `type`: Same as in `AgentId`.
44+
* `key`: Same as in `AgentId`.
45+
* `description`: A human-readable explanation of what the agent does (e.g., "Researches topics using web search").
46+
47+
```python
48+
# From: _agent_metadata.py
49+
from typing import TypedDict
50+
51+
class AgentMetadata(TypedDict):
52+
type: str
53+
key: str
54+
description: str
55+
```
56+
This metadata helps understand the agent's purpose within the system.
57+
58+
4. **It Communicates via Messages:** Agents don't work in isolation. They collaborate by sending and receiving messages. The primary way an agent receives work is through its `on_message` method. Think of this like the agent's inbox.
59+
60+
```python
61+
# From: _agent.py (Simplified Agent Protocol)
62+
from typing import Any, Mapping, Protocol
63+
# ... other imports
64+
65+
class Agent(Protocol):
66+
@property
67+
def id(self) -> AgentId: ... # The agent's unique ID
68+
69+
async def on_message(self, message: Any, ctx: MessageContext) -> Any:
70+
"""Handles an incoming message."""
71+
# Agent's logic to process the message goes here
72+
...
73+
```
74+
When an agent receives a message, `on_message` is called. The `message` contains the data or task, and `ctx` (MessageContext) provides extra information about the message (like who sent it). We'll cover `MessageContext` more later.
75+
76+
5. **It Can Remember Things (State):** Sometimes, an agent needs to remember information between tasks, like keeping notes on research progress. Agents can optionally implement `save_state` and `load_state` methods to store and retrieve their internal memory.
77+
78+
```python
79+
# From: _agent.py (Simplified Agent Protocol)
80+
class Agent(Protocol):
81+
# ... other methods
82+
83+
async def save_state(self) -> Mapping[str, Any]:
84+
"""Save the agent's internal memory."""
85+
# Return a dictionary representing the state
86+
...
87+
88+
async def load_state(self, state: Mapping[str, Any]) -> None:
89+
"""Load the agent's internal memory."""
90+
# Restore state from the dictionary
91+
...
92+
```
93+
We'll explore state and memory in more detail in [Chapter 7: Memory](07_memory.md).
94+
95+
6. **Different Agent Types:** AutoGen Core provides base classes to make creating agents easier:
96+
* `BaseAgent`: The fundamental class most agents inherit from. It provides common setup.
97+
* `ClosureAgent`: A very quick way to create simple agents using just a function (like hiring a temp worker for a specific task defined on the spot).
98+
* `RoutedAgent`: An agent that can automatically direct different types of messages to different internal handler methods (like a smart receptionist).
99+
100+
## Use Case Example: Researcher and Writer
101+
102+
Let's revisit our blog post example. We want a `Researcher` agent and a `Writer` agent.
103+
104+
**Goal:**
105+
1. Tell the `Researcher` a topic (e.g., "AutoGen Agents").
106+
2. The `Researcher` finds some facts (we'll keep it simple and just make them up for now).
107+
3. The `Researcher` sends these facts to the `Writer`.
108+
4. The `Writer` receives the facts and drafts a short post.
109+
110+
**Simplified Implementation Idea (using `ClosureAgent` for brevity):**
111+
112+
First, let's define the messages they might exchange:
113+
114+
```python
115+
from dataclasses import dataclass
116+
117+
@dataclass
118+
class ResearchTopic:
119+
topic: str
120+
121+
@dataclass
122+
class ResearchFacts:
123+
topic: str
124+
facts: list[str]
125+
126+
@dataclass
127+
class DraftPost:
128+
topic: str
129+
draft: str
130+
```
131+
These are simple Python classes to hold the data being passed around.
132+
133+
Now, let's imagine defining the `Researcher` using a `ClosureAgent`. This agent will listen for `ResearchTopic` messages.
134+
135+
```python
136+
# Simplified concept - requires AgentRuntime (Chapter 3) to actually run
137+
138+
async def researcher_logic(agent_context, message: ResearchTopic, msg_context):
139+
print(f"Researcher received topic: {message.topic}")
140+
# In a real scenario, this would involve searching, calling an LLM, etc.
141+
# For now, we just make up facts.
142+
facts = [f"Fact 1 about {message.topic}", f"Fact 2 about {message.topic}"]
143+
print(f"Researcher found facts: {facts}")
144+
145+
# Find the Writer agent's ID (we assume we know it)
146+
writer_id = AgentId(type="writer", key="blog_writer_1")
147+
148+
# Send the facts to the Writer
149+
await agent_context.send_message(
150+
message=ResearchFacts(topic=message.topic, facts=facts),
151+
recipient=writer_id,
152+
)
153+
print("Researcher sent facts to Writer.")
154+
# This agent doesn't return a direct reply
155+
return None
156+
```
157+
This `researcher_logic` function defines *what* the researcher does when it gets a `ResearchTopic` message. It processes the topic, creates `ResearchFacts`, and uses `agent_context.send_message` to send them to the `writer` agent.
158+
159+
Similarly, the `Writer` agent would have its own logic:
160+
161+
```python
162+
# Simplified concept - requires AgentRuntime (Chapter 3) to actually run
163+
164+
async def writer_logic(agent_context, message: ResearchFacts, msg_context):
165+
print(f"Writer received facts for topic: {message.topic}")
166+
# In a real scenario, this would involve LLM prompting
167+
draft = f"Blog Post about {message.topic}:\n"
168+
for fact in message.facts:
169+
draft += f"- {fact}\n"
170+
print(f"Writer drafted post:\n{draft}")
171+
172+
# Perhaps save the draft or send it somewhere else
173+
# For now, we just print it. We don't send another message.
174+
return None # Or maybe return a confirmation/result
175+
```
176+
This `writer_logic` function defines how the writer reacts to receiving `ResearchFacts`.
177+
178+
**Important:** To actually *run* these agents and make them communicate, we need the `AgentRuntime` (covered in [Chapter 3: AgentRuntime](03_agentruntime.md)) and the `Messaging System` (covered in [Chapter 2: Messaging System](02_messaging_system__topic___subscription_.md)). For now, focus on the *idea* that Agents are distinct workers defined by their logic (`on_message`) and identified by their `AgentId`.
179+
180+
## Under the Hood: How an Agent Gets a Message
181+
182+
While the full message delivery involves the `Messaging System` and `AgentRuntime`, let's look at the agent's role when it receives a message.
183+
184+
**Conceptual Flow:**
185+
186+
```mermaid
187+
sequenceDiagram
188+
participant Sender as Sender Agent
189+
participant Runtime as AgentRuntime
190+
participant Recipient as Recipient Agent
191+
192+
Sender->>+Runtime: send_message(message, recipient_id)
193+
Runtime->>+Recipient: Locate agent by recipient_id
194+
Runtime->>+Recipient: on_message(message, context)
195+
Recipient->>Recipient: Process message using internal logic
196+
alt Response Needed
197+
Recipient->>-Runtime: Return response value
198+
Runtime->>-Sender: Deliver response value
199+
else No Response
200+
Recipient->>-Runtime: Return None (or no return)
201+
end
202+
```
203+
204+
1. Some other agent (Sender) or the system decides to send a message to our agent (Recipient).
205+
2. It tells the `AgentRuntime` (the manager): "Deliver this `message` to the agent with `recipient_id`".
206+
3. The `AgentRuntime` finds the correct `Recipient` agent instance.
207+
4. The `AgentRuntime` calls the `Recipient.on_message(message, context)` method.
208+
5. The agent's internal logic inside `on_message` (or methods called by it, like in `RoutedAgent`) runs to process the message.
209+
6. If the message requires a direct response (like an RPC call), the agent returns a value from `on_message`. If not (like a general notification or event), it might return `None`.
210+
211+
**Code Glimpse:**
212+
213+
The core definition is the `Agent` Protocol (`_agent.py`). It's like an interface or a contract – any class wanting to be an Agent *must* provide these methods.
214+
215+
```python
216+
# From: _agent.py - The Agent blueprint (Protocol)
217+
218+
@runtime_checkable
219+
class Agent(Protocol):
220+
@property
221+
def metadata(self) -> AgentMetadata: ...
222+
223+
@property
224+
def id(self) -> AgentId: ...
225+
226+
async def on_message(self, message: Any, ctx: MessageContext) -> Any: ...
227+
228+
async def save_state(self) -> Mapping[str, Any]: ...
229+
230+
async def load_state(self, state: Mapping[str, Any]) -> None: ...
231+
232+
async def close(self) -> None: ...
233+
```
234+
235+
Most agents you create will inherit from `BaseAgent` (`_base_agent.py`). It provides some standard setup:
236+
237+
```python
238+
# From: _base_agent.py (Simplified)
239+
class BaseAgent(ABC, Agent):
240+
def __init__(self, description: str) -> None:
241+
# Gets runtime & id from a special context when created by the runtime
242+
# Raises error if you try to create it directly!
243+
self._runtime: AgentRuntime = AgentInstantiationContext.current_runtime()
244+
self._id: AgentId = AgentInstantiationContext.current_agent_id()
245+
self._description = description
246+
# ...
247+
248+
# This is the final version called by the runtime
249+
@final
250+
async def on_message(self, message: Any, ctx: MessageContext) -> Any:
251+
# It calls the implementation method you need to write
252+
return await self.on_message_impl(message, ctx)
253+
254+
# You MUST implement this in your subclass
255+
@abstractmethod
256+
async def on_message_impl(self, message: Any, ctx: MessageContext) -> Any: ...
257+
258+
# Helper to send messages easily
259+
async def send_message(self, message: Any, recipient: AgentId, ...) -> Any:
260+
# It just asks the runtime to do the actual sending
261+
return await self._runtime.send_message(
262+
message, sender=self.id, recipient=recipient, ...
263+
)
264+
# ... other methods like publish_message, save_state, load_state
265+
```
266+
Notice how `BaseAgent` handles getting its `id` and `runtime` during creation and provides a convenient `send_message` method that uses the runtime. When inheriting from `BaseAgent`, you primarily focus on implementing the `on_message_impl` method to define your agent's unique behavior.
267+
268+
## Next Steps
269+
270+
You now understand the core concept of an `Agent` in AutoGen Core! It's the fundamental worker unit with an identity, the ability to process messages, and optionally maintain state.
271+
272+
In the next chapters, we'll explore:
273+
274+
* [Chapter 2: Messaging System](02_messaging_system__topic___subscription_.md): How messages actually travel between agents.
275+
* [Chapter 3: AgentRuntime](03_agentruntime.md): The manager responsible for creating, running, and connecting agents.
276+
277+
Let's continue building your understanding!
278+
279+
---
280+
281+
Generated by [AI Codebase Knowledge Builder](https://github.com/The-Pocket/Tutorial-Codebase-Knowledge)

0 commit comments

Comments
 (0)