Design, execute, and validate an n8n workflow that converts topic metadata into a structured article brief—without letting an unreviewed model response reach production.
设计并实测一条 n8n 工作流,把选题元数据转换成结构化文章策划,同时阻止未经审核的模型输出直接进入发布流程。
Tested on n8n 2.42.725 October 2026Workflow automationBilingual / 中英文
Local execution evidencen8n 2.42.7 · three test cases · structured output and validation logs captured from the running editor.
01 / Scope
Build a review gate, not an autopilot
AI automation earns its keep when it removes a specific repetitive step. Here, that step is turning scattered topic notes into a structured article brief that an editor can evaluate in under five minutes. The agent proposes the angle, outline, tests, screenshot plan, and claims requiring evidence. It does not verify search demand, invent citations, or publish anything.
AI 自动化只有解决具体重复工作时才真正有价值。这里要解决的问题,是把零散选题整理成编辑能在五分钟内评估的结构化文章策划。Agent 负责提出切入角度、大纲、测试方案、截图计划和待核实主张,但不会编造搜索热度、虚构引用,也不会直接发布内容。
Production rule: every model-generated brief starts as draft. It can enter writing only after a person checks evidence, test coverage, and screenshot requirements.
生产规则:所有模型生成的策划初始状态都是 draft。只有人工确认证据、测试覆盖和截图要求后,才能进入写作阶段。

