基于LangChain与LLM的智能体工作流:从自然语言需求到代码自动生成
最近在WAIC现场体验了一款新工具它能把模糊的自然语言需求直接变成可运行的应用。这背后其实是一套完整的“智能体Agent”工作流在支撑。对于开发者而言理解这套从需求到代码的自动化链路远比单纯使用某个工具更有价值。本文将深入拆解这类“需求驱动开发”新范式的核心原理并手把手带你构建一个简化版的智能体系统涵盖环境搭建、核心模块实现到工程化实践的全流程。无论你是想了解AI编程前沿还是希望将自动化开发能力集成到自己的项目中这篇文章都能提供从概念到落地的完整参考。1. 智能体工作流从模糊需求到完整应用的核心架构所谓“说出需求自动干活”的新物种其本质是一个由多个AI智能体协同工作的复杂系统。它并不是单一模型的神奇魔法而是一个精心设计的工程化流水线。理解这个架构是复现或应用此类技术的前提。一个典型的智能体工作流通常包含以下几个核心环节需求分析与拆解智能体接收用户模糊、不完整的自然语言描述通过大语言模型LLM进行意图识别、歧义消除和场景补全。例如用户说“做个管理会员的页面”智能体会追问“需要哪些字段如姓名、电话、等级”、“需要什么功能增删改查、搜索、导出”等将模糊需求转化为清晰、结构化的功能清单。技术方案设计智能体根据结构化的需求选择合适的技术栈如前端用Vue3Element Plus后端用Spring Boot设计数据库表结构规划API接口并输出初步的项目目录结构。这一步相当于高级架构师。代码生成智能体这是最核心的编码环节。它根据技术方案分别调用不同的子智能体或工具生成前端组件、后端控制器、服务层、数据访问层以及SQL脚本等具体代码。每个子智能体专注于特定类型的代码生成。代码验证与集成智能体生成的代码可能存在语法错误、逻辑缺陷或接口不匹配。此智能体负责运行静态检查、执行单元测试甚至能自动生成测试用例、尝试构建项目并将各个模块的代码进行集成确保它们能协同工作。部署与交付智能体将验证通过的代码自动部署到指定的环境如本地服务器、Docker容器或云平台并生成可供访问的链接或安装包。整个流程形成了一个闭环智能体之间通过共享“结构化需求文档”、“设计稿”、“代码库”等中间产物进行通信和迭代。接下来我们将聚焦最核心的代码生成与验证部分构建一个演示性的智能体系统。2. 环境准备与核心技术选型为了构建一个可运行的演示系统我们需要选择合适的技术栈。本示例将采用Python因为它拥有丰富的AI库和快速的开发迭代能力。我们将构建一个控制台应用模拟接收一个简单的“创建用户管理CRUD API”需求并自动生成对应的Spring Boot后端代码。基础环境操作系统Windows 10/11, macOS 或 Linux (如Ubuntu 20.04)。Python版本3.8 或更高版本 (推荐3.9)。本文示例基于 Python 3.9。包管理工具pip。核心依赖库我们将使用LangChain这个流行的框架来构建智能体链并使用 OpenAI 的 GPT 模型作为“大脑”。当然你也可以替换为其他兼容的模型API如国内大模型平台提供的接口。# 创建项目目录并初始化虚拟环境推荐 mkdir ai_agent_demo cd ai_agent_demo python -m venv venv # 激活虚拟环境 # Windows: venv\Scripts\activate # macOS/Linux: source venv/bin/activate # 安装核心依赖 pip install langchain langchain-openai # 安装用于处理结构化输出的库 pip install langchain-experimental # 安装用于生成代码后格式化的库可选但推荐 pip install black项目结构预览在开始编码前我们先规划一下目录结构这有助于理解后续的代码模块。ai_agent_demo/ ├── requirements.txt # 项目依赖列表 ├── main.py # 主程序入口 ├── agents/ # 智能体模块目录 │ ├── __init__.py │ ├── requirement_analyzer.py # 需求分析智能体 │ ├── tech_designer.py # 技术设计智能体 │ └── code_generator.py # 代码生成智能体 ├── templates/ # 代码模板目录可选 │ └── spring_boot_controller.java.tpl └── output/ # 生成的代码输出目录 ├── UserController.java ├── UserService.java └── ...重要配置API密钥使用OpenAI API需要配置密钥。请务必通过环境变量管理不要硬编码在代码中。# 在终端中设置环境变量临时 # Windows: setx OPENAI_API_KEY your-api-key-here # macOS/Linux: export OPENAI_API_KEYyour-api-key-here或者在代码中通过os.environ设置仅用于演示生产环境应用更安全的方式# 在main.py开头添加 import os os.environ[OPENAI_API_KEY] your-api-key-here3. 核心模块拆解与实现我们的简化版智能体系统包含三个核心模块。我们将使用LangChain的LCEL(LangChain Expression Language) 来以声明式的方式组合它们。3.1 需求分析智能体将模糊需求结构化这个智能体的任务是理解用户的自然语言输入并将其转换为机器可处理的、结构化的数据。我们将使用Pydantic来定义这个结构。首先定义结构化输出的数据模型# file: agents/requirement_analyzer.py from pydantic import BaseModel, Field from typing import List from langchain.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI # 定义需求分析的结果结构 class StructuredRequirement(BaseModel): 从模糊需求中提取的结构化信息 core_function: str Field(description核心功能描述如‘用户增删改查’) entities: List[str] Field(description涉及的主要实体对象如[‘用户’ ‘订单’]) fields: dict Field(description每个实体包含的字段格式如{‘用户’: [‘id’, ‘name’, ‘email’]}) operations: List[str] Field(description需要支持的操作如[‘create’, ‘read’, ‘update’, ‘delete’, ‘list’]) # 构建提示词模板 requirement_analysis_prompt ChatPromptTemplate.from_messages([ (system, 你是一个资深软件需求分析师。请将用户模糊、不完整的业务需求转化为结构化的技术需求描述。), (human, 用户需求{user_input}\n\n请严格按照给定的JSON格式输出。) ]) # 创建带有结构化输出的链 def create_requirement_analyzer(): llm ChatOpenAI(modelgpt-4, temperature0.1) # 使用低temperature保证输出稳定 # 使用with_structured_output绑定输出模型 structured_llm llm.with_structured_output(StructuredRequirement) chain requirement_analysis_prompt | structured_llm return chain # 使用示例 if __name__ __main__: analyzer create_requirement_analyzer() user_input 我想做一个管理公司员工信息的系统要能记录姓名、工号、部门和入职时间并且可以新增、查询和修改。 result analyzer.invoke({user_input: user_input}) print(f核心功能: {result.core_function}) print(f实体: {result.entities}) print(f字段: {result.fields}) print(f操作: {result.operations})运行上述代码你会得到类似这样的结构化输出核心功能: 员工信息增删改查 实体: [‘员工’] 字段: {‘员工’: [‘姓名’ ‘工号’ ‘部门’ ‘入职时间’]} 操作: [‘create’ ‘read’ ‘update’]这就把一句模糊的话变成了程序可以明确理解的数据对象。3.2 技术设计智能体生成项目蓝图拿到结构化的需求后下一个智能体负责进行“技术设计”。它需要决定技术栈、数据库表结构、API路径等。这里我们以生成一个简单的Spring Boot项目设计为例。# file: agents/tech_designer.py from pydantic import BaseModel, Field from typing import List from langchain.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI class TechnicalDesign(BaseModel): 技术设计方案 tech_stack: dict Field(description技术栈如{‘backend’: ‘Spring Boot 3.x’ ‘database’: ‘MySQL 8.0’}) entity_classes: List[str] Field(description需要生成的实体类名如[‘User’]) api_endpoints: dict Field(descriptionAPI端点设计格式如{‘User’: {‘POST’: ‘/api/users’ ‘GET’: ‘/api/users/{id}’}}) database_schema: str Field(description简化的数据库建表SQL语句) tech_design_prompt ChatPromptTemplate.from_messages([ (system, 你是一个Java后端架构师。根据结构化的业务需求生成一份可直接指导开发的技术设计方案。请为Spring Boot项目设计。), (human, 业务需求{structured_requirement}\n\n请输出技术设计方案。) ]) def create_tech_designer(): llm ChatOpenAI(modelgpt-4, temperature0.2) structured_llm llm.with_structured_output(TechnicalDesign) chain tech_design_prompt | structured_llm return chain if __name__ __main__: # 这里模拟接收上一个智能体的输出 from agents.requirement_analyzer import StructuredRequirement mock_requirement StructuredRequirement( core_function员工信息管理, entities[员工], fields{员工: [id, name, employee_id, department, hire_date]}, operations[create, read, update, list] ) designer create_tech_designer() design designer.invoke({structured_requirement: mock_requirement.json()}) print(f技术栈: {design.tech_stack}) print(f实体类: {design.entity_classes}) print(fAPI端点: {design.api_endpoints}) print(f数据库Schema:\n{design.database_schema})这个智能体会输出一份详细的设计文档包括建议的依赖、类名、API路径和SQL语句为代码生成提供了精确的“图纸”。3.3 代码生成智能体根据图纸编写代码这是最激动人心的部分。我们将创建一个智能体它接收技术设计方案并为每个指定的实体类生成对应的Java代码。为了提高生成代码的质量和一致性我们可以使用更细致的提示词和少量示例Few-Shot Learning。# file: agents/code_generator.py from langchain.prompts import ChatPromptTemplate, FewShotChatMessagePromptTemplate from langchain_openai import ChatOpenAI import os # 定义代码生成的示例Few-Shot Examples examples [ { input: 生成一个Spring Boot的User实体类包含字段Long id, String username, String email。, output: java package com.example.demo.entity; import jakarta.persistence.*; import lombok.Data; Entity Table(name users) Data public class User { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; Column(nullable false, unique true) private String username; Column(nullable false) private String email; } },]构建Few-Shot提示词模板example_prompt ChatPromptTemplate.from_messages([ (human, {input}), (ai, {output}) ]) few_shot_prompt FewShotChatMessagePromptTemplate( example_promptexample_prompt, examplesexamples, )构建完整的代码生成提示词code_gen_prompt ChatPromptTemplate.from_messages([ (system, 你是一个经验丰富的Java开发专家。请根据给定的技术设计和实体描述生成符合Spring Boot和JPA规范的、可直接运行的Java代码。代码要简洁、规范包含必要的注解如Entity, RestController。只输出代码块不要额外解释。), few_shot_prompt, (human, 技术设计概述{tech_design_summary}\n\n请为实体类‘{entity_name}’生成代码包含字段{fields}。) ])def create_code_generator(): llm ChatOpenAI(modelgpt-4, temperature0.1) # 低温度保证代码确定性 chain code_gen_prompt | llm return chaindef generate_and_save_code(tech_design, output_diroutput): 根据技术设计为每个实体生成并保存代码文件 generator create_code_generator() os.makedirs(output_dir, exist_okTrue)# 这里简化处理假设tech_design是TechnicalDesign对象 # 实际应用中需要解析这个对象 for entity in tech_design.entity_classes: # 构造请求这里需要根据实际数据结构调整 fields_str , .join(tech_design.fields.get(entity, [])) # 假设fields在tech_design中 prompt_input { tech_design_summary: f技术栈{tech_design.tech_stack}, entity_name: entity, fields: fields_str } code generator.invoke(prompt_input).content # 清理代码块标记保存文件 clean_code code.strip().strip(java).strip().strip() file_path os.path.join(output_dir, f{entity}.java) with open(file_path, w, encodingutf-8) as f: f.write(clean_code) print(f[] 已生成文件{file_path})ifname main: # 模拟技术设计输入 class MockTechDesign: entity_classes [Employee, Department] tech_stack {backend: Spring Boot 3.x, database: H2} fields {Employee: [id:Long, name:String, employeeId:String], Department: [id:Long, name:String]}generate_and_save_code(MockTechDesign())运行此代码将在output目录下生成Employee.java和Department.java两个实体类文件内容符合JPA规范。 ## 4. 构建完整智能体工作流与实战演示 现在我们将三个智能体串联起来形成一个完整的、端到端的流水线。我们创建一个主程序来协调整个流程。 python # file: main.py import asyncio import os from agents.requirement_analyzer import create_requirement_analyzer, StructuredRequirement from agents.tech_designer import create_tech_designer, TechnicalDesign from agents.code_generator import generate_and_save_code from langchain_core.runnables import RunnablePassthrough def main(): 主函数串联智能体工作流 print( AI智能体代码生成系统 ) user_input input(请输入您的业务需求例如做一个管理图书借阅的系统\n ) print(\n[阶段一] 需求分析中...) # 1. 需求分析 analyzer create_requirement_analyzer() structured_req: StructuredRequirement analyzer.invoke({user_input: user_input}) print(f 分析完成核心功能 - {structured_req.core_function}) print(\n[阶段二] 技术设计中...) # 2. 技术设计 designer create_tech_designer() # 将结构化需求转换为JSON字符串传递给设计器 tech_design: TechnicalDesign designer.invoke({structured_requirement: structured_req.json()}) print(f 设计完成技术栈 - {tech_design.tech_stack}) print(\n[阶段三] 代码生成中...) # 3. 代码生成与保存 # 注意这里需要将TechnicalDesign对象适配到generate_and_save_code函数 # 我们创建一个适配的简单对象 class SimpleDesignForGen: def __init__(self, tech_design: TechnicalDesign, structured_req: StructuredRequirement): self.entity_classes tech_design.entity_classes self.tech_stack tech_design.tech_stack # 将需求中的字段映射到设计中的实体这里做简单假设第一个实体对应需求中的第一个实体 self.fields {} if structured_req.entities and structured_req.fields: for i, entity in enumerate(tech_design.entity_classes): req_entity structured_req.entities[i % len(structured_req.entities)] self.fields[entity] structured_req.fields.get(req_entity, []) design_for_gen SimpleDesignForGen(tech_design, structured_req) generate_and_save_code(design_for_gen, output_dir./generated_code) print(f\n✅ 流程结束生成的代码已保存至 ./generated_code 目录。) print(f 数据库Schema建议\n{tech_design.database_schema}) if __name__ __main__: # 设置API密钥生产环境请使用环境变量 os.environ[OPENAI_API_KEY] your-api-key-here main()运行演示在项目根目录下执行python main.py。输入需求“做一个简单的员工管理系统需要记录员工姓名、工号、邮箱和所属部门能进行增删改查。”观察控制台输出查看./generated_code目录下生成的Java实体类文件。一个可能生成的Employee.java文件内容如下package com.example.demo.entity; import jakarta.persistence.*; import lombok.Data; import java.time.LocalDate; Entity Table(name employees) Data public class Employee { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; Column(nullable false) private String name; Column(name employee_number, nullable false, unique true) private String employeeNumber; Column(nullable false) private String email; Column(nullable false) private String department; Column(name hire_date) private LocalDate hireDate; }5. 常见问题与排查思路在构建和运行此类AI智能体系统时你可能会遇到一些典型问题。问题现象可能原因解决思路调用API时超时或报错1. 网络连接不稳定。2. API密钥无效或余额不足。3. 请求速率超限。1. 检查网络尝试使用更稳定的环境。2. 在OpenAI控制台验证API密钥状态和余额。3. 降低请求频率为代码添加重试机制和指数退避。生成的代码结构混乱或不符合规范1. 提示词Prompt不够精确。2. 大语言模型“温度”temperature参数过高随机性太强。3. 缺少Few-Shot示例引导。1. 细化系统提示词明确角色、框架、规范和输出格式。2. 将temperature调低如0.1使输出更确定。3. 在提示词中添加高质量、符合规范的代码示例。智能体间数据传递格式错误上一个智能体的输出格式不符合下一个智能体的输入预期。1. 使用Pydantic等工具严格定义智能体间传递的数据结构Schema。2. 在串联智能体时添加数据格式转换和验证层。生成代码存在语法或逻辑错误大语言模型并非编译器可能产生看似合理但有细微错误的代码。1.必须引入验证环节集成代码静态分析工具如对于Java可以用Checkstyle、PMD、尝试编译或解释执行。2. 建立“测试生成智能体”为关键代码自动生成单元测试并运行。处理复杂需求时效果差单一提示词或链难以处理过于复杂、步骤繁多的任务。采用“规划-执行”模式。先让一个“规划智能体”将大任务分解为多个原子性子任务再分发给不同的“执行智能体”处理最后汇总结果。6. 工程化最佳实践与扩展方向将演示系统转化为可用于实际项目的生产级工具需要考虑更多工程化因素。1. 提示词工程与管理模板化将提示词存储在外部文件如YAML、JSON或数据库中便于版本管理和A/B测试。变量注入动态将用户输入、上下文信息、历史对话等注入提示词模板。评估与迭代建立提示词效果评估体系根据生成代码的质量通过率、规范符合度持续优化提示词。2. 智能体的鲁棒性增强异常处理与重试为每个智能体调用包裹完善的异常处理逻辑并设计合理的重试策略。验证与回退在关键节点如生成代码后设置验证点。如果验证失败如编译错误应能触发回退机制例如让另一个智能体修复代码或提示用户澄清需求。流控与限速管理对大语言模型API的调用频率避免因超额请求导致失败或产生高额费用。3. 生成代码的质量保障集成代码格式化工具生成代码后自动调用black(Python)、prettier(JS)、google-java-format(Java)等工具进行格式化。静态分析与安全扫描集成SonarQube、Bandit(Python)、SpotBugs(Java)等工具对生成的代码进行质量和安全漏洞扫描。容器化与沙箱运行对于需要验证运行结果的场景可以将生成代码放在Docker容器中执行确保环境隔离与安全。4. 扩展为多语言、全栈生成前端智能体基于技术设计生成Vue/React组件、页面路由和状态管理代码。数据库智能体生成更复杂的SQL迁移脚本、索引优化建议。部署配置智能体生成Dockerfile、Kubernetes YAML、CI/CD流水线配置如GitHub Actions。5. 构建交互式与持续学习系统人机交互当需求模糊或智能体不确定时应能主动向用户提问例如“您希望的搜索功能是精确匹配还是模糊查询”。这可以通过LangChain的Tool概念来实现让智能体拥有“提问”的能力。反馈循环记录每次用户对生成结果的反馈接受、修改、拒绝并利用这些数据微调提示词或训练奖励模型让系统越用越智能。从“说出需求”到“自动生成代码”的智能体系统代表了软件开发范式的一次重要演进。它并非要取代开发者而是成为开发者的“超级副驾”将开发者从重复性的基础编码中解放出来更专注于架构设计、复杂逻辑和创造性工作。通过本文的拆解与实践希望你不仅能够搭建一个演示系统更能理解其背后的设计哲学与工程挑战从而在自己的领域中探索AI赋能的无限可能。