ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

用DeepSeek打造智能问答系统:TaoToken统一API接入与RAG检索增强实战

用DeepSeek打造智能问答系统:TaoToken统一API接入与RAG检索增强实战 1. 从零搭建智能问答系统为什么我选 TaoToken 统一 API 接入 DeepSeek如果你正在搜「DeepSeek 智能问答系统怎么搭」「Python RAG 检索增强实战」大概率会遇到两个卡点一是模型 API 的接入方式五花八门二是 RAG 流程听起来玄乎真动手又不知道从哪切。这篇就把这两件事一次讲透用 Python 从零跑通一个最小可用的问答系统模型走 TaoToken 统一 API 通道接入 DeepSeek检索部分用本地向量库做 RAG 增强。先说清楚这套系统是什么、能做什么、适合谁。它是一个基于 DeepSeek 大模型的问答服务你把自己的文档产品手册、内部规范、FAQ喂进去用户提问时系统先从文档里检索相关片段再把片段作为上下文交给 DeepSeek 生成回答。适合三类人想给公司做内部知识库的后端同学、想练手 RAG 的算法入门者、以及需要快速验证 AI 问答产品的独立开发者。为什么用 TaoToken 而不是直连各家模型因为统一 API 通道的价值在于一套 Base URL、一个 Key、一套 OpenAI 兼容的调用格式就能切换 DeepSeek 等不同模型。你写好的 Python 代码不用改换模型只改一个 model 字段。对 RAG 这种需要反复对比不同模型效果的场景省下的适配时间非常可观。下面所有代码都基于这个前提你可以直接复制运行。2. TaoToken 前置准备拿 Key、配环境、装依赖动手前先把地基打好。这一章解决三件事注册拿 API Key、配置 Python 环境、安装依赖库。别跳过后面所有代码都依赖这里的配置。2.1 获取 TaoToken API Key打开 TaoToken 官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册登录后进入控制台。在左侧菜单找到「API Keys」点「创建新密钥」复制生成的 Key。这个 Key 只显示一次务必存好。拿到 Key 后我建议不要硬编码进代码而是写进环境变量。Linux/macOS 下export TAOTOKEN_API_KEYsk-你的密钥Windows PowerShell$env:TAOTOKEN_API_KEYsk-你的密钥如果你用.env文件管理装个python-dotenv更省事。记住一点Key 泄露等于钱包泄露别提交到 Git。2.2 安装 Python 依赖环境要求 Python 3.8 以上。我们需要的库不多openai负责调用 APInumpy做向量计算scikit-learn提供余弦相似度pypdf用来读 PDF 文档。一条命令装齐pip install openai numpy scikit-learn pypdf python-dotenv这里解释下为什么不用 LangChain 或 LlamaIndex。它们功能全但对新手来说抽象层太厚出问题不好排查。我们先用最朴素的 numpy 手写向量检索把 RAG 的每一步都摊开给你看理解透了再上框架也不迟。2.3 验证 API 通道连通性在写完整系统前先跑一个最小请求确认通道没问题。新建test_conn.pyimport os from openai import OpenAI client OpenAI( api_keyos.environ.get(TAOTOKEN_API_KEY), base_urlhttps://taotoken.net/api, ) resp client.chat.completions.create( modeldeepseek-chat, messages[{role: user, content: 回复两个字通了}], max_tokens16, ) print(resp.choices[0].message.content)运行python test_conn.py如果打印出「通了」或类似内容说明 Base URL、Key、模型 ID 三件套都对了。如果报 401检查 Key 是否复制完整如果报连接错误检查网络和 Base URL 拼写。这一步过了再往下走。3. 可复制配置DeepSeek 接入参数与 RAG 向量库搭建这一章是核心交付两样东西一份可直接用的 API 配置以及一个能跑的本地向量库。配置部分我会给出 JSON 和 Python 两种形式路径和字段名都按实际可用的来。3.1 API 配置片段JSON 与 Python先看 JSON 配置适合放进config.json统一管理{ base_url: https://taotoken.net/api, api_key_env: TAOTOKEN_API_KEY, model: deepseek-chat, temperature: 0.3, max_tokens: 1024, embedding_model: deepseek-chat }注意temperature设成 0.3因为 RAG 场景要的是忠实于检索内容不是天马行空。api_key_env存的是环境变量名不是 Key 本身这样配置文件可以安全提交。对应的 Python 加载逻辑import os, json from openai import OpenAI with open(config.json, r, encodingutf-8) as f: cfg json.load(f) client OpenAI( api_keyos.environ.get(cfg[api_key_env]), base_urlcfg[base_url], ) def chat(messages, streamFalse): return client.chat.completions.create( modelcfg[model], messagesmessages, temperaturecfg[temperature], max_tokenscfg[max_tokens], streamstream, )这套配置的好处是换模型只改config.json里的model字段代码零改动。TaoToken 的 OpenAI 兼容格式让这件事变得很自然。3.2 文档切片与向量化RAG 第一步是把文档切成小块。切太大检索不准切太小丢上下文。我的经验是中文按 300 到 500 字一块块之间留 50 字重叠避免句子被拦腰截断。def split_text(text, chunk_size400, overlap50): chunks, start [], 0 while start len(text): end start chunk_size chunks.append(text[start:end]) start end - overlap return chunks向量化这一步严格说需要 embedding 模型。为了让你不依赖额外服务就能跑通这里用一个轻量方案用字符 n-gram 的 TF-IDF 向量代替神经 embedding。效果不如专业 embedding但足以验证整条链路且完全离线。from sklearn.feature_extraction.text import TfidfVectorizer import numpy as np class VectorStore: def __init__(self): self.vectorizer TfidfVectorizer(analyzerchar, ngram_range(2, 3)) self.matrix None self.chunks [] def add(self, chunks): self.chunks chunks self.matrix self.vectorizer.fit_transform(chunks) def search(self, query, top_k3): q_vec self.vectorizer.transform([query]) scores (self.matrix q_vec.T).toarray().ravel() idx np.argsort(scores)[::-1][:top_k] return [(self.chunks[i], scores[i]) for i in idx if scores[i] 0]TfidfVectorizer用字符级 2-3 gram对中文友好不需要分词。search返回得分最高的 top_k 个片段。生产环境你可以把这里换成 DeepSeek 的 embedding 接口或本地 bge 模型接口保持一致即可。3.3 组装 RAG 问答主流程把检索和生成串起来。核心思路用户提问 → 检索相关片段 → 拼进 Prompt → 调 DeepSeek 生成。def rag_answer(store, question, top_k3): hits store.search(question, top_ktop_k) context \n\n.join([f[片段{i1}] {c} for i, (c, _) in enumerate(hits)]) messages [ {role: system, content: 你是知识库助手。只根据提供的资料回答资料中没有的信息就明确说不知道不要编造。}, {role: user, content: f资料\n{context}\n\n问题{question}}, ] resp chat(messages) return resp.choices[0].message.content, hits系统提示里那句「资料中没有就说不知道」很关键能大幅降低幻觉。temperature已经在配置里压到 0.3进一步保证回答贴着资料走。4. 验证请求端到端跑通一次问答并看结果配置写完了得真跑一次才算数。这一章给你完整的可执行脚本和预期输出照着做就能看到结果。4.1 完整可运行脚本新建rag_demo.py把前面所有片段整合import os, json from openai import OpenAI from sklearn.feature_extraction.text import TfidfVectorizer import numpy as np with open(config.json, r, encodingutf-8) as f: cfg json.load(f) client OpenAI(api_keyos.environ.get(cfg[api_key_env]), base_urlcfg[base_url]) def split_text(text, chunk_size400, overlap50): chunks, start [], 0 while start len(text): chunks.append(text[start:start chunk_size]) start chunk_size - overlap return chunks class VectorStore: def __init__(self): self.vectorizer TfidfVectorizer(analyzerchar, ngram_range(2, 3)) self.matrix, self.chunks None, [] def add(self, chunks): self.chunks chunks self.matrix self.vectorizer.fit_transform(chunks) def search(self, query, top_k3): q self.vectorizer.transform([query]) scores (self.matrix q.T).toarray().ravel() idx np.argsort(scores)[::-1][:top_k] return [(self.chunks[i], float(scores[i])) for i in idx if scores[i] 0] def rag_answer(store, question, top_k3): hits store.search(question, top_ktop_k) context \n\n.join([f[片段{i1}] {c} for i, (c, _) in enumerate(hits)]) messages [ {role: system, content: 你是知识库助手。只根据资料回答没有的信息说不知道。}, {role: user, content: f资料\n{context}\n\n问题{question}}, ] resp client.chat.completions.create( modelcfg[model], messagesmessages, temperaturecfg[temperature], max_tokenscfg[max_tokens], ) return resp.choices[0].message.content, hits if __name__ __main__: doc TaoToken 是一个统一的大模型 API 接入平台提供 OpenAI 兼容接口。 开发者只需配置 Base URL 为 https://taotoken.net/api即可调用 DeepSeek 等模型。 平台支持流式输出、多轮对话和自定义参数适合构建问答系统与智能体应用。 计费按 Token 用量结算控制台可查看实时消耗。 store VectorStore() store.add(split_text(doc)) answer, hits rag_answer(store, TaoToken 的 Base URL 是什么) print(检索命中, [round(s, 3) for _, s in hits]) print(回答, answer)4.2 预期输出与结果解读运行python rag_demo.py你会看到类似输出检索命中 [0.42, 0.18, 0.05] 回答 TaoToken 的 Base URL 是 https://taotoken.net/api。检索命中列表是每个片段的相似度得分第一个片段得分最高说明它最相关。回答部分模型准确提取了 URL没有编造。如果你问一个文档里没有的问题比如「TaoToken 支持哪些支付方式」模型应该回答「资料中没有相关信息」这就是系统提示在起作用。4.3 换成流式输出提升体验问答系统上线后用户最烦的是等半天没反应。把streamTrue打开边生成边显示def rag_answer_stream(store, question, top_k3): hits store.search(question, top_ktop_k) context \n\n.join([c for c, _ in hits]) messages [ {role: system, content: 你是知识库助手只根据资料回答。}, {role: user, content: f资料\n{context}\n\n问题{question}}, ] stream client.chat.completions.create( modelcfg[model], messagesmessages, temperaturecfg[temperature], streamTrue, ) collected for chunk in stream: delta chunk.choices[0].delta if delta.content: print(delta.content, end, flushTrue) collected delta.content print() return collected流式模式下注意一点chunk.choices[0].delta.content可能是 None比如首个 chunk 只带 role所以要先判断再拼接否则会报TypeError。5. 本篇常见报错排查401、local proxy failed、reading choices 全解代码跑不通是常态这一章把 RAG 接入 DeepSeek 时最容易撞的坑列出来对照报错直接定位。5.1 401 Authentication Error报错长这样openai.AuthenticationError: Error code: 401 - {error: {message: Invalid API key}}。原因无非三个Key 没设置进环境变量、Key 复制时带了空格、Key 已失效。排查顺序先在终端echo $TAOTOKEN_API_KEYWindows 用echo %TAOTOKEN_API_KEY%确认变量有值再检查代码里os.environ.get的变量名和导出时是否一致最后去控制台确认 Key 状态。注意base_url必须是https://taotoken.net/api少写/api或写成别的路径也会 401。5.2 APIConnectionError / local proxy failed报错openai.APIConnectionError: Connection error或日志里出现local proxy failed。这类是网络层问题。先确认机器能正常访问外网再检查有没有残留的代理环境变量干扰。执行env | grep -i proxyWindows 用set | findstr /i proxy如果有HTTP_PROXY、HTTPS_PROXY指向一个已经关掉的本地端口就会报 local proxy failed。清掉这些变量unset HTTP_PROXY HTTPS_PROXY ALL_PROXY然后重跑。另外确认base_url拼写完整别漏了协议头。5.3 reading choices / IndexError报错TypeError: NoneType object is not subscriptable或IndexError: list index out of range通常发生在resp.choices[0]这一行。根因是响应结构和你预期的不一样。流式模式下某些 chunk 的choices是空列表非流式下如果请求被限流返回体里可能没有choices。稳妥写法是先判空if resp.choices and resp.choices[0].message.content: answer resp.choices[0].message.content else: answer 模型未返回内容请检查请求参数流式循环里同理先if chunk.choices:再取 delta。5.4 OAuth / token 过期类报错如果你在别的工具里见过OAuth token expired或invalid_grant那是另一套鉴权体系。TaoToken 走的是 API Key 模式不涉及 OAuth 流程。如果你把 Key 配到了需要 OAuth 的工具里会报鉴权失败。确认你用的是「API Key」而不是「OAuth 客户端」两者别混。5.5 检索结果为空导致回答跑偏这个不报错但结果不对。现象是模型回答「资料中没有相关信息」但你明明上传了文档。排查打印store.search(question)的返回看是否为空列表。为空通常是切片粒度问题——问题关键词和文档用词不一致。解决办法是调小chunk_size或把 TF-IDF 换成语义 embedding。另外确认文档确实被add进去了len(store.chunks)应该有值。6. 继续深入把最小系统扩展成可用产品跑通最小系统只是起点。这一章给你几个明确的下一步方向以及对应的 TaoToken 入口方便你按需深入。6.1 换用真正的语义向量TF-IDF 只能匹配字面遇到同义改写就歇菜。生产环境建议换成 embedding 模型。你可以通过 TaoToken 的模型对话入口先对比不同模型效果https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 。把VectorStore里的 TF-IDF 替换成 embedding 接口调用search方法改用余弦相似度其余代码不动。6.2 多轮对话与历史管理现在的rag_answer是单轮的。要做多轮维护一个history列表每轮把检索到的 context 和用户问题追加进去同时定期裁剪过长的历史控制成本。注意 RAG 场景下历史不宜太长否则旧 context 会干扰当前检索。6.3 用 Coding Plan 做长期迭代如果你打算把这个问答系统持续做下去涉及大量代码编写和调试可以了解下 TaoToken 的 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。它适合需要长期调用模型做开发辅助的场景配合本文的接入方式能把编码效率提上来。6.4 上线前的检查清单最后给你一份上线前自查Key 是否走环境变量、temperature是否压低、系统提示是否加了「不知道就说不知道」、检索 top_k 是否合理、是否加了超时和重试、日志是否记录了每次请求的 Token 消耗。这几项做完你的问答系统就从 demo 迈向了可用。API Key 管理入口在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 遇到问题先翻文档再排查。把上面这套跑一遍你就有了一个能检索、能生成、能流式输出的 DeepSeek 问答系统。剩下的就是喂数据、调提示、换向量模型一步步把它磨成真正好用的产品。
返回列表