index.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. "use strict";
  2. /**
  3. * 统一的 LLM 服务 - 使用 LangChain 管理多模型
  4. */
  5. Object.defineProperty(exports, "__esModule", { value: true });
  6. exports.getLLM = getLLM;
  7. exports.callLLM = callLLM;
  8. exports.callLLMStream = callLLMStream;
  9. exports.getAvailableModels = getAvailableModels;
  10. exports.clearModelCache = clearModelCache;
  11. const openai_1 = require("@langchain/openai");
  12. const config_1 = require("../../config");
  13. // 模型缓存
  14. const modelCache = new Map();
  15. /**
  16. * 获取 ChatOpenAI 实例
  17. */
  18. function getLLM(modelId) {
  19. const id = modelId || config_1.config.models.textGeneration.defaultModel;
  20. if (modelCache.has(id)) {
  21. return modelCache.get(id);
  22. }
  23. const modelConfig = config_1.config.models.getModel(id);
  24. if (!modelConfig) {
  25. throw new Error(`模型 ${id} 不存在`);
  26. }
  27. if (!modelConfig.apiKey) {
  28. throw new Error(`模型 ${id} 缺少 API Key`);
  29. }
  30. const llm = new openai_1.ChatOpenAI({
  31. model: id,
  32. apiKey: modelConfig.apiKey,
  33. temperature: modelConfig.temperature,
  34. maxTokens: modelConfig.maxTokens,
  35. configuration: {
  36. baseURL: modelConfig.baseUrl,
  37. },
  38. });
  39. modelCache.set(id, llm);
  40. return llm;
  41. }
  42. /**
  43. * 统一调用 - 带自动切换
  44. */
  45. async function callLLM(prompt, modelId) {
  46. const id = modelId || config_1.config.models.textGeneration.defaultModel;
  47. try {
  48. const llm = getLLM(id);
  49. const response = await llm.invoke(prompt);
  50. return response.content;
  51. }
  52. catch (error) {
  53. const errorMessage = error?.message || '';
  54. // 检查是否需要切换模型
  55. if (config_1.config.models.shouldSwitchModel(errorMessage)) {
  56. const nextModel = config_1.config.models.getNextModel(id, 'text');
  57. if (nextModel) {
  58. console.log(`[LLM] ${id} 失败,自动切换到 ${nextModel}`);
  59. return callLLM(prompt, nextModel);
  60. }
  61. }
  62. throw error;
  63. }
  64. }
  65. /**
  66. * 流式调用
  67. */
  68. async function* callLLMStream(prompt, modelId) {
  69. const id = modelId || config_1.config.models.textGeneration.defaultModel;
  70. try {
  71. const llm = getLLM(id);
  72. const stream = await llm.stream(prompt);
  73. for await (const chunk of stream) {
  74. yield chunk.content;
  75. }
  76. }
  77. catch (error) {
  78. const errorMessage = error?.message || '';
  79. if (config_1.config.models.shouldSwitchModel(errorMessage)) {
  80. const nextModel = config_1.config.models.getNextModel(id, 'text');
  81. if (nextModel) {
  82. console.log(`[LLM] ${id} 失败,自动切换到 ${nextModel}`);
  83. yield* callLLMStream(prompt, nextModel);
  84. return;
  85. }
  86. }
  87. throw error;
  88. }
  89. }
  90. /**
  91. * 获取可用模型列表
  92. */
  93. function getAvailableModels() {
  94. return config_1.config.models.getModelsByType('text');
  95. }
  96. /**
  97. * 清除模型缓存
  98. */
  99. function clearModelCache() {
  100. modelCache.clear();
  101. }