Skip to content

Commit f738fcd

Browse files
jssmithtconley1428
andauthored
Reorganize OpenAI samples (#221)
* update for plugins * formatting * reference main branch * cleanup * switch to plugins on the runners * move around samples * update README files * formatting update * formatting * timeout adjustments * Reset uv.lock --------- Co-authored-by: Tim Conley <timothy.conley@temporal.io>
1 parent 85e9843 commit f738fcd

27 files changed

+287
-56
lines changed

openai_agents/README.md

Lines changed: 6 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -21,42 +21,13 @@ This approach ensures that AI agent workflows are durable, observable, and can h
2121
- Required dependencies installed via `uv sync --group openai-agents`
2222
- OpenAI API key set as environment variable: `export OPENAI_API_KEY=your_key_here`
2323

24-
## Running the Examples
24+
## Examples
2525

26-
1. **Start the worker** (supports all samples):
27-
```bash
28-
uv run openai_agents/run_worker.py
29-
```
26+
Each directory contains a complete example with its own README for detailed instructions:
3027

31-
2. **Run individual samples** in separate terminals:
28+
- **[Basic Examples](./basic/README.md)** - Simple agent examples including a hello world agent and a tools-enabled agent that can access external APIs like weather services.
29+
- **[Agent Patterns](./agent_patterns/README.md)** - Advanced patterns for agent composition, including using agents as tools within other agents.
30+
- **[Research Bot](./research_bot/README.md)** - Multi-agent research system with specialized roles: a planner agent, search agent, and writer agent working together to conduct comprehensive research.
31+
- **[Customer Service](./customer_service/README.md)** - Interactive customer service agent with escalation capabilities, demonstrating conversational workflows.
3232

33-
### Basic Agent Examples
34-
35-
- **Hello World Agent** - Simple agent that responds in haikus:
36-
```bash
37-
uv run openai_agents/run_hello_world_workflow.py
38-
```
39-
40-
- **Tools Agent** - Agent with access to external tools (weather API):
41-
```bash
42-
uv run openai_agents/run_tools_workflow.py
43-
```
44-
45-
### Advanced Multi-Agent Examples
46-
47-
- **Research Workflow** - Multi-agent research system with specialized roles:
48-
```bash
49-
uv run openai_agents/run_research_workflow.py
50-
```
51-
Features a planner agent, search agent, and writer agent working together.
52-
53-
- **Customer Service Workflow** - Customer service agent with escalation capabilities (interactive):
54-
```bash
55-
uv run openai_agents/run_customer_service_client.py --conversation-id my-conversation-123
56-
```
57-
58-
- **Agents as Tools** - Demonstrate using agents as tools within other agents:
59-
```bash
60-
uv run openai_agents/run_agents_as_tools_workflow.py
61-
```
6233

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Agent Patterns
2+
3+
Common agentic patterns extended with Temporal's durable execution capabilities.
4+
5+
*Adapted from [OpenAI Agents SDK agent patterns](https://github.com/openai/openai-agents-python/tree/main/examples/agent_patterns)*
6+
7+
## Running the Examples
8+
9+
First, start the worker (supports all patterns):
10+
```bash
11+
uv run openai_agents/agent_patterns/run_worker.py
12+
```
13+
14+
Then run individual examples in separate terminals:
15+
16+
## Deterministic Flows
17+
18+
**TODO**
19+
20+
A common tactic is to break down a task into a series of smaller steps. Each task can be performed by an agent, and the output of one agent is used as input to the next. For example, if your task was to generate a story, you could break it down into the following steps:
21+
22+
1. Generate an outline
23+
2. Generate the story
24+
3. Generate the ending
25+
26+
Each of these steps can be performed by an agent. The output of one agent is used as input to the next.
27+
28+
## Handoffs and Routing
29+
30+
**TODO**
31+
32+
In many situations, you have specialized sub-agents that handle specific tasks. You can use handoffs to route the task to the right agent.
33+
34+
For example, you might have a frontline agent that receives a request, and then hands off to a specialized agent based on the language of the request.
35+
36+
## Agents as Tools
37+
38+
The mental model for handoffs is that the new agent "takes over". It sees the previous conversation history, and owns the conversation from that point onwards. However, this is not the only way to use agents. You can also use agents as a tool - the tool agent goes off and runs on its own, and then returns the result to the original agent.
39+
40+
For example, you could model a translation task as tool calls instead: rather than handing over to the language-specific agent, you could call the agent as a tool, and then use the result in the next step. This enables things like translating multiple languages at once.
41+
42+
```bash
43+
uv run openai_agents/agent_patterns/run_agents_as_tools_workflow.py
44+
```
45+
46+
## LLM-as-a-Judge
47+
48+
**TODO**
49+
50+
LLMs can often improve the quality of their output if given feedback. A common pattern is to generate a response using a model, and then use a second model to provide feedback. You can even use a small model for the initial generation and a larger model for the feedback, to optimize cost.
51+
52+
For example, you could use an LLM to generate an outline for a story, and then use a second LLM to evaluate the outline and provide feedback. You can then use the feedback to improve the outline, and repeat until the LLM is satisfied with the outline.
53+
54+
## Parallelization
55+
56+
**TODO**
57+
58+
Running multiple agents in parallel is a common pattern. This can be useful for both latency (e.g. if you have multiple steps that don't depend on each other) and also for other reasons e.g. generating multiple responses and picking the best one.
59+
60+
## Guardrails
61+
62+
**TODO**
63+
64+
Related to parallelization, you often want to run input guardrails to make sure the inputs to your agents are valid. For example, if you have a customer support agent, you might want to make sure that the user isn't trying to ask for help with a math problem.
65+
66+
You can definitely do this without any special Agents SDK features by using parallelization, but we support a special guardrail primitive. Guardrails can have a "tripwire" - if the tripwire is triggered, the agent execution will immediately stop and a `GuardrailTripwireTriggered` exception will be raised.
67+
68+
This is really useful for latency: for example, you might have a very fast model that runs the guardrail and a slow model that runs the actual agent. You wouldn't want to wait for the slow model to finish, so guardrails let you quickly reject invalid inputs.

openai_agents/run_agents_as_tools_workflow.py renamed to openai_agents/agent_patterns/run_agents_as_tools_workflow.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
from temporalio.client import Client
44
from temporalio.contrib.openai_agents import OpenAIAgentsPlugin
55

6-
from openai_agents.workflows.agents_as_tools_workflow import AgentsAsToolsWorkflow
6+
from openai_agents.agent_patterns.workflows.agents_as_tools_workflow import (
7+
AgentsAsToolsWorkflow,
8+
)
79

810

911
async def main():
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from __future__ import annotations
2+
3+
import asyncio
4+
from datetime import timedelta
5+
6+
from temporalio.client import Client
7+
from temporalio.contrib.openai_agents import ModelActivityParameters, OpenAIAgentsPlugin
8+
from temporalio.worker import Worker
9+
10+
from openai_agents.agent_patterns.workflows.agents_as_tools_workflow import (
11+
AgentsAsToolsWorkflow,
12+
)
13+
14+
15+
async def main():
16+
# Create client connected to server at the given address
17+
client = await Client.connect(
18+
"localhost:7233",
19+
plugins=[
20+
OpenAIAgentsPlugin(
21+
model_params=ModelActivityParameters(
22+
start_to_close_timeout=timedelta(seconds=30)
23+
)
24+
),
25+
],
26+
)
27+
28+
worker = Worker(
29+
client,
30+
task_queue="openai-agents-task-queue",
31+
workflows=[
32+
AgentsAsToolsWorkflow,
33+
],
34+
)
35+
await worker.run()
36+
37+
38+
if __name__ == "__main__":
39+
asyncio.run(main())

openai_agents/basic/README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Basic Agent Examples
2+
3+
Simple examples to get started with OpenAI Agents SDK integrated with Temporal workflows.
4+
5+
*Adapted from [OpenAI Agents SDK basic examples](https://github.com/openai/openai-agents-python/tree/main/examples/basic)*
6+
7+
## Running the Examples
8+
9+
First, start the worker (supports all basic examples):
10+
```bash
11+
uv run openai_agents/basic/run_worker.py
12+
```
13+
14+
Then run individual examples in separate terminals:
15+
16+
### Hello World Agent
17+
```bash
18+
uv run openai_agents/basic/run_hello_world_workflow.py
19+
```
20+
21+
### Tools Agent
22+
Agent with access to external tools (weather API):
23+
```bash
24+
uv run openai_agents/basic/run_tools_workflow.py
25+
```

openai_agents/run_hello_world_workflow.py renamed to openai_agents/basic/run_hello_world_workflow.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from temporalio.client import Client
44
from temporalio.contrib.openai_agents import OpenAIAgentsPlugin
55

6-
from openai_agents.workflows.hello_world_workflow import HelloWorldAgent
6+
from openai_agents.basic.workflows.hello_world_workflow import HelloWorldAgent
77

88

99
async def main():

openai_agents/run_tools_workflow.py renamed to openai_agents/basic/run_tools_workflow.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from temporalio.client import Client
44
from temporalio.contrib.openai_agents import OpenAIAgentsPlugin
55

6-
from openai_agents.workflows.tools_workflow import ToolsWorkflow
6+
from openai_agents.basic.workflows.tools_workflow import ToolsWorkflow
77

88

99
async def main():

openai_agents/run_worker.py renamed to openai_agents/basic/run_worker.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,9 @@
77
from temporalio.contrib.openai_agents import ModelActivityParameters, OpenAIAgentsPlugin
88
from temporalio.worker import Worker
99

10-
from openai_agents.workflows.agents_as_tools_workflow import AgentsAsToolsWorkflow
11-
from openai_agents.workflows.customer_service_workflow import CustomerServiceWorkflow
12-
from openai_agents.workflows.get_weather_activity import get_weather
13-
from openai_agents.workflows.hello_world_workflow import HelloWorldAgent
14-
from openai_agents.workflows.research_bot_workflow import ResearchWorkflow
15-
from openai_agents.workflows.tools_workflow import ToolsWorkflow
10+
from openai_agents.basic.activities.get_weather_activity import get_weather
11+
from openai_agents.basic.workflows.hello_world_workflow import HelloWorldAgent
12+
from openai_agents.basic.workflows.tools_workflow import ToolsWorkflow
1613

1714

1815
async def main():
@@ -22,7 +19,7 @@ async def main():
2219
plugins=[
2320
OpenAIAgentsPlugin(
2421
model_params=ModelActivityParameters(
25-
start_to_close_timeout=timedelta(seconds=120)
22+
start_to_close_timeout=timedelta(seconds=30)
2623
)
2724
),
2825
],
@@ -34,9 +31,6 @@ async def main():
3431
workflows=[
3532
HelloWorldAgent,
3633
ToolsWorkflow,
37-
ResearchWorkflow,
38-
CustomerServiceWorkflow,
39-
AgentsAsToolsWorkflow,
4034
],
4135
activities=[
4236
get_weather,

0 commit comments

Comments
 (0)