调用OpenAI API传入FS读取的智能合约代码时遇400错误与undefined响应
问题分析与解决方案
1. 为什么会得到undefined?
你的genrateScript函数仅在控制台打印了API返回结果,没有返回生成的测试代码。调用时const testCode = await genrateScript.genrateScript(contract)自然会拿到undefined。
修复方法:
在函数中添加返回语句,同时抛出错误让调用方捕获:
async function genrateScript(smartContractCode) { try { const response = await openai.createCompletion({ model: "text-davinci-003", prompt: `Here is the smart contract code : ${smartContractCode} , write the test script for hardhat in Js`, max_tokens: 1000, // 先调整到合理范围 temperature: 0.5, }); const result = response.data.choices[0].text.trim(); console.log(result); return result; // 新增返回逻辑 } catch (error) { console.error("API调用失败:", error.response?.data || error.message); throw error; // 抛出错误,让调用方的try/catch捕获 } }
2. 400错误的常见原因与修复
原因1:max_tokens超出模型上限
text-davinci-003的最大上下文长度为4097 tokens(prompt内容 + 生成内容的tokens总和不能超过该值)。你设置的max_tokens: 10000远超限制,直接触发API报错。
修复:
根据合约代码长度调整max_tokens,确保prompt的tokens数 + max_tokens ≤4097。比如先设为1000-2000,后续可根据实际情况微调。
原因2:合约代码过长导致prompt超限
如果智能合约代码本身篇幅较长,加上prompt前缀后总tokens超过4097,API会返回400错误。
修复:
- 精简合约代码:只传入核心逻辑部分,删除注释、空行和无关代码;
- 更换大上下文模型:比如
gpt-3.5-turbo(支持4k/16k tokens),注意调用方式需改为createChatCompletion(适配聊天模型的调用格式)。
原因3:合约代码的特殊字符破坏prompt格式
合约中的换行、引号、特殊符号可能导致prompt格式异常,API无法正确解析。
修复:
对读取的合约代码做简单转义处理:
const contract = fs.readFileSync("./smartContract.sol", "utf-8") .replace(/"/g, '\\"') // 转义双引号 .replace(/\r\n/g, "\n") // 统一换行格式 .trim();
3. 修正后的完整调用代码
const genrateScript = require("./index"); const fs = require("fs"); // 读取并预处理合约代码 const contract = fs.readFileSync("./smartContract.sol", "utf-8") .replace(/"/g, '\\"') .trim(); async function main() { try { const testCode = await genrateScript.genrateScript(contract); if (testCode) { fs.writeFileSync("./testScript.js", testCode); console.log("测试脚本生成成功"); } } catch (error) { console.error("生成失败:", error); } } main();
内容的提问来源于stack exchange,提问作者krish
相关产品推荐
相关产品推荐