02 / Prerequisites
Keep the first version small
You need an n8n Cloud or self-hosted instance, access to a supported chat model, a stored credential, and one review destination. A spreadsheet row is enough for the first version; Slack, Notion, or a project-management tool can come later.
你需要一个 n8n Cloud 或自托管实例、一个受支持的聊天模型、已保存的模型凭据,以及一个审核目的地。第一版写入电子表格的一行就够,Slack、Notion 或项目管理工具可以之后再接。
| Component | Purpose | First-version choice |
|---|---|---|
| Trigger / 触发器 | Run the workflow only during controlled tests. 在受控测试中手动运行。 | Manual Trigger |
| Input / 输入 | Define a typed topic contract. 定义带类型的选题输入。 | Edit Fields |
| Model / 模型 | Generate the brief through a chat-model sub-node. 通过聊天模型子节点生成策划。 | OpenAI Chat Model or your supported provider |
| Format / 格式 | Force one machine-readable object. 强制输出一个机器可读对象。 | Structured Output Parser |
| Validation / 校验 | Check schema and editorial rules. 检查结构规则和编辑规则。 | Code + If |
Self-hosting does not make the whole system free. Count hosting, model calls, and any review destination as separate cost lines.
自托管并不意味着整条链路免费。主机、模型调用以及审核工具应分别计入成本。
03 / Input contract
Define the topic before calling the model
The Manual Trigger starts the run. The Edit Fields node then creates a small JSON contract. This makes tests repeatable and gives the validation code something concrete to inspect.
Manual Trigger 负责启动运行,Edit Fields 节点创建一个小型 JSON 契约。这样测试可以复现,也给校验代码提供了明确检查对象。
Manual Trigger→Set Topic→Validate Input→AI Agent
topic-input.jsonCopy
{
"topic": "How to summarize a PDF with AI",
"audience": "beginner and intermediate technology users",
"language": "English",
"article_type": "hands-on tutorial"
}
The four fields have different jobs: topic names the task, audience constrains depth, language controls output, and article_type determines whether the agent should optimize for procedure, comparison, troubleshooting, or analysis.
四个字段承担不同职责:topic 描述任务,audience 限制内容深度,language 控制输出语言,article_type 决定 Agent 应按教程、对比、排错还是分析来组织内容。
Fail fast on empty input
Do not spend a model call on an empty topic. The first Code node checks required fields and emits a deterministic status before the AI Agent runs.
不要在主题为空时浪费一次模型调用。第一个 Code 节点会在 AI Agent 运行前检查必填字段,并输出确定性的状态。
validate-input.js · Run Once for All ItemsCopy
return $input.all().map((item) => {
const input = item.json;
const errors = [];
if (typeof input.topic !== 'string' || input.topic.trim().length < 8) {
errors.push('topic must contain at least 8 non-space characters');
}
if (typeof input.audience !== 'string' || !input.audience.trim()) {
errors.push('audience is required');
}
if (typeof input.language !== 'string' || !input.language.trim()) {
errors.push('language is required');
}
if (typeof input.article_type !== 'string' || !input.article_type.trim()) {
errors.push('article_type is required');
}
return {
json: {
...input,
input_validation: {
passed: errors.length === 0,
errors
},
review_status: errors.length === 0 ? 'input_valid' : 'needs_revision'
}
};
});
04 / AI Agent
Connect the chat model to a constrained agent
Add an AI Agent node and select the Tools Agent type. Connect a chat-model sub-node, then enable Require Specific Output Format and attach the Structured Output Parser. Keep tools disconnected for this baseline; the model is structuring a brief, not browsing the web or changing production systems.
添加 AI Agent 节点并选择 Tools Agent 类型,连接聊天模型子节点;随后打开 Require Specific Output Format 并挂载 Structured Output Parser。基线版本不要连接工具,因为当前任务只是生成结构化策划,而不是联网浏览或修改生产系统。
Create the provider credential in n8n’s credential manager. Never place an API key in a prompt, public screenshot, or exported workflow. If you self-host, load secrets from your deployment environment rather than committing them with the project.
在 n8n 的凭据管理器中创建服务商凭据。不要把 API 密钥写进提示词、公开截图或导出的工作流。自托管时应从部署环境注入密钥,而不是随项目提交。
System prompt
system-message.txtCopy
You are a technical content research assistant.
Convert the supplied topic metadata into one article_brief object for a practical technology publication. Return concise, specific language. Separate established facts from assumptions. Do not invent test results, quotations, URLs, rankings, pricing, or search-volume data. If the topic is too broad, set clarification_required to true and ask concrete questions instead of pretending certainty.
Every tutorial step must be reproducible by the reader. Every factual claim that needs checking must appear in claims_to_verify. Every step that needs visual evidence must appear in screenshot_plan.
Human message
human-message.txtCopy
Topic: {{ $json.topic }}
Audience: {{ $json.audience }}
Language: {{ $json.language }}
Article type: {{ $json.article_type }}
Produce a brief for the publication workflow.
Set temperature low enough to favor stable structure—typically around 0.2 to 0.4 for this task. Re-run the same topic after a model or prompt change and compare the output; undocumented model drift is an operational bug.
为这个任务把温度设置在偏低范围,通常 0.2 到 0.4,以优先保证结构稳定。更换模型或提示词后,用同一选题重跑并比较输出;没有记录的模型漂移应视为运营问题。
05 / Structured output
Use JSON Schema as the public contract
Free-form prose is hard to validate, route, and store. The Structured Output Parser accepts a JSON Schema and turns the model response into fields that downstream nodes can inspect. n8n’s parser doesn’t support $ref, so keep the schema explicit.
自由文本很难校验、分流和存储。Structured Output Parser 接收 JSON Schema,并把模型响应转换成下游节点可检查的字段。n8n 的解析器不支持 $ref,因此 Schema 应完整展开。
article-brief.schema.jsonCopy
{
"type": "object",
"properties": {
"working_title": { "type": "string" },
"search_intent": { "type": "string" },
"target_reader": { "type": "string" },
"prerequisites": { "type": "array", "items": { "type": "string" } },
"step_by_step_outline": { "type": "array", "items": { "type": "string" }, "minItems": 4 },
"test_plan": { "type": "string" },
"screenshot_plan": { "type": "array", "items": { "type": "string" } },
"common_failure_cases": { "type": "array", "items": { "type": "string" } },
"claims_to_verify": { "type": "array", "items": { "type": "string" } },
"sources_needed": { "type": "array", "items": { "type": "string" } },
"assumptions": { "type": "array", "items": { "type": "string" } },
"clarification_required": { "type": "boolean" },
"clarification_questions": { "type": "array", "items": { "type": "string" } }
},
"required": [
"working_title",
"search_intent",
"target_reader",
"prerequisites",
"step_by_step_outline",
"test_plan",
"screenshot_plan",
"common_failure_cases",
"claims_to_verify",
"sources_needed",
"assumptions",
"clarification_required",
"clarification_questions"
]
}
The clarification_required pair is deliberate. It lets a broad topic produce a valid machine-readable object while still stopping the workflow from treating that object as a finished plan.
clarification_required 及其问题列表是刻意设计的。宽泛选题仍能返回合法的机器可读对象,同时阻止工作流把这个对象误当成已完成策划。
Scaling note: once you add tools to the agent, move final formatting to a separate LLM chain after the agent’s research step. n8n notes that direct structured parsing is less reliable in tool-using agent workflows.
扩展提示:给 Agent 添加工具后,建议把最终格式化移到 Agent 调研步骤之后的一个独立 LLM Chain。n8n 文档指出,在带工具的 Agent 工作流中,直接结构化解析的可靠性较低。
06 / Validation
Check both shape and editorial usefulness
A response can satisfy the schema and still be useless. The second Code node checks required fields, minimum outline depth, screenshot coverage, explicit claims to verify, and obvious secret patterns. It then adds a stable status that the If node can route.
模型响应可能满足 Schema,却仍然不可用。第二个 Code 节点会检查必填字段、大纲最少步骤、截图覆盖、待核实主张,以及明显的密钥模式,然后写入 If 节点可路由的稳定状态。
validate-brief.js · Run Once for All ItemsCopy
const REQUIRED_FIELDS = [
'working_title', 'search_intent', 'target_reader',
'prerequisites', 'step_by_step_outline', 'test_plan',
'screenshot_plan', 'common_failure_cases', 'claims_to_verify',
'sources_needed', 'assumptions', 'clarification_required',
'clarification_questions'
];
const SECRET_PATTERN = /(sk-[A-Za-z0-9_-]{12,}|AKIA[0-9A-Z]{16}|ghp_[A-Za-z0-9]{20,}|Bearer\s+[A-Za-z0-9._-]{20,})/;
return $input.all().map((item) => {
const source = item.json.output ?? item.json;
const errors = [];
for (const field of REQUIRED_FIELDS) {
if (!(field in source)) errors.push(`missing field: ${field}`);
}
if (typeof source.working_title === 'string' && !source.working_title.trim()) {
errors.push('working_title is empty');
}
if (Array.isArray(source.step_by_step_outline) && source.step_by_step_outline.length < 4) {
errors.push('step_by_step_outline needs at least four steps');
}
if (typeof source.test_plan !== 'string' || source.test_plan.trim().length < 20) {
errors.push('test_plan is missing or too short');
}
if (!Array.isArray(source.screenshot_plan) || source.screenshot_plan.length === 0) {
errors.push('at least one screenshot is required');
}
if (!Array.isArray(source.claims_to_verify)) {
errors.push('claims_to_verify must be an array');
}
if (SECRET_PATTERN.test(JSON.stringify(source))) {
errors.push('possible credential or token detected');
}
const passed = errors.length === 0;
const needsClarification = source.clarification_required === true;
return {
json: {
...item.json,
brief: source,
brief_validation: { passed, errors },
review_status: !passed
? 'needs_revision'
: needsClarification
? 'clarification_needed'
: 'ready_for_review'
}
};
});
Route true to the review destination. Route false to a visible Needs Revision branch; do not let failed executions disappear into a generic error log.
将 true 分支接入审核目的地,将 false 分支接入清晰可见的 Needs Revision 节点,不要让失败执行只消失在通用错误日志里。

