AB
AiBoss
Tutorials

SophNet

Tutorials

用 SophNet 兼容 OpenAI SDK 调用基础模型与知识注入模型

面向开发者的实操教程:在 SophNet 项目下创建 API Key、启用 Chat Completion 服务,用兼容 OpenAI 的 Python SDK 完成基础模型调用,并为自定义模型注入 Q&A 与知识文档,包含非流式与流式两种调用方式及引用来源的处理。

SophNet 提供了一套与 OpenAI Python SDK 兼容的接口,开发者只要把 base_url 指向 SophNet 的地址、把 api_key 换成平台签发的密钥,就能沿用已有的 OpenAI 调用习惯去访问平台上的模型。它适合两类人:一类是已经用 OpenAI SDK 写过代码、想低成本切换或增加一个模型来源的开发者;另一类是需要在模型之上叠加自有知识(问答对、知识文档)再对外提供问答能力的团队。本文要讲清楚的是完整的一条链路:在项目里创建密钥、启用服务、跑通基础模型调用,再为自定义模型注入知识,并处理非流式与流式两种返回中的引用信息。如果你只是想先看看平台上有哪些工具可用,可以从 SophNet 这个条目入手了解。

准备工作

在写第一行代码之前,需要先把平台侧的前置条件准备好。这一步没做完,后面无论怎么调都会失败。

账号与项目

调用服务端 API 之前,必须先完成两件事:在项目下创建 API Key,以及启用对应的模型服务。这里有一个容易被忽略的约束:API Key 和你要调用的模型服务必须位于同一个项目下。如果密钥建在 A 项目、服务开在 B 项目,调用会失败。因此建议先确认自己当前所处的项目,再在这个项目里完成密钥与服务的创建。

访问凭证的传递方式

调用 API 时,访问凭证需要放在请求 Header 中,形式为 Authorization: Bearer API Key。使用 OpenAI SDK 时这一步由 SDK 自动完成,你只需要把密钥传给客户端构造函数即可,不需要手动拼 Header。

安装 Python 库

使用 Python SDK 前需要安装 OpenAI 库。在终端运行:

pip install openai

注意包名是 openai,导入时写作 from openai import OpenAI。装好之后就可以进入服务启用环节。

操作步骤

第一步:启用 Chat Completion 服务(基础模型)

在项目概览界面点击「添加新服务」,然后按下面的方式填写:

  • 服务名称:填写 ChatCompletion
  • 服务类型:选择「基础模型」
  • 模型:选择你要使用的模型

点击「确认」后,服务即创建成功。此时可以在「启用的服务列表」中看到这条服务的状态与信息。点击服务详情,页面会给出对应的调用示例,示例里的 model 值就是你在代码中应当填写的模型标识。

第二步:编写基础模型调用脚本

新建一个名为 chat_quickstart.py 的 Python 文件,在编辑器或 IDE 中打开,把内容替换为下面的代码:

from openai import OpenAI

# 初始化客户端
client = OpenAI(
    api_key="API_KEY",
    base_url="https://www.sophnet.com/api/open-apis"
)

# 调用接口
response = client.chat.completions.create(
    model="DeepSeek-v3",
    messages=[
        {"role": "system", "content": "你是Sophnet智能助手"},
        {"role": "user", "content": "你可以帮我做些什么"},
    ]
)

# 打印结果
print(response.choices[0].message.content)

代码里有三个关键点需要替换或确认:

  • api_key:换成你在项目下创建的真实密钥,不要保留占位符 API_KEY。
  • base_url:固定为 https://www.sophnet.com/api/open-apis,这是让 OpenAI SDK 指向 SophNet 的关键。
  • model:填写服务详情中调用示例给出的模型值。示例中用的是 DeepSeek-v3,实际可用模型以平台当前提供的为准。

messages 采用标准的对话结构:system 角色用于设定助手身份,user 角色用于提出请求。返回结果通过 response.choices[0].message.content 取出。

第三步:运行脚本

在终端执行:

python chat_quickstart.py

如果一切正常,终端会打印出模型对「你可以帮我做些什么」这个问题的回答。到这里,基础模型的接入就完成了。

第四步:启用自定义模型服务

如果要在模型之上叠加自己的知识,需要再启用一个服务,类型不同。同样在项目概览界面点击「添加新服务」:

  • 服务名称:填写 ChatCompletion
  • 服务类型:选择「自定义模型」
  • 模型:选择要使用的模型

点击「确认」。创建成功后,在启用的服务列表中可以看到这条服务,并且它带有「自定义」字样的标记。这个标记是后续进入知识注入入口的依据。

第五步:为自定义模型注入知识

平台支持两种知识注入方式:Q&A Table 和上传知识文档。两者可以按需选用。

方式一:Q&A Table

  1. 点击带有「自定义」字样的服务,进入服务详情。
  2. 点击「新建」按钮新增一条 Q&A。
  3. 填写「问题」和「回答」两个字段。
  4. 点击「保存」,这条知识即注入到模型中。

这种方式适合知识条目少、结构清晰、需要精确控制的场景,比如固定的业务口径、常见问题标准答案。

方式二:上传知识文档

  1. 点击「上传文件」按钮上传知识文件。
  2. 上传完成后,文件处于「未注入」状态。
  3. 点击「注入我的模型」,触发注入。
  4. 文件状态变为「已注入」,代表注入成功。

这里的状态流转值得留意:上传成功不等于注入成功。如果只上传而没有点「注入我的模型」,文件会一直停留在「未注入」,模型也就不会用到这份知识。排查「为什么模型答不出文档里的内容」时,先看这个状态。

