
最近折腾了一下 RAG(检索增强生成)系统,把 Claude 和 ChatGPT 的 API 串起来用,踩了几个坑,这篇把关键点说清楚。
我们这套系统会把文档检索和两个大模型的能力结合起来:用户提问 → 从文档库拉相关资料 → 把上下文喂给 AI → 生成答案。这种玩法在客服机器人、技术文档问答这类场景很实用。
简单说,我们要做的是这样一件事:
用户输入查询 → 从预建好的文档库检索相关内容 → 把文档上下文分别发给 Claude 和 ChatGPT → 拿到两边的回答,可以对比着用,也可以合并。
这种双模型策略的好处是:一个模型的强项可能补另一个的弱项,尤其在需要高准确性的场景,比如客服系统、研发知识库。
先装依赖包:
npm install openai anthropic dotenv 在项目根目录建一个 .env 文件,把 API key 配进去:
OPENAI_API_KEY=your_openai_api_key
ANTHROPIC_API_KEY=your_anthropic_api_key
文档仓库本质上就是个数据源,我们用 JSON 文件模拟。实际生产环境可以换成向量数据库(Milvus、Pinecone 之类的)。
const fs = require('fs');
const documents = JSON.parse(fs.readFileSync('documents.json', 'utf8')); function getRelevantDocuments(query) { // 简单关键词匹配 return documents.filter(doc => doc.text.includes(query));
} module.exports = { getRelevantDocuments };
这个函数读取 JSON 文档,然后根据查询词过滤相关内容。实际项目中建议换成语义检索,效果会好很多。
初始化两个 AI 客户端:
require('dotenv').config();
const { OpenAI } = require('openai');
const { Anthropic } = require('anthropic'); const openAIClient = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
const anthropicClient = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY }); async function generateResponseWithClaude(prompt) { const response = await anthropicClient.chat.completions.create({ model: "claude-3-5-sonnet-20241022", messages: [{ role: "user", content: prompt }] }); return response.data.choices[0].message.content;
} async function generateResponseWithChatGPT(prompt) { const response = await openAIClient.chat.completions.create({ model: "gpt-4o", messages: [{ role: "user", content: prompt }] }); return response.data.choices[0].message.content;
} module.exports = { generateResponseWithClaude, generateResponseWithChatGPT };
两个函数分别调各自的 API,把 prompt 扔进去,拿回答回来。
现在把检索和 AI 能力串起来:
const { getRelevantDocuments } = require('./documentRepository');
const { generateResponseWithClaude, generateResponseWithChatGPT } = require('./aiIntegrations'); async function handleUserQuery(query) { const relevantDocs = getRelevantDocuments(query); const combinedContext = relevantDocs.map(doc => doc.text).join('\n'); const prompt = `Based on these documents:\n${combinedContext}\nAnswer the following question: ${query}`; const claudeResponse = await generateResponseWithClaude(prompt); const chatGPTResponse = await generateResponseWithChatGPT(prompt); return { claude: claudeResponse, chatGPT: chatGPTResponse };
} module.exports = { handleUserQuery };
核心流程:检索相关文档 → 拼成上下文 → 同时问两个模型 → 返回两边答案。
⚠️ 容易踩的坑:环境变量没配对或者 key 没加载进来,会直接报认证错误。先 console.log(process.env.OPENAI_API_KEY) 确认能读到。
写个简单脚本验证下:
const { handleUserQuery } = require('./queryHandler'); (async () => { const query = "How does the RAG system work?"; const responses = await handleUserQuery(query); console.log("Claude's response:", responses.claude); console.log("ChatGPT's response:", responses.chatGPT);
})();
跑一下,应该能看到两个模型各自的回答,对比一下质量和相关性。