createLLMNode
workflow.createLLMNode() Creates a one-time LLM invocation node. When the node executes, it will first parse the provider, then call provider.chat(llmInput), and finally convert the LLM output into business payload through mapOutput.
Signature
workflow.createLLMNode<Input>(
options: LLMNodeOptions<Input, LLMChatOutput>,
): BaseNode<Input, LLMChatOutput>
workflow.createLLMNode<Input, Output>(
options: LLMNodeOptions<Input, Output> & {
mapOutput: LLMOutputMapper<Input, Output>;
},
): BaseNode<Input, Output>
Parameter
| Parameter | Type | Description |
|---|---|---|
options | LLMNodeOptions<Input, Output> | Define provider, input mappings, output mappings, and node meta information. |
LLMNodeOptions
| Field | Type | Description |
|---|---|---|
name | string | Node name, default "llm". provider binding to override the provider by that name. |
provider | LLMProviderSource | provider instance, provider id, provider ref, or resolver. Required. |
mapInput | (input, context) => LLMChatInput | Translate the business input into an LLM request. Required. |
mapOutput | (output, input, context) => Output | Converts the LLM output to business output; returns the original LLMChatOutput when not passed. |
historyLimit | number | The number of nodes retained in the execution history. The default value is 50. |
metadata | WorkflowNodeMetadataInput | The node displays meta information. |
LLMProviderSource
| Form | Type | Description |
|---|---|---|
| provider examples | LLMProvider | Use the callable provider directly. |
| provider id | string | Lookup from context.providers.llmProviders. |
| provider ref | LLMProviderRef | Delay parsing by id and configure the fallback. |
| resolver | (context, nodeName) => LLMProvider | undefined | Dynamically selects provider by node or context. |
LLMChatInput
| Field | Type | Description |
|---|---|---|
prompt | string | Single prompt; and messages two-choice 1. |
messages | ModelMessage[] | Multi-round message; 1 with prompt binary. |
system | string | System prompt. |
temperature | number | Sampling temperature. |
maxOutputTokens | number | The maximum number of output tokens. |
topP / topK | number | Sampling parameters. |
presencePenalty / frequencyPenalty | number | Repeat the penalty parameter. |
stopSequences | string[] | Stop the sequence. |
seed | number | Random seed. |
maxRetries | number | Number of retries. |
timeout | number | The call timed out. |
headers | object | Extra request header. |
providerOptions | LLMProviderOptions | provider private extension parameters. |
abortSignal | AbortSignal | Nodes are automatically injected from context.abortSignal. |
Output
| Situation | Node Output Type | Description |
|---|---|---|
Not passed mapOutput | LLMChatOutput | Returns the provider chat result as it is. |
Imported mapOutput | Output | Returns the result of mapOutput(output, input, context). |
LLMChatOutput
| Field | Type | Description |
|---|---|---|
text | string | Model text output. |
finishReason | FinishReason | undefined | Stop the cause. |
usage | LanguageModelUsage | undefined | token usage. |
providerMetadata | ProviderMetadata | undefined | provider meta information. |
When an executor configures tokenUsage: { enabled: true }, the provider resolved by getLLMProvider() reports LLMChatOutput.usage to context.tokenUsage after chat returns, so accounting still works when mapOutput omits usage. The run aggregate appears in report.tokenUsage.run; cumulative totals are written to the current project's KV and, when present, its conversation KV. Server derives the system total by aggregating project totals. Input, output, reasoning, cached-input, and cache-creation token details are supported.
Call process
| Phase | Input | Result |
|---|---|---|
| Upstream node | Input | Business input |
mapInput | Input, NodeContext | LLMChatInput |
provider chat | LLMChatInput | LLMChatOutput |
mapOutput | LLMChatOutput, Input, NodeContext | Output |
Example
const llmNode = workflow.createLLMNode<ParsedInput, AnswerPayload>({
name: "answer",
provider: workflow.createLLMProviderRef("default"),
mapInput(input) {
return {
system: "You answer briefly.",
prompt: input.message,
temperature: 0.2,
};
},
mapOutput(output) {
return {
errCode: 0,
errMessage: "",
content: output.text,
};
},
});