基于自有PDF创建可公开访问的GPT技术方案咨询
问题分析与解决方案
核心问题拆解
- ChatCompletion端点不支持文件参数:你直接给
ChatCompletion.create()传file=file.id完全无效,该端点没有file参数,也不具备基于文件内容检索问答的能力——文件检索是Assistants API的专属功能。 - Assistants API调用流程错误:你注释掉的
client.assistants.chat是不存在的方法,Assistants API有固定的线程-消息-运行流程,并非直接调用chat接口。 - 界面GPT的分享限制:ChatGPT界面创建的自定义GPT,分享后仅限Plus用户使用是官方设定,要让普通用户可用,必须基于OpenAI API自行实现服务逻辑。
正确的Assistants API实现方案
以下是完整可运行的代码,实现基于上传PDF的问答功能:
from openai import OpenAI import time client = OpenAI(api_key="你的API密钥") # 1. 上传文件(仅需执行一次,后续可复用file_id) file = client.files.create( file=open("mydoc.pdf", "rb"), purpose='assistants' ) print(f"文件上传成功,file_id: {file.id}") # 2. 创建Assistant(仅需执行一次,后续可复用assistant_id) assistant = client.beta.assistants.create( instructions="你需要基于上传的PDF文档回答用户的问题,严格依据文档内容,不要编造信息。", model="gpt-4-1106-preview", tools=[{"type": "retrieval"}], file_ids=[file.id] ) print(f"Assistant创建成功,assistant_id: {assistant.id}") # 3. 创建对话线程(每次新对话创建一个,或复用已有线程) thread = client.beta.threads.create() print(f"对话线程创建成功,thread_id: {thread.id}") while True: user_input = input("你: ") if user_input.lower() in ["exit", "退出"]: print("结束对话") break # 4. 向线程添加用户消息 client.beta.threads.messages.create( thread_id=thread.id, role="user", content=user_input ) # 5. 运行Assistant处理对话 run = client.beta.threads.runs.create( thread_id=thread.id, assistant_id=assistant.id ) # 6. 等待Run执行完成 while run.status not in ["completed", "failed", "cancelled"]: time.sleep(1) run = client.beta.threads.runs.retrieve( thread_id=thread.id, run_id=run.id ) # 7. 获取并输出Assistant的回复 messages = client.beta.threads.messages.list( thread_id=thread.id ) # 最新消息在列表最前端,筛选assistant的回复 for msg in messages.data: if msg.role == "assistant": print(f"AI: {msg.content[0].text.value}") break
关键注意事项
- 资源复用:文件上传和Assistant创建只需执行一次,后续直接保存
file_id和assistant_id重复使用,避免浪费API额度。 - 权限自定义:基于API搭建的服务,你可以自行控制访问权限,普通用户无需ChatGPT Plus即可使用——只需搭配简单前端(如Flask/Django网页)提供交互入口。
- 错误处理:可添加对Run失败状态的逻辑处理,比如输出错误原因,提升服务稳定性。
- 模型适配:必须使用支持检索工具的模型,比如
gpt-4-1106-preview或gpt-3.5-turbo-1106,旧模型不兼容该工具。
内容的提问来源于stack exchange,提问作者dbeings
相关产品推荐
相关产品推荐

