资讯详情

资讯详情

基于LangChain与开源模型的前端内容创作Agent实战

前端内容创作这块我折腾了大半年总算把一个“基于 LangChain 开源模型”的内容创作 Agent 从原型跑到了勉强能用的阶段。这里说的“内容创作”不是让你生成几句文案而是真正交付一个可以发布、可以交互、视觉效果还过得去的网页——活动页、落地页、H5 宣传页、博客主题、组件 Demo、作品集页面这些前端里“既有模板化套路、又需要一点创意”的活儿正是 Agent 最值得落地的场景。这个方案不算复杂核心就是用 LangChain 把大模型、工具、记忆串成一个能自主工作的 Agent模型层全部采用开源模型不上闭源 API好处是数据可控、成本可算、还能在本地离线跑。整个项目我拆成了需求理解、技术选型、代码生成、本地预览、自动迭代五个环节实测下来一个中等复杂度的活动页从一句话需求到可运行页面五到八分钟能出一个可用版本再花十几分钟人工调样式细节基本就能交付。这篇文章我会把整套设计思路、核心代码骨架、踩过的坑和排查方法都写出来。适合三类人看想用 LLM 做前端自动化的开发者、正在调研 Agent 落地的技术负责人以及刚入门前端工程化、想给自己写点提效工具的同学。不保证你看完能直接部署一套生产级系统但至少能少走我走过的弯路。1. 内容整体设计与思路拆解1.1 为什么要做“前端内容创作”而不是“通用代码生成”市面上很多“AI 写代码”的产品目标都是让 AI 直接生成一个完整应用。真做过的都知道这想法听起来性感落地起来全是坑。复杂业务系统有大量状态管理、权限、接口联调、边界条件现阶段的开源模型根本扛不住生成的代码跑起来一堆 bug调试成本比手写还高。但“内容创作”类页面是另一个物种。这类页面的特征是技术栈相对固定绝大多数是 React 或 Vue 单页配 Tailwind、Bootstrap 这类样式框架不涉及复杂工程配置。逻辑不深但视觉要求高核心是排版、配色、动效、信息层级模型只要“审美在线 代码工整”就能产出不错的结果。需求描述相对完整用户会告诉你“做一个科技产品发布会的报名页”“给咖啡店做个品牌介绍页”这种需求本身信息量足够模型不需要多轮追问就能开工。迭代成本低生成完本地预览不满意重新生成不用牵一发动全身。想通这一点就明白 Agent 的核心定位不该是“全能程序员”而是“又快又便宜的初级前端”——专门处理那些量大、重复、创意要求不高的内容型页面。我最终把技术路线锁定在 React Tailwind也是基于这个现实考量React 生态丰富Tailwind 的类名语义化强模型生成的还原度远比写原生 CSS 高。1.2 技术栈选型LangChain 与 LangGraph 的取舍选型时最先纠结的就是框架。LangChain 和 LangGraph 同源但设计哲学完全不同。LangChain 的核心抽象是Agent Tool适合“多轮调用工具、动态决策”的场景LangGraph 则把节点和边显式建模成图适合状态机、人工介入、复杂分支流转。我们这个项目流程看着是多步骤但本质上是个线性循环理解需求 → 生成代码 → 运行检查 → 不满意再改。没有复杂的状态回退不需要多个角色并行协作用一个 LangChain 的 AgentExecutor 就够了没必要上 LangGraph 增加维护成本。当然如果你后续想让“设计 Agent”和“代码 Agent”分开跑一个负责出视觉稿、一个负责写代码那时候再迁移到 LangGraph 也不迟。模型层我测过 Qwen、DeepSeek、GLM 三家的开源版本最终主力用的是 Qwen 系列。理由很朴素代码能力均衡、中文理解到位、对长上下文的支持比较稳而且生态里配套的工具链全不管是类 OpenAI 的 API 格式还是流式输出接入成本都低。追求更极致的代码能力可以用 DeepSeek视觉审美相关的任务我后面想接一个开源文生图模型做配图比如阿里开源的 6B 级别图像模型轻量且效果不错。1.3 Agent 整体工作流设计这个 Agent 的工作流我画了很多版最后收敛成五个节点需求理解把用户的自然语言输入转成结构化需求包括页面类型、主题风格、目标受众、必含模块。技术确认判断是否需要路由到特定模板或组件库决定技术栈和依赖。代码生成按照 Prompt 约束输出完整可运行的代码文件。本地验证生成的代码写入临时目录启动预览服务调用截图工具看效果。自动迭代把截图结果和错误信息反馈给模型最多循环 3 次超时或连续失败就降级给人工处理。这五步里最关键的设计决策是一定要让 Agent “看见”自己的产物。很多 Agent 生成完代码就交差了页面长什么样根本不知道这是导致前端生成质量差的最主要原因。我在架构里引入了一个预览截图工具Agent 每次生成代码后会主动截图给自己看再根据视觉反馈调整样式。这个闭环一打通生成质量提升非常明显后面第三章我会详细说实现方法。2. 核心细节解析与实操要点2.1 模型参数配置别让模型太“自由”模型参数是最容易被忽略、但影响巨大的部分。前端代码生成和闲聊不一样我们需要的是确定性不是创造性。如果 temperature 设得太高模型会放飞自我变量命名飘忽、样式时有时无、组件结构每次都不一样根本没法迭代。我给出了这套参数基线实测下来稳定性和创造性的平衡比较好参数推荐值说明temperature0.2 ~ 0.4代码生成建议低位视觉创意任务可适当升到 0.5top_p0.85配合 temperature 控制采样范围max_tokens4096 ~ 8192一个页面级代码通常在 2000~4000 token 内frequency_penalty0代码不需要刻意避免重复词汇presence_penalty0同上保持输出稳定优先streamTrue前端必须开流式否则等输出太煎熬为什么 top_p 用 0.85 而不是 1因为前端代码里有大量结构化标记如果采样空间完全放开括号、引号、组件名很容易产生低概率错误。把采样范围收窄一点生成质量会显著变好。这类参数不需要玄学调参跑二十个样本对比一下结果差异一眼就能看出来。2.2 Prompt 体系用 API 方式约束生成规范模型写代码能力取决于训练数据但写得好不好、规不规范很大程度上取决于你怎么用 Prompt 约束它。我总结了一套适合前端代码生成的 Prompt 体系核心思维是把 Prompt 当成接口规范来写而不是简单的“帮我写一个页面”。系统层 Prompt 我固定了几个硬性要求所有代码必须完整可运行禁止输出省略号或“此处省略”这类占位符。CSS 优先使用 Tailwind 工具类不使用单独 CSS 文件减少文件依赖。功能性交互点击、跳转、表单提交必须给出实现不能用注释代替。输出格式完全遵循 JSON 结构化定义禁止任何额外解释文字。代码顶部必须写清楚运行方式、依赖安装命令、启动命令。用户输入进来后先经过一个“需求理解”节点转成结构化 JSON再拼进 Prompt 模板。例如用户说“做一个新能源车发布会的报名页面”Agent 内部会先转成类似的结构再发给模型{ page_type: event_registration, theme: tech_automotive, color_scheme: [dark, electric_blue], sections: [hero, event_info, speaker, registration_form], tech_stack: react18 tailwind, extra_notes: 产品名称暂定为 Aurora报名按钮要突出 }这么做的核心好处是把不可控的自然语言变成可控的结构化输入。模型拿到明确的字段定义生成质量比直接拿自然语言 prompt 稳定得多。我还试过让模型“自己想”怎么组织页面结构结果就是天马行空最后不得不做字段约束。2.3 工具与记忆Agent 不只是聊天机器人如果只是“Prompt 优化得好”那用一个普通的 LLM API 就够了没必要上 Agent。Agent 的核心价值在于它可以通过工具去改变环境再根据结果调整行为。我这个 Agent 挂载了五个核心工具文件写入工具把生成的代码写入项目目录支持多文件。命令执行工具在沙箱环境里执行 npm install、npm run build 等命令。浏览器预览工具启动本地服务用无头浏览器打开页面并截图。视觉反馈工具把截图 base64 编码作为多模态输入回传给模型。日志排查工具读取构建日志和控制台报错帮助模型定位问题。这五个工具串起来Agent 的“认知 - 行动 - 观察”循环就完整了。模型生成代码写文件构建看截图发现有问题改代码再构建。整套流程和人类前端的工作方式几乎一致只是速度和体力更好。关于记忆前端生成场景有很强的连续上下文依赖用户说“背景改深一点”Agent 必须记得上一轮背景是什么。所以对话记忆我用的是 LangChain 的ConversationBufferMemory同时叠加了一个上下文摘要器当对话超过 8 轮或 Token 超过 12000 时自动把早期对话压缩成要点摘要避免上下文爆炸。2.4 上下文窗口前端生成最容易踩的坑聊到记忆就不得不说上下文窗口问题这是前端内容创作 Agent 最容易翻车的地方。一次页面生成的完整链路包含系统 Prompt、用户需求、结构化 JSON、模型的完整代码、构建日志、截图描述加在一起轻松超过 8000 token窗口使用高度紧张。实测下来有两种最常见的爆窗情况一是代码太长。一个信息量大的页面轻松写出 800 行以上放进去就吃掉一万多 token。解决方式是“分模块生成”把页面拆成 Hero、功能区块、页脚等独立组件每一个生成完先落盘然后再生成下一个。Agent 的记忆里只保留“已完成模块清单”和“接口约定”而不是完整代码。二是迭代过程旧状态堆积。每轮截图、每轮报错日志都存进消息历史三轮之后上下文中全是噪音。我的处理方式是独立维护一个BuildState对象记录当前最新的生成状态、最近一次错误和截图描述对话历史只保留摘要模型每次只读状态而非全部日志。这个设计实操中极其重要后面第四章我还会单独讲怎么排查上下文相关故障。3. 实操过程与核心环节实现3.1 环境搭建与模型接入先说环境。我的开发机是 64G 内存的 Mac Studio本地跑 7B~14B 模型很流畅。如果你只是做验证建议先用 Ollama 跑一个小一点的模型比如 Qwen 系列 7B 或 14B 版本。部署很简单ollama pull qwen2.5:14b ollama run qwen2.5:14bLangChain 接 Ollama 的方式也直接文档齐全跑通不用一个小时from langchain_community.llms import Ollama llm Ollama( modelqwen2.5:14b, base_urlhttp://localhost:11434, temperature0.2, top_p0.85, num_predict4096 )如果你的场景允许连外网 API可以用各家开源模型的托管服务效果更稳定、并发更高不过自己部署的成本和隐私优势就没了。我建议两手准备代码里抽象一个 LLMProvider 接口本地和远程随时切换这套设计帮你避免被单一模型供应商绑架。3.2 核心代码骨架一套可复用的 Agent 实现下面是整个 Agent 的核心代码骨架我已经简化成可运行的最小版本。核心组件包括Prompt 模板、工具集、Agent 执行器。from langchain.agents import AgentExecutor, create_openai_tools_agent from langchain.tools import Tool from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder from typing import Optional import os, subprocess, json # 1. 定义文件写入工具 def write_files(files_json: str) - str: 写入多个项目文件输入为JSON格式 {filename: content} try: files json.loads(files_json) for filename, content in files.items(): filepath os.path.join(generated_project, filename) os.makedirs(os.path.dirname(filepath), exist_okTrue) with open(filepath, w, encodingutf-8) as f: f.write(content) return f成功写入 {len(files)} 个文件 except Exception as e: return f写入失败: {str(e)} # 2. 定义命令执行工具 def run_command(command: str) - str: 在生成项目目录执行shell命令返回stdout和stderr try: result subprocess.run( command, shellTrue, capture_outputTrue, textTrue, timeout120, cwdgenerated_project ) output result.stdout[-3000:] \n---STDERR---\n result.stderr[-3000:] return output if output.strip() else 命令执行成功无输出 except subprocess.TimeoutExpired: return 命令执行超时 except Exception as e: return f执行异常: {str(e)} # 3. 定义截图工具简化版实际可用 Playwright def capture_screenshot(url: str http://localhost:5173) - str: 启动项目预览后截图返回base64编码图片 from playwright.sync_api import sync_playwright import base64 with sync_playwright() as p: browser p.chromium.launch() page browser.new_page(viewport{width: 1280, height: 800}) page.goto(url, wait_untilnetworkidle) screenshot page.screenshot() browser.close() return base64.b64encode(screenshot).decode(utf-8) # 4. 组装 Tool 列表 tools [ Tool(namewrite_files, funcwrite_files, description将生成的代码写入项目文件输入必须是JSON格式), Tool(namerun_command, funcrun_command, description在项目目录执行Shell命令比如 npm install / npm run build), Tool(namecapture_screenshot, funccapture_screenshot, description截图预览当前页面并返回base64图片), ] # 5. Prompt 模板 prompt ChatPromptTemplate.from_messages([ (system, SYSTEM_PROMPT), (human, {input}), MessagesPlaceholder(variable_nameagent_scratchpad), ]) # 6. 创建 Agent from langchain.agents import create_openai_tools_agent agent create_openai_tools_agent(llm, tools, prompt) agent_executor AgentExecutor( agentagent, toolstools, verboseTrue, memoryConversationBufferMemory( memory_keychat_history, return_messagesTrue, max_token_limit12000 ) ) # 7. 执行 result agent_executor.invoke({ input: 帮我生成一个新能源车发布会报名页面深色背景、科技感、包含报名表单 }) print(result[output])这里有个设计细节值得强调工具描述必须非常精确LangChain 的 Agent 靠描述决定工具调用顺序。如果capture_screenshot的描述写得太泛模型会在代码没写完时就去截图导致一直看空白页面然后陷入“生成-截图-空白-再生成”的死循环。我在工具描述里都加上了前置条件比如截图工具写明“仅在 npm run dev 启动成功后调用”实测能减少一半无效调用。3.3 从需求到页面的完整生成过程实录拿一个真实案例走一遍流程。用户输入“做一个独立开发者的个人作品集页面风格简约有项目展示、关于我、联系方式三块技术栈 React Tailwind。”Agent 的执行过程如下第一轮需求理解节点把输入转成结构化 JSON标记页面类型为portfolio风格minimal配色倾向白底灰字生成 React 结构。第二轮模型输出一个单文件 App.jsx大约 300 行包含 Hero、项目展示卡片、关于我、联系方式四个区块。write_files工具写入文件。第三轮Agent 调用run_command(npm install npm run dev)构建成功启动本地服务。第四轮capture_screenshot截了一张 1280x800 的图。模型看过图后发现两个问题项目卡片区域的间距过小文字挤在一起Hero 标题在深色背景上用了深色字体几乎看不清。第五轮模型修改代码调整间距字体改成亮色二次截图验证通过。整个流程用时大约 4 分钟人工只需要在最后看一下交互细节就完事。这个案例里最有价值的部分在第四轮模型能基于视觉反馈修改代码而不是靠想象盲改。我一开始没用截图工具模型生成的页面经常出现“代码写得没毛病页面丑得没法看”的情况因为模型无法感知最终的视觉呈现。加上视觉反馈后Agent 对“审美”的把握明显提升虽然距离高级设计师还有差距但已经超过了不少初阶前端。3.4 工程化落地产物输出规范与部署Agent 生成的代码最终还要落地成可发布的内容。我做了两道工序第一道是产物规范化校验。Agent 完成生成后启用 ESLint 和 TypeScript 检查跑一遍自动化测试。这一步骤非常必要因为 Agent 生成的代码风格不稳定不格式化直接进代码库后面维护会很痛苦。我写了个后处理脚本自动执行 prettier 格式化、依赖树检查、license 检查然后才提交到产物目录。第二道是一键部署。内容创作场景大多数产物是静态页面部署到对象存储或者 Docker 容器都行。我会让 Agent 在交付时同时输出一个Dockerfile和deploy.sh用镜像方式跑 Nginx 托管静态文件谁能拒绝“一键上线”的交付物呢。FROM node:20-alpine AS build WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build FROM nginx:alpine COPY --frombuild /app/dist /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 80这个 Dockerfile 是通用模板实际项目根据需求改改静态目录就行。如果你不想折腾 Docker也可以让 Agent 直接输出适配 GitHub Pages、Vercel 或云存储的配置部署路径选择很多。4. 常见问题与排查技巧实录4.1 生成的代码总是“被截断”这是我被问得最多的问题。Agent 写代码写到一半就停了或者干脆把/div全给吞了页面直接崩。根因有两个一是max_tokens设得不够。单文件代码超过 4096 token 时模型会在上限处截断。我把数字提到 8192 之后明显改善。二是 Agent 自身维护的消息列表里有太多历史记录每一轮调用都叠加旧的代码片段模型上下文空间被历史挤占输出的有效 token 就变少了。解决方法是前面提过的分模块生成 状态压缩。大页面拆成多个组件每个组件单独生成单独落盘。这样单次生成的代码量被控制在一个可预测的范围内截断概率大幅下降。4.2 Agent 陷入了“修改-构建失败-再修改”的死循环另一个高频事故。Agent 试着修复一个构建错误但改完引入新问题新问题又触发新一轮修复最夸张的一次循环了 11 轮还没有结果Token 费用刷上去很多产出的代码反而比最初版更烂。排查后发现问题出在记忆污染。每一轮构建失败的错误日志都完整留在历史消息里模型越到后面越混乱不知道该优先修哪个错误。我加了两个防护机制一是单轮错误信息截断构建日志只保留最近 300 个字符给模型看。报错信息里 80% 的冗余内容对定位问题没有帮助模型需要的是“哪一行什么错误”不是整个堆栈。二是循环次数上限。AgentExecutor 里设置max_iterations5第 6 次还没成功就不再让模型自己挣扎而是输出失败报告并请求人工介入。这招很救命避免 Agent 把问题越改越复杂。现象可能原因处理办法代码写到一半截断max_tokens 不足 / 上下文被历史挤占调大 max_tokens多文件分步生成画面和需求描述偏差大需求理解环节丢信息检查结构化 JSON 是否符合预期反复尝试却构建失败记忆里有大量旧日志只保留最近 300 字符错误信息页面生成后样式错乱Tailwind 版本不匹配锁定依赖版本在系统 Prompt 中声明截图工具返回空内容服务未启动成功检查启动命令加入轮询等待4.3 上下文冲爆Token 预算失控内容创作 Agent 的上下文之所以容易爆除了代码量大这个客观原因还有个隐蔽的元凶——图片输入。如果用了多模态模型并且把截图 base64 编码直接塞进上下文一张 1280x800 的 PNG 可能等价于几千 token三轮迭代下来窗口就挤爆了。我没有直接放弃视觉反馈而是换了一种策略让图像理解模型先“看图说话”——用一个小参数的多模态模型把截图转换成结构化的视觉描述比如“Hero 区域标题使用了深色字体与背景对比度不足”然后把这段文字描述交给主 Agent主 Agent 全程保持纯文本输入不直接接收图片。这样既保留了视觉反馈循环又把 Token 消耗控制得极低。如果你们团队使用的是不支持视觉的开源模型这个方案几乎是必选项。4.4 一套 Prompt 很难适配所有页面类型我一开始设计了一套“万能 Prompt”希望它既能生成活动页又能生成后台管理界面。结果发现一个很尴尬的现实模型在通用约束下生成的代码“不出错但没个性”风格极其相似看多了会腻。后来我改成多套 Prompt 模板按页面类型路由营销页模板强化视觉冲击力、转化按钮、动效引导。内容型页面模板强化排版可读性、信息层级、长文阅读体验。工具型页面模板强化交互反馈、状态处理、表单验证。作品集模板强化视觉效果、动画流畅度、主题一致性。每一套模板在系统 Prompt 里注入不同的风格指导和组件偏好生成出来的页面类型差异化非常明显。这个改动比较费功夫但收益是用户满意度直接从“能跑就行”变成“确实好看”。5. 性能优化与后续扩展方向5.1 缓存复用别让 Agent 重复造轮子跑了一段时间后你会发现很多页面框架上是类似的都是 Hero 产品特性 定价 CTA。不同客户只是改了文案和配色。我在架构里加了产物缓存层已经生成的组件按“页面类型 主题风格 技术栈”三个维度做哈希索引。如果命中缓存直接复用组件代码只修改文案和图片资源生成速度能提升到 30 秒以内Token 成本也大幅下降。这块思路其实和前端工程化里的“组件库”一模一样只不过之前是人肉维护组件库现在变成了 Agent 自动沉淀组件资产。将来这些沉淀出来的组件甚至会反过来变成你们团队自己的私域组件库价值越滚越大。5.2 多模态扩展用图像模型补足视觉短板目前 Agent 用的都是背景图占位符或纯色块真实业务里这是不行的。做营销页不可能没有产品图、活动图这块正是文生图模型能补位的。我后续规划是接入轻量级的开源文生图模型让 Agent 根据页面主题自动生成 Hero 配图、卡片素材然后走一遍“生成图 - 压缩 - 转 base64 - 给多模态模型预览”的流程。这样一来“文字 图片 布局”三种内容全部由 Agent 自动产出内容创作的自动化程度会再上一个台阶。如果你用的是 6B 级别的开源图像模型单张 512x512 的图大概几秒钟能出配合低配推理卡就能跑得很舒服。注意配图版权和内容合规问题毕竟开源模型生成素材的自由度高授权边界要自己把握。5.3 从单 Agent 到多 Agent什么时候需要上 LangGraph目前的单 Agent 架构在我的场景下够用但如果你要处理更复杂的任务比如“用户上传一个设计稿Agent 还原成页面”“用户提一个复杂站点的完整需求需要同时管理多个页面和共享组件”单 Agent 会非常吃力。这时候就需要引入多 Agent 编排LangGraph 的价值就开始显现。你可以拆出三个角色需求分析 Agent负责把需求拆成页面清单和数据模型。页面生成 Agent每个页面一个独立 Agent并行生成。质量审查 Agent统一检查所有生成结果的风格一致性、链接有效性、响应式表现。LangGraph 的好处是有显式的状态管理和条件分支多 Agent 协作时不会乱。但代价是学习成本和代码复杂度都明显上升。我的建议是能用一个 Agent 解决问题的绝对不要上多 Agent。等你的需求规模和复杂度真的撑不起单 Agent 架构时再迁移不迟。5.4 这套方案对前端学习和面试场景的价值最后聊一个意外的收获。这套 Agent 不只是拿来产出页面它还被我用来做前端学习和模拟面试效果出奇的好。前端八股文背得再多不如实际动手看别人怎么写。我给 Agent 加了两种模式Demo 演示模式给定一个前端知识点比如「useMemo 和 useCallback 的区别」Agent 自动生成一个可视化交互 Demo把抽象概念变成可以点击的页面学习效率高很多。模拟面试模式Agent 扮演面试官出一个前端面试题要求用户现场写代码然后 Agent 根据运行结果给出评价和改进建议。这套玩法在准备前后端分离开的岗位面试时特别好用。这也是为什么即使现在这套 Agent 生成质量还有各种限制我依然觉得方向值得继续做——它本质上是一个能把想法变成可交互作品的高效引擎前端只是目前最适合切入的舞台。从最早拿着 LangChain 文档从头啃到现在能稳定生成可交付的活动页面这个项目带我走完了一个完整的 Agent 落地闭环。我个人最有感触的一点是Agent 项目能不能成功七分在工程和 Prompt 设计三分在模型能力。模型选型固然重要但更关键的是你有没有把“工具调用、视觉反馈、上下文管理、失败降级”这些工程细节做到位。最后再分享一个小技巧让 Agent 生成代码时始终输出三段式内容——第一段设计思路说明第二段完整代码第三段使用方法和备注。这不仅方便你后续 review也让模型在生成时被迫先想清楚再动手代码质量明显高于直接输出。这个技巧不大但谁用谁知道。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →