用于从 LLM API 获取结构化的 JSON 数据返回

20 阅读4分钟

没错ai写的,就是一个llm获取json数据的库,llm返回的json数据不可靠,加入了jsonrepair修复、验证、重试、缓存等功能而已

LLM JSON SDK

一个可靠的 SDK,用于从 LLM API 获取结构化的 JSON 数据返回。

特性

  • 🚀 支持任意兼容 OpenAI API 格式的 LLM 服务
  • 📦 自动解析 JSON 响应,支持提取 markdown 代码块中的 JSON
  • 🔧 内置 JSON 修复机制(jsonrepair),处理 LLM 幻觉导致的格式错误
  • 🔄 多层重试机制:API 重试 + JSON 解析重试 + 校验重试
  • 📝 简化的字段描述,只需传入 { key: "描述" } 即可
  • 💾 内置缓存机制,相同请求直接返回缓存结果
  • 💪 完整的 TypeScript 类型支持
  • 🌐 支持 Node.js、React、Vue 等多种环境

安装

npm install llm-json-sdk
# 或
pnpm add llm-json-sdk
# 或
yarn add llm-json-sdk

快速开始

import { LLMJsonSDK } from 'llm-json-sdk';

// 初始化 SDK
const sdk = new LLMJsonSDK({
  baseUrl: 'https://api.openai.com/v1',
  apiKey: 'your-api-key',
  model: 'gpt-4',
});

// 简单用法:只传要做什么
const result = await sdk.getJSON({
  content: '生成一个用户信息',
});

if (result.success) {
  console.log(result.data.result); // 实际数据在 result 字段中
} else {
  console.log(result.data);  // null
  console.log(result.error); // 错误信息
}

返回数据结构

SDK 会自动将 LLM 返回的数据包装在 result 字段中,确保数据结构一致:

// LLM 返回:{ "name": "张三", "age": 25 }
// SDK 返回:
{
  "result": {
    "name": "张三",
    "age": 25
  }
}

这样你可以始终通过 response.data.result 获取数据,无需关心具体的 key。

使用字段描述(推荐)

只需传入字段名和描述,SDK 会自动生成提示语:

const result = await sdk.getJSON({
  content: '生成一个随机用户',
  fields: {
    name: '用户姓名',
    age: '年龄(数字)',
    email: '邮箱地址',
  },
});

if (result.success) {
  console.log(result.data.result.name);
  console.log(result.data.result.age);
}

SDK 会自动生成类似这样的提示语:

期望的 JSON 结构:
{
  "result": {
      "name": 用户姓名
      "age": 年龄(数字)
      "email": 邮箱地址
  }
}

缓存功能

启用缓存后,相同的请求会直接返回缓存结果,不会重复调用 LLM:

const sdk = new LLMJsonSDK({
  baseUrl: 'https://api.openai.com/v1',
  apiKey: 'your-api-key',
  model: 'gpt-4',
  cache: true,           // 启用缓存
  cacheTTL: 600000,      // 缓存有效期 10 分钟(默认 5 分钟)
});

// 第一次请求,会调用 LLM
const result1 = await sdk.getJSON({ content: '生成用户信息' });
console.log(result1.fromCache); // false 或 undefined

// 第二次相同请求,直接返回缓存
const result2 = await sdk.getJSON({ content: '生成用户信息' });
console.log(result2.fromCache); // true

// 单次请求禁用缓存
const result3 = await sdk.getJSON({ content: '生成用户信息', cache: false });

// 手动清除所有缓存
sdk.clearCache();

缓存 key 基于content + fields + temperature + maxTokens + extraParams

响应结构

interface LLMResponse<T> {
  data: T | null;         // 解析后的数据,失败时为 null
  rawContent: string;     // 原始响应文本
  success: boolean;       // 是否成功解析
  error?: string;         // 错误信息(如果失败)
  fromCache?: boolean;    // 是否来自缓存
  usage?: {               // Token 使用量(来自缓存时无此字段)
    promptTokens: number;
    completionTokens: number;
    totalTokens: number;
  };
}

配置选项

