#Human in the loop workflow
9 messages · Page 1 of 1 (latest)
Hi @hushed river. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
To implement a "human in the loop" workflow using the Convex Workflow component, you should combine the Workflow component's durable, multi-step orchestration with the Agent component's support for human agents and tool calls.
Key Steps
-
Expose Agent Actions for Workflow Steps
Use the Agent component to expose actions that can be called from within a workflow. For example, you can create actions for generating LLM responses, saving messages, or requesting human input. These actions can be used as steps in your workflow, each with configurable retries and idempotency guarantees. -
Insert Human Steps via Tool Calls
You can provide a tool to the LLM that, when invoked, signals that human intervention is required. This is done by defining a tool (e.g.,askHuman) and handling its invocation by pausing the workflow and notifying a human agent to respond. The human's response is then saved and the workflow resumes. This pattern is shown in the "Human responses as tool calls" example:const askHuman = tool({ description: "Ask a human a question", parameters: z.object({ question: z.string().describe("The question to ask the human"), }), }); export const ask = action({ args: { question: v.string(), threadId: v.string() }, handler: async (ctx, { question, threadId }) => { const result = await agent.generateText( ctx, { threadId }, { prompt: question, tools: { askHuman }, }, ); // Handle tool call and notify human agent }, });The human's response is then saved and the workflow can continue from where it left off by invoking another action or step in the workflow.
See full example
-
Define the Workflow
Use the Workflow component to define your workflow, orchestrating both LLM and human steps. Each step can be a mutation or action, and you can use the workflow's durability to ensure the process resumes after human input or server restarts.export const supportAgentWorkflow = workflow.define({ args: { prompt: v.string(), userId: v.string() }, handler: async (step, { prompt, userId }) => { // Create thread, get LLM suggestion, possibly request human input // Wait for human response, then continue }, });
Best Practices
- Use tool calls to let the LLM decide when human input is needed.
- Store workflow state and messages in threads, so the UI can reactively update as the workflow progresses.
- Leverage the workflow's durability and retry features to handle unreliable steps and ensure completion, even if human input introduces delays.
Summary
The best way to implement human-in-the-loop with Convex is to use the Workflow component to orchestrate both automated (LLM) and human steps, leveraging tool calls to pause for human input and resume the workflow once the input is received. This approach ensures reliability, durability, and a reactive user experience.
For detailed code examples, see the Human responses as tool calls and Workflow with agent actions documentation.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@hushed river Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@tepid badge Can workflows be paused and resumed without agents? Maybe through a webhook or some other type of trigger to both pause and resume.
Let me check the knowledge base for you again. One moment! :books:
Based on the available knowledge sources, Convex workflows are designed to be durable and can survive server restarts, allowing them to resume from where they left off after interruptions. The Workflow component supports pausing at steps (such as waiting for human input) and resuming when the required input or event occurs. This is typically implemented by saving the workflow state and continuing execution when the next step is triggered, for example, by a user action or an external event.
However, the documentation does not explicitly mention a built-in mechanism to "pause" and "resume" workflows arbitrarily via webhooks or external triggers, outside of the agent/human-in-the-loop use case. The pausing and resuming described are generally tied to workflow logic—such as waiting for input or a scheduled delay—rather than an external pause/resume API.
That said, you can design your workflow handler to wait for an external event (such as a webhook or trigger) by having a step that checks for a condition or waits for a signal (e.g., a database flag or message). When the external event occurs, you could update the relevant state in Convex, and the workflow can be resumed by scheduling the next step. This pattern is not described as a built-in feature, but it is implied by the flexibility of the workflow handler and the ability to react to state changes or external inputs.
In summary:
- Workflows can be paused and resumed as part of their logic (e.g., waiting for input or a scheduled time).
- There is no explicit mention of a generic "pause/resume" API via webhooks or triggers, but you can implement similar behavior by designing your workflow steps to wait for external signals and resume accordingly.
If you need a concrete example or further details, the knowledge sources do not provide one, so you may need to experiment or ask the Convex team for more guidance on this pattern.