💻 代码生成
代码生成是 LangGraph 的一个强大应用场景,它可以帮助开发者自动化编程任务,从简单的代码片段生成到复杂的多文件项目创建。本节将介绍如何使用 LangGraph 构建智能的代码生成系统。
引言
在现代软件开发中,代码生成工具已经成为提高开发效率的重要手段。LangGraph 通过其灵活的图结构和强大的 LLM 集成能力,为构建智能代码生成系统提供了理想的平台。
与前端开发的关联
对于前端开发者来说,代码生成就像是:
- 组件生成器:自动创建 React 组件模板
- 脚手架工具:类似于
create-react-app或vite - 代码模板系统:根据需求生成样板代码
- 自动化重构:智能地修改和优化现有代码
核心概念
代码生成系统通常包含以下几个关键步骤:
需求分析
理解用户的编程需求,包括:
- 功能描述
- 技术栈要求
- 代码风格偏好
- 性能要求
代码生成
基于需求分析结果,生成相应的代码:
- 选择合适的编程语言和框架
- 应用最佳实践和设计模式
- 生成可读性强的代码
代码验证
确保生成的代码质量:
- 语法正确性检查
- 逻辑合理性验证
- 性能和安全性评估
基础代码生成器
让我们从一个简单的代码生成器开始:
基础代码生成器:
import '../../utils/loadEnv';
import { StateGraph, Annotation, START, END } from '@langchain/langgraph';
import { ChatOpenAI } from '@langchain/openai';
// 定义状态结构
const CodeGeneratorState = Annotation.Root({
// 用户需求描述
requirement: Annotation<string>(),
// 技术栈要求
techStack: Annotation<string>(),
// 生成的代码
generatedCode: Annotation<string>(),
// 代码语言
language: Annotation<string>(),
});
// 初始化 LLM
const llm = new ChatOpenAI({
model: process.env.OPENAI_MODEL_NAME,
temperature: 0.1, // 降低随机性,提高代码质量
});
/**
* 需求分析节点
* 分析用户需求,确定技术栈和编程语言
*/
async function analyzeRequirement(state: typeof CodeGeneratorState.State) {
const prompt = `
分析以下编程需求,确定合适的技术栈和编程语言:
需求:${state.requirement}
请返回JSON格式的分析结果:
{
"language": "编程语言",
"techStack": "推荐的技术栈",
"complexity": "复杂度评估"
}
`;
const response = await llm.invoke([
{
role: 'system',
content: '你是一个资深的技术架构师,擅长分析需求并推荐合适的技术方案。',
},
{ role: 'user', content: prompt },
]);
try {
const analysis = JSON.parse(response.content as string);
return {
language: analysis.language,
techStack: analysis.techStack,
};
} catch (error) {
// 如果解析失败,使用默认值
return {
language: 'TypeScript',
techStack: 'React + TypeScript',
};
}
}
/**
* 代码生成节点
* 根据需求和技术栈生成代码
*/
async function generateCode(state: typeof CodeGeneratorState.State) {
const prompt = `
根据以下需求生成${state.language}代码:
需求:${state.requirement}
技术栈:${state.techStack}
编程语言:${state.language}
要求:
1. 代码要完整可运行
2. 包含必要的注释
3. 遵循最佳实践
4. 代码风格要一致
5. 包含错误处理
请只返回代码,不要包含其他说明文字。
`;
const response = await llm.invoke([
{
role: 'system',
content: `你是一个专业的${state.language}开发工程师,擅长编写高质量、可维护的代码。`,
},
{ role: 'user', content: prompt },
]);
return {
generatedCode: response.content as string,
};
}
/**
* 构建基础代码生成器图
*/
function createBasicCodeGenerator() {
const workflow = new StateGraph(CodeGeneratorState)
.addNode('analyzeRequirement', analyzeRequirement)
.addNode('generateCode', generateCode)
.addEdge(START, 'analyzeRequirement')
.addEdge('analyzeRequirement', 'generateCode')
.addEdge('generateCode', END);
return workflow.compile();
}
// 使用示例
async function runBasicCodeGenerator() {
const app = createBasicCodeGenerator();
console.log('🚀 启动基础代码生成器...\n');
// 示例1:生成React组件
const result1 = await app.invoke({
requirement:
'创建一个用户登录表单组件,包含用户名、密码输入框和登录按钮,支持表单验证',
});
console.log('📝 生成的React组件代码:');
console.log('语言:', result1.language);
console.log('技术栈:', result1.techStack);
console.log('代码:');
console.log(result1.generatedCode);
console.log('\n' + '='.repeat(50) + '\n');
// 示例2:生成工具函数
const result2 = await app.invoke({
requirement: '创建一个数据处理工具函数,能够对数组进行去重、排序和过滤操作',
});
console.log('📝 生成的工具函数代码:');
console.log('语言:', result2.language);
console.log('技术栈:', result2.techStack);
console.log('代码:');
console.log(result2.generatedCode);
}
// 导出主要函数和类型
export {
CodeGeneratorState,
createBasicCodeGenerator,
runBasicCodeGenerator,
analyzeRequirement,
generateCode,
};
// 如果直接运行此文件,执行示例
if (require.main === module) {
runBasicCodeGenerator().catch(console.error);
}
这个基础生成器展示了代码生成的核心流程:
- 接收用户需求
- 分析技术要求
- 生成对应代码
- 返回结果
带验证的代码生成器
为了提高代码质量,我们可以添加验证和优化步骤:
带验证的代码生成器:
import '../../utils/loadEnv';
import { StateGraph, Annotation, START, END } from '@langchain/langgraph';
import { ChatOpenAI } from '@langchain/openai';
// 定义状态结构
const ValidatedCodeGeneratorState = Annotation.Root({
// 用户需求描述
requirement: Annotation<string>(),
// 技术栈要求
techStack: Annotation<string>(),
// 生成的代码
generatedCode: Annotation<string>(),
// 代码语言
language: Annotation<string>(),
// 验证结果
validationResult: Annotation<{
isValid: boolean;
issues: string[];
suggestions: string[];
score: number;
}>(),
// 优化后的代码
optimizedCode: Annotation<string>(),
// 迭代次数
iterationCount: Annotation<number>({
reducer: (x, y) => y,
default: () => 0,
}),
});
// 初始化 LLM
const llm = new ChatOpenAI({
model: process.env.OPENAI_MODEL_NAME,
temperature: 0.1,
});
/**
* 代码生成节点
* 根据需求生成或优化代码
*/
async function generateCode(state: typeof ValidatedCodeGeneratorState.State) {
let prompt: string;
if (state.iterationCount === 0) {
// 首次生成
prompt = `
根据以下需求生成${state.language || 'TypeScript'}代码:
需求:${state.requirement}
技术栈:${state.techStack || 'React + TypeScript'}
要求:
1. 代码要完整可运行
2. 包含必要的注释
3. 遵循最佳实践
4. 代码风格要一致
5. 包含错误处理
请只返回代码,不要包含其他说明文字。
`;
} else {
// 基于反馈优化
prompt = `
请根据以下反馈优化代码:
原始需求:${state.requirement}
当前代码:
${state.generatedCode}
验证问题:
${state.validationResult?.issues.join('\n')}
优化建议:
${state.validationResult?.suggestions.join('\n')}
请返回优化后的完整代码,解决所有提到的问题。
`;
}
const response = await llm.invoke([
{
role: 'system',
content: `你是一个专业的${state.language || 'TypeScript'}开发工程师,擅长编写高质量、可维护的代码。`,
},
{ role: 'user', content: prompt },
]);
return {
generatedCode: response.content as string,
language: state.language || 'TypeScript',
techStack: state.techStack || 'React + TypeScript',
iterationCount: state.iterationCount + 1,
};
}
/**
* 代码验证节点
* 检查代码质量和正确性
*/
async function validateCode(state: typeof ValidatedCodeGeneratorState.State) {
const prompt = `
请对以下代码进行全面的质量评估:
代码:
${state.generatedCode}
需求:${state.requirement}
请从以下维度评估代码质量:
1. 语法正确性
2. 逻辑合理性
3. 代码风格
4. 性能考虑
5. 安全性
6. 可维护性
7. 错误处理
请返回JSON格式的评估结果:
{
"isValid": boolean,
"score": number (0-100),
"issues": ["问题1", "问题2"],
"suggestions": ["建议1", "建议2"],
"strengths": ["优点1", "优点2"]
}
`;
const response = await llm.invoke([
{
role: 'system',
content: '你是一个资深的代码审查专家,擅长发现代码问题并提供改进建议。',
},
{ role: 'user', content: prompt },
]);
try {
const validation = JSON.parse(response.content as string);
return {
validationResult: {
isValid: validation.isValid,
issues: validation.issues || [],
suggestions: validation.suggestions || [],
score: validation.score || 0,
},
};
} catch (error) {
// 如果解析失败,返回默认验证结果
return {
validationResult: {
isValid: true,
issues: [],
suggestions: [],
score: 80,
},
};
}
}
/**
* 最终优化节点
* 对通过验证的代码进行最后的优化
*/
async function finalizeCode(state: typeof ValidatedCodeGeneratorState.State) {
const prompt = `
对以下代码进行最终优化,确保代码质量达到生产级别:
代码:
${state.generatedCode}
需求:${state.requirement}
请进行以下优化:
1. 添加完整的类型定义
2. 优化性能
3. 增强错误处理
4. 改进代码注释
5. 确保代码风格一致
返回优化后的完整代码。
`;
const response = await llm.invoke([
{
role: 'system',
content: '你是一个代码优化专家,专注于提升代码质量和性能。',
},
{ role: 'user', content: prompt },
]);
return {
optimizedCode: response.content as string,
};
}
/**
* 路由函数
* 决定下一步执行哪个节点
*/
function routeNext(state: typeof ValidatedCodeGeneratorState.State) {
// 如果验证通过且分数足够高,进行最终优化
if (state.validationResult?.isValid && state.validationResult.score >= 85) {
return 'finalizeCode';
}
// 如果迭代次数过多,强制结束
if (state.iterationCount >= 3) {
return 'finalizeCode';
}
// 否则继续优化
return 'generateCode';
}
/**
* 构建带验证的代码生成器图
*/
function createValidatedCodeGenerator() {
const workflow = new StateGraph(ValidatedCodeGeneratorState)
.addNode('generateCode', generateCode)
.addNode('validateCode', validateCode)
.addNode('finalizeCode', finalizeCode)
.addEdge(START, 'generateCode')
.addEdge('generateCode', 'validateCode')
.addConditionalEdges('validateCode', routeNext, {
generateCode: 'generateCode',
finalizeCode: 'finalizeCode',
})
.addEdge('finalizeCode', END);
return workflow.compile();
}
// 使用示例
async function runValidatedCodeGenerator() {
const app = createValidatedCodeGenerator();
console.log('🚀 启动带验证的代码生成器...\n');
// 示例:生成一个复杂的React Hook
const result = await app.invoke({
requirement: `
创建一个自定义React Hook叫useLocalStorage,功能包括:
1. 可以读取和写入localStorage
2. 支持JSON序列化和反序列化
3. 提供类型安全
4. 处理存储错误
5. 支持默认值
6. 当localStorage变化时自动更新组件
`,
});
console.log('📝 代码生成结果:');
console.log('语言:', result.language);
console.log('技术栈:', result.techStack);
console.log('迭代次数:', result.iterationCount);
console.log('\n验证结果:');
console.log('- 是否有效:', result.validationResult?.isValid);
console.log('- 质量分数:', result.validationResult?.score);
console.log('- 发现问题:', result.validationResult?.issues.length || 0, '个');
console.log(
'- 优化建议:',
result.validationResult?.suggestions.length || 0,
'个'
);
console.log('\n🎯 最终优化后的代码:');
console.log(result.optimizedCode || result.generatedCode);
// 显示验证详情
if (result.validationResult?.issues.length > 0) {
console.log('\n⚠️ 发现的问题:');
result.validationResult.issues.forEach((issue, index) => {
console.log(`${index + 1}. ${issue}`);
});
}
if (result.validationResult?.suggestions.length > 0) {
console.log('\n💡 优化建议:');
result.validationResult.suggestions.forEach((suggestion, index) => {
console.log(`${index + 1}. ${suggestion}`);
});
}
}
// 流式执行示例
async function runValidatedCodeGeneratorWithStreaming() {
const app = createValidatedCodeGenerator();
console.log('🚀 启动流式代码生成器...\n');
const stream = await app.stream(
{
requirement:
'创建一个TypeScript工具函数,用于深度克隆对象,支持循环引用检测',
},
{ streamMode: 'updates' }
);
for await (const chunk of stream) {
const [nodeName, nodeOutput] = Object.entries(chunk)[0];
console.log(`📍 执行节点: ${nodeName}`);
if (nodeName === 'generateCode') {
console.log(` 迭代次数: ${(nodeOutput as any).iterationCount}`);
} else if (nodeName === 'validateCode') {
const output = nodeOutput as any;
console.log(
` 验证结果: ${output.validationResult?.isValid ? '✅ 通过' : '❌ 需要改进'}`
);
console.log(` 质量分数: ${output.validationResult?.score}/100`);
} else if (nodeName === 'finalizeCode') {
console.log(' ✨ 代码优化完成');
}
console.log('');
}
}
// 导出主要函数和类型
export {
ValidatedCodeGeneratorState,
createValidatedCodeGenerator,
runValidatedCodeGenerator,
runValidatedCodeGeneratorWithStreaming,
generateCode,
validateCode,
finalizeCode,
routeNext,
};
// 如果直接运行此文件,执行示例
if (require.main === module) {
runValidatedCodeGenerator()
.then(() => {
console.log('\n' + '='.repeat(60) + '\n');
return runValidatedCodeGeneratorWithStreaming();
})
.catch(console.error);
}
这个增强版本使用了 Evaluator-Optimizer 模式:
- 生成器节点:负责生成代码
- 验证器节点:检查代码质量
- 优化器节点:根据反馈改进代码
验证流程图
多文件代码生成器
对于复杂项目,我们需要生成多个相关文件:
多文件代码生成器:
import '../../utils/loadEnv';
import { StateGraph, Annotation, START, END, Send } from '@langchain/langgraph';
import { ChatOpenAI } from '@langchain/openai';
// 文件规格接口
interface FileSpec {
name: string;
type: string;
description: string;
dependencies: string[];
}
// 主状态结构
const MultiFileGeneratorState = Annotation.Root({
// 项目需求描述
projectRequirement: Annotation<string>(),
// 项目类型
projectType: Annotation<string>(),
// 文件规格列表
fileSpecs: Annotation<FileSpec[]>({
reducer: (x, y) => y,
default: () => [],
}),
// 生成的文件内容
generatedFiles: Annotation<Record<string, string>>({
reducer: (x, y) => ({ ...x, ...y }),
default: () => ({}),
}),
// 项目结构
projectStructure: Annotation<string>(),
});
// 工作器状态结构
const WorkerState = Annotation.Root({
// 文件规格
fileSpec: Annotation<FileSpec>(),
// 项目上下文
projectContext: Annotation<{
requirement: string;
type: string;
allFiles: FileSpec[];
}>(),
// 生成的文件内容
generatedFiles: Annotation<Record<string, string>>({
reducer: (x, y) => ({ ...x, ...y }),
default: () => ({}),
}),
});
// 初始化 LLM
const llm = new ChatOpenAI({
model: process.env.OPENAI_MODEL_NAME,
temperature: 0.1,
});
/**
* 项目规划节点
* 分析项目需求,规划需要生成的文件
*/
async function planProject(state: typeof MultiFileGeneratorState.State) {
const prompt = `
分析以下项目需求,规划需要生成的文件结构:
项目需求:${state.projectRequirement}
请返回JSON格式的规划结果:
{
"projectType": "项目类型(如:React应用、Node.js API、工具库等)",
"fileSpecs": [
{
"name": "文件名(包含路径)",
"type": "文件类型(如:component、utility、config、test等)",
"description": "文件功能描述",
"dependencies": ["依赖的其他文件名"]
}
]
}
要求:
1. 文件结构要合理,遵循最佳实践
2. 包含必要的配置文件
3. 考虑代码复用和模块化
4. 文件数量控制在10个以内
`;
const response = await llm.invoke([
{
role: 'system',
content: '你是一个资深的软件架构师,擅长设计项目结构和文件组织。',
},
{ role: 'user', content: prompt },
]);
try {
const plan = JSON.parse(response.content as string);
return {
projectType: plan.projectType,
fileSpecs: plan.fileSpecs,
};
} catch (error) {
// 如果解析失败,返回默认规划
return {
projectType: 'React应用',
fileSpecs: [
{
name: 'src/App.tsx',
type: 'component',
description: '主应用组件',
dependencies: [],
},
{
name: 'src/index.tsx',
type: 'entry',
description: '应用入口文件',
dependencies: ['src/App.tsx'],
},
],
};
}
}
/**
* 文件生成工作器节点
* 生成单个文件的内容
*/
async function generateFile(state: typeof WorkerState.State) {
const { fileSpec, projectContext } = state;
const prompt = `
根据以下信息生成文件内容:
项目需求:${projectContext.requirement}
项目类型:${projectContext.type}
当前文件:
- 文件名:${fileSpec.name}
- 文件类型:${fileSpec.type}
- 功能描述:${fileSpec.description}
- 依赖文件:${fileSpec.dependencies.join(', ')}
项目中的其他文件:
${projectContext.allFiles
.map((f) => `- ${f.name}: ${f.description}`)
.join('\n')}
要求:
1. 生成完整可用的代码
2. 包含必要的导入语句
3. 添加适当的注释
4. 遵循代码规范
5. 考虑与其他文件的协作
请只返回文件内容,不要包含其他说明。
`;
const response = await llm.invoke([
{
role: 'system',
content: `你是一个专业的${projectContext.type}开发工程师,擅长编写高质量的代码文件。`,
},
{ role: 'user', content: prompt },
]);
return {
generatedFiles: {
[fileSpec.name]: response.content as string,
},
};
}
/**
* 项目整合节点
* 整合所有生成的文件,创建项目结构说明
*/
async function integrateProject(state: typeof MultiFileGeneratorState.State) {
const fileList = Object.keys(state.generatedFiles);
const fileCount = fileList.length;
const prompt = `
为以下项目生成结构说明和使用指南:
项目需求:${state.projectRequirement}
项目类型:${state.projectType}
生成的文件(${fileCount}个):
${fileList.map((fileName) => `- ${fileName}`).join('\n')}
请生成:
1. 项目结构说明
2. 文件功能介绍
3. 运行和使用指南
4. 依赖安装说明
5. 注意事项
格式要清晰易读。
`;
const response = await llm.invoke([
{
role: 'system',
content: '你是一个技术文档专家,擅长编写清晰的项目说明文档。',
},
{ role: 'user', content: prompt },
]);
return {
projectStructure: response.content as string,
};
}
/**
* 工作器分配函数
* 为每个文件创建一个工作器任务
*/
function assignWorkers(state: typeof MultiFileGeneratorState.State) {
return state.fileSpecs.map(
(fileSpec) =>
new Send('generateFile', {
fileSpec,
projectContext: {
requirement: state.projectRequirement,
type: state.projectType,
allFiles: state.fileSpecs,
},
})
);
}
/**
* 构建多文件代码生成器图
*/
function createMultiFileGenerator() {
const workflow = new StateGraph(MultiFileGeneratorState)
.addNode('planProject', planProject)
.addNode('generateFile', generateFile)
.addNode('integrateProject', integrateProject)
.addEdge(START, 'planProject')
.addConditionalEdges('planProject', assignWorkers, ['generateFile'])
.addEdge('generateFile', 'integrateProject')
.addEdge('integrateProject', END);
return workflow.compile();
}
// 使用示例
async function runMultiFileGenerator() {
const app = createMultiFileGenerator();
console.log('🚀 启动多文件代码生成器...\n');
// 示例:生成一个React Todo应用
const result = await app.invoke({
projectRequirement: `
创建一个React Todo应用,功能包括:
1. 添加、删除、编辑待办事项
2. 标记完成状态
3. 过滤显示(全部、已完成、未完成)
4. 本地存储数据
5. 响应式设计
6. TypeScript支持
`,
});
console.log('📝 项目生成结果:');
console.log('项目类型:', result.projectType);
console.log('生成文件数量:', Object.keys(result.generatedFiles).length);
console.log('\n📁 生成的文件:');
Object.keys(result.generatedFiles).forEach((fileName, index) => {
console.log(`${index + 1}. ${fileName}`);
});
console.log('\n📋 项目结构说明:');
console.log(result.projectStructure);
console.log('\n📄 文件内容预览:');
Object.entries(result.generatedFiles).forEach(([fileName, content]) => {
console.log(`\n--- ${fileName} ---`);
console.log(content.substring(0, 200) + '...');
});
}
// 流式执行示例
async function runMultiFileGeneratorWithStreaming() {
const app = createMultiFileGenerator();
console.log('🚀 启动流式多文件生成器...\n');
const stream = await app.stream(
{
projectRequirement:
'创建一个简单的Express.js API服务器,包含用户管理和认证功能',
},
{ streamMode: 'updates' }
);
for await (const chunk of stream) {
const [nodeName, nodeOutput] = Object.entries(chunk)[0];
console.log(`📍 执行节点: ${nodeName}`);
if (nodeName === 'planProject') {
const output = nodeOutput as any;
console.log(` 项目类型: ${output.projectType}`);
console.log(` 规划文件: ${output.fileSpecs?.length || 0} 个`);
} else if (nodeName === 'generateFile') {
const output = nodeOutput as any;
const fileName = Object.keys(output.generatedFiles || {})[0];
console.log(` ✅ 生成文件: ${fileName}`);
} else if (nodeName === 'integrateProject') {
console.log(' 📦 项目整合完成');
}
console.log('');
}
}
// 批量生成示例
async function runBatchGeneration() {
const app = createMultiFileGenerator();
console.log('🚀 启动批量项目生成...\n');
const projects = [
{
name: 'React组件库',
requirement: '创建一个React组件库,包含Button、Input、Modal等基础组件',
},
{
name: 'Node.js工具包',
requirement:
'创建一个Node.js工具包,包含文件操作、日期处理、字符串工具等实用函数',
},
{
name: 'Vue.js单页应用',
requirement: '创建一个Vue.js单页应用,实现用户注册登录和个人资料管理',
},
];
for (const project of projects) {
console.log(`\n📦 生成项目: ${project.name}`);
console.log('='.repeat(40));
const result = await app.invoke({
projectRequirement: project.requirement,
});
console.log(
`✅ 完成 - 生成了 ${Object.keys(result.generatedFiles).length} 个文件`
);
console.log(`项目类型: ${result.projectType}`);
}
}
// 导出主要函数和类型
export {
MultiFileGeneratorState,
WorkerState,
FileSpec,
createMultiFileGenerator,
runMultiFileGenerator,
runMultiFileGeneratorWithStreaming,
runBatchGeneration,
planProject,
generateFile,
integrateProject,
assignWorkers,
};
// 如果直接运行此文件,执行示例
if (require.main === module) {
runMultiFileGenerator()
.then(() => {
console.log('\n' + '='.repeat(60) + '\n');
return runMultiFileGeneratorWithStreaming();
})
.then(() => {
console.log('\n' + '='.repeat(60) + '\n');
return runBatchGeneration();
})
.catch(console.error);
}
这个系统使用了 Orchestrator-Worker 模式:
- 规划器:分析项目需求,确定需要生成的文件
- 工作器:并行生成各个文件
- 整合器:组织和验证最终项目结构
多文件生成流程
工具集成
代码生成系统通常需要集成各种工具:
代码生成工具:
import '../../utils/loadEnv';
import { tool } from '@langchain/core/tools';
import { z } from 'zod';
/**
* 代码语法检查工具
* 模拟语法检查功能
*/
export const syntaxCheckTool = tool(
async ({ code, language }: { code: string; language: string }) => {
// 模拟语法检查逻辑
const issues: string[] = [];
// 基本语法检查
if (language === 'typescript' || language === 'javascript') {
// 检查括号匹配
const openBraces = (code.match(/\{/g) || []).length;
const closeBraces = (code.match(/\}/g) || []).length;
if (openBraces !== closeBraces) {
issues.push('括号不匹配');
}
// 检查分号
const lines = code.split('\n');
lines.forEach((line, index) => {
const trimmed = line.trim();
if (
trimmed &&
!trimmed.endsWith(';') &&
!trimmed.endsWith('{') &&
!trimmed.endsWith('}') &&
!trimmed.startsWith('//') &&
!trimmed.startsWith('/*') &&
!trimmed.includes('import') &&
!trimmed.includes('export')
) {
issues.push(`第${index + 1}行可能缺少分号`);
}
});
// 检查未定义变量(简单检查)
const variablePattern =
/(?:const|let|var|function)\s+([a-zA-Z_$][a-zA-Z0-9_$]*)/g;
const usagePattern = /\b([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/g; // 只检查函数调用
const defined = new Set<string>();
const used = new Set<string>();
// 添加常见的全局变量和函数
const globals = [
'console',
'window',
'document',
'process',
'require',
'module',
'exports',
'setTimeout',
'setInterval',
'clearTimeout',
'clearInterval',
'Math',
'Date',
'Array',
'Object',
'String',
'Number',
'Boolean',
'JSON',
'Promise',
'Error',
'RegExp',
'parseInt',
'parseFloat',
'isNaN',
'isFinite',
'encodeURIComponent',
'decodeURIComponent',
];
globals.forEach((g) => defined.add(g));
let match;
while ((match = variablePattern.exec(code)) !== null) {
defined.add(match[1]);
}
while ((match = usagePattern.exec(code)) !== null) {
used.add(match[1]);
}
// 检查可能未定义的函数调用
for (const variable of used) {
if (!defined.has(variable)) {
issues.push(`可能使用了未定义的变量: ${variable}`);
}
}
}
return {
isValid: issues.length === 0,
issues,
language,
checkedAt: new Date().toISOString(),
};
},
{
name: 'syntax_check',
description: '检查代码语法错误',
schema: z.object({
code: z.string().describe('要检查的代码'),
language: z.string().describe('编程语言'),
}),
}
);
/**
* 代码格式化工具
* 模拟代码格式化功能
*/
export const formatCodeTool = tool(
async ({ code, language }: { code: string; language: string }) => {
// 模拟代码格式化逻辑
let formattedCode = code;
if (language === 'typescript' || language === 'javascript') {
// 基本格式化
formattedCode = code
.split('\n')
.map((line) => {
// 移除行尾空格
line = line.trimEnd();
// 简单的缩进处理
const openBraces = (line.match(/\{/g) || []).length;
const closeBraces = (line.match(/\}/g) || []).length;
const indentLevel = Math.max(0, openBraces - closeBraces);
// 添加适当的缩进
if (line.trim()) {
return ' '.repeat(indentLevel) + line.trim();
}
return '';
})
.join('\n');
// 在操作符周围添加空格
formattedCode = formattedCode
.replace(/([^=!<>])=([^=])/g, '$1 = $2')
.replace(/([^=!<>])==([^=])/g, '$1 == $2')
.replace(/([^=!<>])===([^=])/g, '$1 === $2')
.replace(/([^!])!=([^=])/g, '$1 != $2')
.replace(/([^!])!==([^=])/g, '$1 !== $2')
.replace(/([^+])\+([^+=])/g, '$1 + $2')
.replace(/([^-])-([^-=])/g, '$1 - $2')
.replace(/([^*])\*([^*=])/g, '$1 * $2')
.replace(/([^/])\/([^/=])/g, '$1 / $2');
}
return {
originalCode: code,
formattedCode,
language,
formattedAt: new Date().toISOString(),
};
},
{
name: 'format_code',
description: '格式化代码',
schema: z.object({
code: z.string().describe('要格式化的代码'),
language: z.string().describe('编程语言'),
}),
}
);
/**
* 代码执行工具
* 模拟代码执行功能(仅用于演示)
*/
export const executeCodeTool = tool(
async ({ code, language }: { code: string; language: string }) => {
// 注意:这只是一个模拟工具,实际生产环境中需要安全的沙箱环境
try {
if (language === 'javascript') {
// 模拟JavaScript执行
const result = eval(code);
return {
success: true,
result: String(result),
output: '',
error: null,
executedAt: new Date().toISOString(),
};
} else {
return {
success: false,
result: null,
output: '',
error: `不支持执行${language}代码`,
executedAt: new Date().toISOString(),
};
}
} catch (error) {
return {
success: false,
result: null,
output: '',
error: error instanceof Error ? error.message : String(error),
executedAt: new Date().toISOString(),
};
}
},
{
name: 'execute_code',
description: '执行代码(仅用于简单测试)',
schema: z.object({
code: z.string().describe('要执行的代码'),
language: z.string().describe('编程语言'),
}),
}
);
/**
* 代码复杂度分析工具
*/
export const analyzeComplexityTool = tool(
async ({ code, language }: { code: string; language: string }) => {
const lines = code.split('\n').filter((line) => line.trim());
const totalLines = lines.length;
// 计算圈复杂度(简化版本)
let cyclomaticComplexity = 1; // 基础复杂度
const complexityKeywords = [
'if',
'else',
'while',
'for',
'switch',
'case',
'catch',
'&&',
'||',
'\\?',
];
for (const line of lines) {
for (const keyword of complexityKeywords) {
// 对于特殊字符,直接使用字符串匹配
if (keyword === '\\?') {
const count = (line.match(/\?/g) || []).length;
cyclomaticComplexity += count;
} else if (keyword === '&&' || keyword === '||') {
const count = (line.match(new RegExp(`\\${keyword}`, 'g')) || [])
.length;
cyclomaticComplexity += count;
} else {
const count = (line.match(new RegExp(`\\b${keyword}\\b`, 'g')) || [])
.length;
cyclomaticComplexity += count;
}
}
}
// 计算函数数量
const functionCount = (code.match(/function\s+\w+|=>\s*{|=>\s*\w+/g) || [])
.length;
// 计算注释比例
const commentLines = lines.filter(
(line) => line.trim().startsWith('//') || line.trim().startsWith('/*')
).length;
const commentRatio = totalLines > 0 ? commentLines / totalLines : 0;
// 复杂度评级
let complexityLevel: string;
if (cyclomaticComplexity <= 5) {
complexityLevel = '简单';
} else if (cyclomaticComplexity <= 10) {
complexityLevel = '中等';
} else if (cyclomaticComplexity <= 20) {
complexityLevel = '复杂';
} else {
complexityLevel = '非常复杂';
}
return {
totalLines,
cyclomaticComplexity,
complexityLevel,
functionCount,
commentRatio: Math.round(commentRatio * 100),
suggestions: [
cyclomaticComplexity > 10 && '考虑拆分复杂函数',
commentRatio < 0.1 && '建议增加代码注释',
functionCount > 10 && '考虑模块化设计',
].filter(Boolean),
analyzedAt: new Date().toISOString(),
};
},
{
name: 'analyze_complexity',
description: '分析代码复杂度',
schema: z.object({
code: z.string().describe('要分析的代码'),
language: z.string().describe('编程语言'),
}),
}
);
/**
* 代码安全检查工具
*/
export const securityCheckTool = tool(
async ({ code, language }: { code: string; language: string }) => {
const securityIssues: string[] = [];
const warnings: string[] = [];
if (language === 'javascript' || language === 'typescript') {
// 检查潜在的安全问题
const securityPatterns = [
{
pattern: /eval\s*\(/g,
issue: '使用eval()可能导致代码注入攻击',
severity: 'high',
},
{
pattern: /innerHTML\s*=/g,
issue: '直接设置innerHTML可能导致XSS攻击',
severity: 'medium',
},
{
pattern: /document\.write\s*\(/g,
issue: '使用document.write可能导致安全问题',
severity: 'medium',
},
{
pattern: /setTimeout\s*\(\s*["']/g,
issue: 'setTimeout使用字符串参数可能导致代码注入',
severity: 'high',
},
{
pattern: /setInterval\s*\(\s*["']/g,
issue: 'setInterval使用字符串参数可能导致代码注入',
severity: 'high',
},
{
pattern: /localStorage\.|sessionStorage\./g,
issue: '使用本地存储时注意数据敏感性',
severity: 'low',
},
];
for (const { pattern, issue, severity } of securityPatterns) {
if (pattern.test(code)) {
if (severity === 'high') {
securityIssues.push(issue);
} else {
warnings.push(issue);
}
}
}
// 检查硬编码密码或密钥
const sensitivePatterns = [
/password\s*[:=]\s*["'][^"']+["']/gi,
/api[_-]?key\s*[:=]\s*["'][^"']+["']/gi,
/secret\s*[:=]\s*["'][^"']+["']/gi,
/token\s*[:=]\s*["'][^"']+["']/gi,
];
for (const pattern of sensitivePatterns) {
if (pattern.test(code)) {
securityIssues.push('检测到可能的硬编码敏感信息');
break;
}
}
}
// 安全评级
let securityLevel: string;
if (securityIssues.length === 0) {
securityLevel = warnings.length === 0 ? '安全' : '基本安全';
} else if (securityIssues.length <= 2) {
securityLevel = '存在风险';
} else {
securityLevel = '高风险';
}
return {
securityLevel,
issues: securityIssues,
warnings,
recommendations: [
'避免使用eval()和类似的动态代码执行函数',
'对用户输入进行适当的验证和转义',
'使用环境变量存储敏感信息',
'定期更新依赖包以修复安全漏洞',
],
checkedAt: new Date().toISOString(),
};
},
{
name: 'security_check',
description: '检查代码安全问题',
schema: z.object({
code: z.string().describe('要检查的代码'),
language: z.string().describe('编程语言'),
}),
}
);
/**
* 生成单元测试工具
*/
export const generateTestTool = tool(
async ({
code,
language,
testFramework,
}: {
code: string;
language: string;
testFramework: string;
}) => {
// 分析代码中的函数
const functions: string[] = [];
// 匹配 function 声明
const functionDeclarations = code.match(/function\s+(\w+)/g);
if (functionDeclarations) {
functionDeclarations.forEach((match) => {
const name = match.replace('function ', '');
if (name) functions.push(name);
});
}
// 匹配 const/let/var 函数赋值(箭头函数或function表达式)
const functionAssignments = code.match(
/(?:const|let|var)\s+(\w+)\s*=\s*(?:\([^)]*\)\s*=>|function)/g
);
if (functionAssignments) {
functionAssignments.forEach((match) => {
const name = match
.replace(/(?:const|let|var)\s+/, '')
.replace(/\s*=\s*(?:\([^)]*\)\s*=>|function).*$/, '');
if (name) functions.push(name);
});
}
let testCode = '';
if (testFramework === 'jest' && language === 'javascript') {
testCode = `// 自动生成的测试文件
import { ${functions.join(', ')} } from './your-module';
describe('函数测试', () => {
${functions
.map(
(func) => ` test('${func} 应该正常工作', () => {
// TODO: 添加具体的测试用例
expect(${func}).toBeDefined();
});`
)
.join('\n\n')}
});
`;
} else if (testFramework === 'mocha' && language === 'javascript') {
testCode = `// 自动生成的测试文件
const { expect } = require('chai');
const { ${functions.join(', ')} } = require('./your-module');
describe('函数测试', () => {
${functions
.map(
(func) => ` it('${func} 应该正常工作', () => {
// TODO: 添加具体的测试用例
expect(${func}).to.exist;
});`
)
.join('\n\n')}
});
`;
} else {
testCode = `// 请手动编写测试用例
// 检测到的函数: ${functions.join(', ')}
`;
}
return {
testCode,
detectedFunctions: functions,
testFramework,
language,
generatedAt: new Date().toISOString(),
};
},
{
name: 'generate_test',
description: '生成单元测试代码',
schema: z.object({
code: z.string().describe('要生成测试的代码'),
language: z.string().describe('编程语言'),
testFramework: z.string().describe('测试框架(如:jest、mocha)'),
}),
}
);
// 导出所有工具
export const codeTools = [
syntaxCheckTool,
formatCodeTool,
executeCodeTool,
analyzeComplexityTool,
securityCheckTool,
generateTestTool,
];
// 工具使用示例
export async function demonstrateCodeTools() {
const sampleCode = `
function calculateSum(a, b) {
return a + b
}
const multiply = (x, y) => {
return x * y;
}
// 这是一个有安全问题的函数
function unsafeFunction(userInput) {
eval(userInput);
}
`;
console.log('🔧 代码工具演示\n');
// 语法检查
console.log('1. 语法检查:');
const syntaxResult = await syntaxCheckTool.invoke({
code: sampleCode,
language: 'javascript',
});
console.log('检查结果:', syntaxResult.isValid ? '✅ 通过' : '❌ 有问题');
if (syntaxResult.issues.length > 0) {
console.log('发现问题:', syntaxResult.issues);
}
// 代码格式化
console.log('\n2. 代码格式化:');
const formatResult = await formatCodeTool.invoke({
code: sampleCode,
language: 'javascript',
});
console.log('格式化完成 ✅');
// 复杂度分析
console.log('\n3. 复杂度分析:');
const complexityResult = await analyzeComplexityTool.invoke({
code: sampleCode,
language: 'javascript',
});
console.log(`复杂度等级: ${complexityResult.complexityLevel}`);
console.log(`圈复杂度: ${complexityResult.cyclomaticComplexity}`);
console.log(`函数数量: ${complexityResult.functionCount}`);
// 安全检查
console.log('\n4. 安全检查:');
const securityResult = await securityCheckTool.invoke({
code: sampleCode,
language: 'javascript',
});
console.log(`安全等级: ${securityResult.securityLevel}`);
if (securityResult.issues.length > 0) {
console.log('安全问题:', securityResult.issues);
}
// 生成测试
console.log('\n5. 生成测试:');
const testResult = await generateTestTool.invoke({
code: sampleCode,
language: 'javascript',
testFramework: 'jest',
});
console.log(`检测到函数: ${testResult.detectedFunctions.join(', ')}`);
console.log('测试代码已生成 ✅');
console.log('\n🎉 代码工具演示完成!');
}
// 如果直接运行此文件,执行演示
if (require.main === module) {
demonstrateCodeTools().catch(console.error);
}
工具选择建议
选择合适的工具对代码生成系统的成功至关重要:
- 语法检查:使用 ESLint、TSC 等工具
- 代码格式化:集成 Prettier、Black 等格式化工具
- 测试生成:自动生成单元测试和集成测试
- 文档生成:创建 README 和 API 文档
实践指导
1. 设计生成模板
创建可重用的代码模板:
// 组件模板示例
const componentTemplate = `
import React from 'react';
interface {{ComponentName}}Props {
{{props}}
}
export const {{ComponentName}}: React.FC<{{ComponentName}}Props> = ({{destructuredProps}}) => {
return (
<div className="{{className}}">
{{content}}
</div>
);
};
`;
2. 建立验证规则
定义代码质量标准:
const validationRules = {
syntax: ['no-syntax-errors', 'valid-typescript'],
style: ['consistent-naming', 'proper-indentation'],
logic: ['no-unused-variables', 'proper-error-handling'],
performance: ['avoid-unnecessary-renders', 'optimize-imports'],
};
3. 实现增量生成
支持代码的增量更新和修改:
// 增量更新策略
const updateStrategies = {
addFeature: 'append-to-existing',
modifyFunction: 'replace-function-body',
updateDependency: 'update-imports-and-usage',
};
高级特性
上下文感知生成
考虑现有代码库的上下文:
// 分析现有代码库
const analyzeCodebase = async (projectPath: string) => {
return {
framework: 'React',
typescript: true,
stateManagement: 'Redux',
styling: 'styled-components',
testingFramework: 'Jest',
};
};
智能错误修复
自动识别和修复常见错误:
const errorPatterns = {
'missing-import': {
pattern: /Cannot find name '(\w+)'/,
fix: (match) => `import { ${match[1]} } from 'appropriate-library';`,
},
'type-error': {
pattern: /Type '(\w+)' is not assignable to type '(\w+)'/,
fix: (match) => `// Add type assertion or fix type definition`,
},
};
性能优化
缓存机制
缓存常用的代码片段和模板:
const codeCache = new Map<string, string>();
const getCachedCode = (key: string) => {
return codeCache.get(key);
};
const setCachedCode = (key: string, code: string) => {
codeCache.set(key, code);
};
并行处理
利用 LangGraph 的并行处理能力:
// 并行生成多个文件
const parallelGeneration = async (files: FileSpec[]) => {
return Promise.all(files.map((file) => generateFile(file)));
};
小结与延伸
代码生成是 LangGraph 的一个强大应用场景,通过合理的架构设计和工具集成,可以构建出高效、可靠的代码生成系统。
关键要点:
- 使用 Evaluator-Optimizer 模式提高代码质量
- 利用 Orchestrator-Worker 模式处理复杂项目
- 集成适当的验证和优化工具
- 建立完善的错误处理机制
接下来,我们将学习如何使用 LangGraph 构建数据分析系统,探索数据处理和洞察提取的智能化方法。