第六步:获取自定义模型的 model 值

自定义模型的调用代码与基础模型几乎一致,唯一的差别在 model 参数。这个值不要凭猜测填写,应当从服务详情页的「调用示例」中读取,替换代码里的 YOUR_MODEL 占位符。

第七步:非流式调用并读取引用来源

非流式调用会在最终结果中一次性输出此次回答包含的所有引用来源信息。代码如下:

from openai import OpenAI

# 初始化客户端
client = OpenAI(
    api_key="API_KEY",
    base_url="https://www.sophnet.com/api/open-apis"
)

# 调用接口
response = client.chat.completions.create(
    model="YOUR_MODEL",
    messages=[
        {"role": "system", "content": "你是Sophnet智能助手"},
        {"role": "user", "content": "你可以帮我做些什么"},
    ]
)

# 打印结果
print(response.choices[0].message.content)

# 检查是否存在引用
if hasattr(chunk.choices[0], 'refs'):
    # 打印引用
    print(chunk.choices[0].refs)

引用信息挂在 choices[0] 上的 refs 属性里。由于不是每次回答都一定带引用,读取前要用 hasattr 做存在性判断,避免在没有引用的回答上直接访问而报错。

第八步:流式调用并实时处理引用

流式调用会在响应过程中实时输出内容,并且在存在引用的位置实时输出引用来源信息;当 finish_reason 不为空时,还会输出此次回答包含的所有引用来源信息。代码如下:

from openai import OpenAI

# 初始化客户端
client = OpenAI(
    api_key="API_KEY",
    base_url="https://www.sophnet.com/api/open-apis"
)

# 调用接口
response = client.chat.completions.create(
    model="YOUR_MODEL",
    messages=[
        {"role": "system", "content": "你是Sophnet智能助手"},
        {"role": "user", "content": "你可以帮我做些什么"},
    ],
    stream=True
)

for chunk in response:
    if chunk.choices:
        # 打印结果
        print(chunk.choices[0].delta.content)
        # 检查是否存在引用
        if hasattr(chunk.choices[0], 'refs'):
            # 打印引用
            print(chunk.choices[0].refs)

流式处理有两个细节必须注意。第一,遍历时要先判断 if chunk.choices,因为并非每个数据块都携带 choices,直接索引可能出错。第二,流式返回的正文在 chunk.choices[0].delta.content 中,而不是 message.content——这是与非流式调用最容易混淆的地方。

第九步:运行并验证

保存文件后执行:

python chat_quickstart.py

非流式版本会一次性打印完整回答,随后打印引用(若有)。流式版本会逐段打印回答内容,并在出现引用的位置插入引用信息。两种方式都可以用来验证知识注入是否生效:向模型提问一个只有你注入的知识才能回答的问题,看回答内容与 refs 是否符合预期。

一个完整示例

下面把前面的步骤串成一个可以直接运行的最小例子。假设你已经在同一个项目下创建了 API Key,并启用了一个「自定义模型」类型的 Chat Completion 服务,且已通过 Q&A Table 注入了一条知识。

第一步,确认环境。

pip install openai

第二步,新建 chat_quickstart.py,写入以下内容。这里用流式方式,便于同时观察正文与引用:

from openai import OpenAI

client = OpenAI(
    api_key="API_KEY",
    base_url="https://www.sophnet.com/api/open-apis"
)

response = client.chat.completions.create(
    model="YOUR_MODEL",
    messages=[
        {"role": "system", "content": "你是Sophnet智能助手"},
        {"role": "user", "content": "你可以帮我做些什么"},
    ],
    stream=True
)

for chunk in response:
    if chunk.choices:
        content = chunk.choices[0].delta.content
        if content:
            print(content, end="")
        if hasattr(chunk.choices[0], 'refs'):
            print("\n[refs]", chunk.choices[0].refs)

第三步,替换占位符。把 API_KEY 换成真实密钥,把 YOUR_MODEL 换成服务详情调用示例中给出的模型值。两处都不能留原样。

第四步,运行。

python chat_quickstart.py

第五步,核对结果。终端应当先逐段输出回答正文,遇到带引用的片段时输出 [refs] 及其内容。如果回答内容与你注入的知识一致,说明从密钥、服务、模型到知识注入的整条链路都是通的。

如果只想验证最基础的连通性,可以把 stream=True 去掉,改用非流式版本,并把 model 换成基础模型服务示例中的模型值。这样能快速区分问题出在「接入层」还是「知识注入层」。

注意事项

  • 密钥与服务必须同项目。这是最容易踩的坑:API Key 和模型服务不在同一个项目下时无法正常调用。创建密钥前先确认当前项目。
  • 先启用服务再写代码。没有启用 Chat Completion 服务,即使密钥正确也调不通。基础模型与自定义模型是两种不同的服务类型,需要分别添加。
  • model 值以调用示例为准。基础模型和自定义模型的 model 取值不同,自定义模型的标识必须从服务详情的调用示例中读取,不要自行拼写。
  • 上传不等于注入。知识文档上传后处于「未注入」状态,必须点击「注入我的模型」,状态变为「已注入」才算生效。
  • 引用字段需要判空。refs 并非每次回答都存在,读取前用 hasattr 判断,否则可能抛出异常。
  • 流式与非流式的字段不同。非流式读 message.content,流式读 delta.content;流式遍历时还要先判断 chunk.choices 是否为空。
  • 模型可用范围、价格与配额以官网当前信息为准。平台提供的模型清单、计费方式与调用额度会调整,接入前请以官网页面显示的最新内容为准,不要依赖本文中的示例模型名做容量或成本估算。