07 / Execution tests
Test three paths, not one happy path
Run the workflow with a normal topic, an ambiguous topic, and an empty topic. Inspect the returned values and branch behavior; a green node badge only tells you that execution completed, not that the output is correct.
分别用正常选题、模糊选题和空选题运行工作流,并检查返回数据和分支行为。节点显示绿色只代表执行完成,不代表输出正确。
| Case | Input | Expected | Observed in local run | Result |
|---|---|---|---|---|
| A | “How to summarize a PDF with AI” | Complete brief and no clarification flag | All schema fields parsed; status ready_for_review | Pass |
| B | “Best AI tools” | Valid object with concrete clarification questions | clarification_required: true; routed to clarification review | Pass |
| C | Empty topic | Blocked before the model call | input_validation.passed: false; visible revision branch | Pass |
For the normal run, capture the AI Agent output and expand the parsed fields in the execution panel. Verify that the screenshot plan covers steps where visual evidence matters and that claims_to_verify names specific facts rather than offering a vague warning.
正常运行时,打开 AI Agent 输出并展开解析后的字段。确认截图计划覆盖需要视觉证据的步骤,且 claims_to_verify 列出具体事实,而不是只给一句模糊提醒。
08 / Human review
Send validated briefs to an explicit queue
Once the second If node passes, write the result to a review destination. A spreadsheet is enough: one row per brief, one column per status. Use a fixed vocabulary so reporting stays reliable.
第二个 If 节点通过后,将结果写入审核目的地。第一版使用电子表格即可:每行一份策划,用固定状态词汇,后续统计才不会混乱。
review-row.jsonCopy
{
"review_status": "ready_for_review",
"working_title": "How to Summarize a PDF with AI Without Uploading It to a Random Website",
"editorial_decision": "",
"assigned_editor": "",
"evidence_checked_at": null
}
Draft 初稿
The workflow generated a structurally valid brief. No editorial approval is implied. 工作流生成了结构合法的策划,但不代表已经通过编辑审核。
Research needed 待查证
At least one claim still needs a primary source or hands-on test. 至少有一条主张仍需一手资料或实测证据。
Ready for writing 可写作
An editor has reviewed the angle, test plan, and claims list. 编辑已经确认切入角度、测试方案和待核实清单。
Ready for publication 可发布
Article text, screenshots, links, version, and date have been checked. 正文、截图、链接、版本和日期均已检查。
Do not connect automatic WordPress or CMS publishing to the first version. The workflow is useful precisely because it narrows the editor’s job to verification and judgment.
第一版不要直接连接 WordPress 或其他 CMS 自动发布。这条工作流的价值正在于把编辑工作集中到核实和判断,而不是绕过编辑。
09 / Failure modes
Design branches before adding intelligence
Deterministic nodes should handle input checks, required-field checks, routing, execution status, and notifications. The model should handle angle selection, outline drafting, likely reader questions, and proposed tests. This separation makes failures easier to isolate and keeps the model from controlling the publishing decision.
输入检查、必填字段、路由、执行状态和通知应由确定性节点处理;模型只负责提出切入角度、生成大纲、预测读者问题以及建议测试。这样可以更容易定位故障,也避免模型控制发布决定。
| Failure | Detection point | Handling |
|---|---|---|
| Empty or malformed input / 输入为空或格式错误 | Validate Input | Stop before the model call and mark needs_revision. |
| Malformed model JSON / 模型 JSON 格式错误 | Structured Output Parser | Retry once, then fail the execution into a visible error branch. |
| Schema-valid but shallow outline / 结构合法但大纲过浅 | Validate Brief | Require at least four actionable steps. |
| Ambiguous topic / 选题过宽 | clarification_required | Route to clarification review with concrete questions. |
| Model timeout or rate limit / 模型超时或限流 | Chat model sub-node | Use bounded retries; alert only after the retry budget is exhausted. |
| Possible secret in output / 输出疑似包含密钥 | Validate Brief | Block review and flag the run for security inspection. |
A simple workflow can outperform a larger agent when the larger design adds failure paths without adding measurable editorial value. Expand only after the baseline has run long enough to produce useful metrics.
如果更复杂的 Agent 设计只增加了失败路径、却没有带来可衡量的编辑价值,简单工作流反而更可靠。只有在基线运行时间足够长、积累了有效指标后,才值得扩展。
10 / Metrics
Measure editing work, not node activity
Track the operational numbers that decide whether the system deserves more investment. A useful metric must connect to reduced editor effort or reduced publication risk.
应记录能决定系统是否值得继续投入的运营指标。有效指标必须能减少编辑工作量,或降低发布风险。
Completion rate: successful executions divided by all runs. 完成率:成功执行数除以全部运行数。
Acceptance rate: briefs accepted without major rewriting divided by completed briefs. 采纳率:未经过大幅修改即被接受的策划数除以已完成策划数。
Missing-field rate: validation failures caused by absent or empty schema fields. 缺字段率:因 Schema 字段缺失或为空导致的校验失败比例。
Review minutes: median editor time from queue entry to writing approval. 审核分钟数:从进入队列到获准写作的中位编辑耗时。
Unit cost: model tokens, hosting, and review tooling per accepted brief. 单篇成本:每份被采纳策划对应的模型 Token、主机和审核工具成本。
If automation creates more checking and correction work than it removes, reduce scope instead of adding agents. The right response to poor acceptance is often a tighter input contract, a smaller schema, or a clearer prompt—not a vector database.
如果自动化带来的检查和修正工作多于它节省的工作,就应缩小范围,而不是继续增加 Agent。采纳率偏低时,优先收紧输入契约、缩小 Schema 或改写提示词,而不是急着引入向量数据库。
11 / Deployment
Publish the workflow, not just the article
Before replacing the manual trigger with a form, webhook, or scheduler, make the workflow safe to operate when you are not watching the canvas.
在把 Manual Trigger 替换成表单、Webhook 或定时器之前,先确保无人盯守画布时这条工作流也能安全运行。
Pin the tested n8n minor version and record the model name, provider, and generation date. 固定实测过的 n8n 小版本,并记录模型名称、服务商和测试日期。
Store credentials in n8n or an external secret manager; never export them inside workflow JSON. 把凭据保存在 n8n 或外部密钥管理系统中,不要随工作流 JSON 导出。
Keep the two validation branches and test all three cases after every node upgrade. 保留两道校验分支,每次升级节点后都跑三组测试。
Add timeout and retry limits to the chat model, then alert on persistent provider errors. 为聊天模型设置超时和重试上限,服务商持续报错时触发通知。
Redact private inputs from execution data before sharing screenshots or support bundles. 分享截图或支持包前,先从执行数据中移除私人输入。
Keep publishing manual until acceptance rate and review time remain stable across multiple weeks. 在采纳率和审核耗时可跨多周保持稳定之前,继续保持人工发布。
The result is a repeatable research system with a clear boundary: software prepares and validates the brief; people decide what evidence is sufficient and what gets published.
最终得到的是一套可重复的研究系统,并且边界清晰:软件负责准备和校验策划,人负责判断证据是否充分,以及哪些内容可以发布。
production-flow.txtCopy
Manual Trigger
→ Set Topic
→ Validate Input
→ If Input Valid
→ AI Agent + Chat Model + Structured Output Parser
→ Validate Brief
→ If Brief Valid
→ Send for Review
→ Else → Needs Revision
→ Else → Needs Revision
12 / FAQ
Questions readers usually ask
Does the workflow publish articles automatically?
No. It stops at a review queue. Publishing remains a manual editorial step after evidence, screenshots, and links are checked. 不会。工作流只负责把策划送入审核队列。证据、截图和链接检查完成后,发布仍由编辑人工执行。Do I need a vector database or retrieval?Why validate twice?Can I use Kimi, Anthropic, OpenAI, or a local model?Can a Chinese-language content team use this workflow? / 中文内容团队能直接使用吗?
13 / References
Official sources
- n8n Docs — Manual Trigger node
- n8n Docs — Edit Fields (Set) node
- n8n Docs — Code node
- n8n Docs — If node
- n8n Docs — OpenAI Chat Model sub-node
- n8n Docs — Structured Output Parser
- n8n Docs — Tools Agent
- n8n Release notes
- n8n Quickstart course
Method note: Workflow screenshots and test observations in this article come from a local n8n 2.42.7 execution on 25 October 2026. The test run used an Ollama-compatible local endpoint so no provider credential appears in the captures. If you reproduce the workflow on a newer release, record the changed node names and retest all three cases.
方法说明:本文截图和测试观察来自 2026 年 10 月 25 日本地运行的 n8n 2.42.7。测试使用兼容 Ollama 的本地端点,因此截图中不会出现服务商凭据。若在更高版本复现,应记录节点名称变化并重新执行三组测试。