interface LLMConfig {
  baseUrl: string;           // LLM API 基础地址
  apiKey: string;            // API 密钥
  model: string;             // 模型名称
  timeout?: number;          // 请求超时时间(毫秒),默认 30000
  maxRetries?: number;       // API 最大重试次数,默认 3
  jsonRepairRetries?: number; // JSON 修复重试次数,默认 2
  cache?: boolean;           // 是否启用缓存,默认 false
  cacheTTL?: number;         // 缓存过期时间(毫秒),默认 300000 (5分钟)
}

请求选项

interface LLMRequestOptions {
  content: string;           // 用户消息(要做什么)
  fields?: FieldDescription; // 期望的字段描述
  temperature?: number;      // 温度参数 0-2,默认 0.7
  maxTokens?: number;        // 最大生成 token 数
  extraParams?: Record<string, unknown>; // 额外的请求参数
  cache?: boolean;           // 是否使用缓存(未设置则使用 LLMConfig.cache)
}

TypeScript 类型支持

import { LLMJsonSDK, LLMResponse, LLMError, JSONParseError } from 'llm-json-sdk';

// 定义返回类型
interface UserInfo {
  name: string;
  age: number;
  email: string;
}

// 类型推断
const result: LLMResponse<{ result: UserInfo }> = await sdk.getJSON<UserInfo>({
  content: '生成用户信息',
});

if (result.success) {
  // result.data.result 类型为 UserInfo
  console.log(result.data.result.name);
}

错误处理

SDK 不会抛出异常,而是通过返回值判断:

const result = await sdk.getJSON({
  content: '生成数据',
  fields: { name: '名称' },
});

if (result.success) {
  // 成功,使用 result.data.result
  console.log(result.data.result);
} else {
  // 失败,result.data 为 null
  console.error('解析失败:', result.error);
  console.log('原始响应:', result.rawContent);
}

内置 JSON 修复机制

SDK 会自动尝试修复 LLM 返回的格式错误:

  1. 提取 markdown 代码块中的 JSON
  2. 移除注释(///* */
  3. 修复尾随逗号(,},]
  4. 修复缺少引号的键名
  5. 使用 jsonrepair 库进行深度修复
  6. 多次重试直到成功或全部失败

兼容性

环境支持
Node.js
React
Vue
浏览器
Next.js
Nuxt

示例

在 Node.js 中使用

import { LLMJsonSDK } from 'llm-json-sdk';

const sdk = new LLMJsonSDK({
  baseUrl: process.env.LLM_BASE_URL!,
  apiKey: process.env.LLM_API_KEY!,
  model: 'gpt-4',
});

const result = await sdk.getJSON({
  content: '生成一个产品列表',
  fields: {
    products: '产品数组',
    total: '总数量',
  },
});

在 React 中使用

import { LLMJsonSDK } from 'llm-json-sdk';

const sdk = new LLMJsonSDK({
  baseUrl: import.meta.env.VITE_LLM_BASE_URL,
  apiKey: import.meta.env.VITE_LLM_API_KEY,
  model: 'gpt-4',
  cache: true,
});

function App() {
  const [data, setData] = useState(null);

  const fetchData = async () => {
    const result = await sdk.getJSON({
      content: '生成用户信息',
    });
    if (result.success) {
      setData(result.data.result);
    }
  };

  return <button onClick={fetchData}>获取数据</button>;
}

使用其他 LLM 服务

// 使用 Azure OpenAI
const sdk = new LLMJsonSDK({
  baseUrl: 'https://your-resource.openai.azure.com/openai/deployments/your-deployment',
  apiKey: 'your-azure-key',
  model: 'gpt-4',
});

// 使用本地 LLM (如 Ollama)
const sdk = new LLMJsonSDK({
  baseUrl: 'http://localhost:11434/v1',
  apiKey: 'ollama', // Ollama 不需要 key,但字段必填
  model: 'llama2',
});

// 使用其他兼容 OpenAI API 的服务
const sdk = new LLMJsonSDK({
  baseUrl: 'https://your-llm-service.com/v1',
  apiKey: 'your-key',
  model: 'your-model',
});

示例

image.png

image.png

image.png

image.png