Define specialist agents
from polos import Agent
grammar_agent = Agent(
id="grammar_reviewer",
provider="openai",
model="gpt-4o-mini",
system_prompt="Review text for grammar, spelling, and punctuation.",
)
tone_agent = Agent(
id="tone_reviewer",
provider="openai",
model="gpt-4o-mini",
system_prompt="Review text for tone consistency and style.",
)
editor_agent = Agent(
id="final_editor",
provider="openai",
model="gpt-4o-mini",
system_prompt="Produce a polished version incorporating all feedback.",
)
import { defineAgent, maxSteps } from '@polos/sdk';
import { openai } from '@ai-sdk/openai';
const grammarReviewAgent = defineAgent({
id: 'grammar_reviewer',
model: openai('gpt-4o-mini'),
systemPrompt: 'Review text for grammar, spelling, and punctuation.',
stopConditions: [maxSteps({ count: 3 })],
});
const toneConsistencyAgent = defineAgent({
id: 'tone_reviewer',
model: openai('gpt-4o-mini'),
systemPrompt: 'Review text for tone consistency and style.',
stopConditions: [maxSteps({ count: 3 })],
});
const finalEditorAgent = defineAgent({
id: 'final_editor',
model: openai('gpt-4o-mini'),
systemPrompt: 'Produce a polished version incorporating all feedback.',
stopConditions: [maxSteps({ count: 3 })],
});
Run agents in parallel
from polos import workflow, WorkflowContext
@workflow(id="blog_review")
async def blog_review(ctx: WorkflowContext, payload):
text = payload["text"]
# Run all reviews in parallel
reviews = await ctx.step.batch_agent_invoke_and_wait(
"parallel_reviews",
[
grammar_agent.with_input(f"Review for grammar:\n\n{text}"),
tone_agent.with_input(f"Review for tone:\n\n{text}"),
]
)
grammar_feedback = reviews[0].result.result
tone_feedback = reviews[1].result.result
# Final edit with all feedback
final = await ctx.step.agent_invoke_and_wait(
"final_edit",
editor_agent.with_input(f"""Original: {text}
Grammar feedback: {grammar_feedback}
Tone feedback: {tone_feedback}
Produce the final polished version.""")
)
return {"final_text": final.result}
import { defineWorkflow } from '@polos/sdk';
const blogReview = defineWorkflow<BlogReviewPayload, unknown, BlogReviewResult>(
{ id: 'blog_review' },
async (ctx, payload) => {
const text = payload.text;
// Run all reviews in parallel
const reviewResults = await ctx.step.batchAgentInvokeAndWait<Record<string, unknown>>(
'parallel_reviews',
[
grammarReviewAgent.withInput(`Review for grammar:\n\n${text}`),
toneConsistencyAgent.withInput(`Review for tone:\n\n${text}`),
],
);
const grammarFeedback = (reviewResults[0]?.['result'] as string) ?? '';
const toneFeedback = (reviewResults[1]?.['result'] as string) ?? '';
// Final edit with all feedback
const editorResult = (await ctx.step.agentInvokeAndWait(
'final_editor',
finalEditorAgent.withInput(
`Original: ${text}\n\nGrammar feedback: ${grammarFeedback}\nTone feedback: ${toneFeedback}\n\nProduce the final polished version.`,
),
)) as Record<string, unknown>;
return { originalText: text, grammarReview: grammarFeedback, toneReview: toneFeedback, finalText: (editorResult['result'] as string) ?? '' };
},
);
Run it
git clone https://github.com/polos-dev/polos.git
cd polos/python-examples/14-router-coordinator
cp .env.example .env # Add your POLOS_PROJECT_ID and API key
uv sync
python main.py
git clone https://github.com/polos-dev/polos.git
cd polos/typescript-examples/14-router-coordinator
cp .env.example .env # Add your POLOS_PROJECT_ID and API key
npm install
npx tsx main.ts