Skip to Content
ExamplesBlog writer

Blog writer

Breaking down complex tasks into smaller, discrete steps is one of the best ways to improve the quality of LLM outputs. The blog writer workflow example does this by following the same approach a human would take to write a blog post: first conducting research, then generating a first draft, and finally editing that draft.

Workflow

The Blog Writer workflow consists of the following steps:

  1. Parallel research phase:
    • Brainstorm topics using LLM (<BrainstormTopics>)
    • Research each topic in detail (<ResearchTopic>)
    • Gather web research (<SearchWeb>)
  2. Write initial draft based on research (<WriteDraft>)
  3. Edit and polish the content (<EditDraft>)

Running the example

# Install dependencies pnpm install # Set your OpenAI API key export OPENAI_API_KEY=<your_api_key> # Run the example pnpm run start

Key patterns

Running components in parallel

The <Research> component runs both the BrainstormTopics and SearchWeb components in parallel. Both sub-workflows return an array of strings which are automatically combined into a single array.

const Research = gensx.Component<ResearchComponentProps, ResearchOutput>( "Research", ({ prompt }) => { return ( <> <BrainstormTopics prompt={prompt}> {({ topics }) => { return topics.map((topic) => <ResearchTopic topic={topic} />); }} </BrainstormTopics> <SearchWeb prompt={prompt} /> </> ); }, );

Streaming Output

The workflow streams back the final output to reduce the time that it takes for the user to receive the first token. The <EditDraft> component is a StreamComponent and the <ChatCompletion> component has stream={true}.

const EditDraft = gensx.StreamComponent<EditDraftProps>( "EditDraft", ({ draft }) => { return ( <ChatCompletion stream={true} model="gpt-4o-mini" temperature={0} messages={[ { role: "system", content: systemPrompt }, { role: "user", content: draft }, ]} /> ); }, );

Then when the component is invoked, stream={true} is passed to the component so that the output is streamed back and can be surfaced to the user:

<EditDraft draft={draft} stream={true} />

Additional resources

Check out the other examples in the GenSX Github Repo.

Last updated on