用 Python 接入大模型 API:从 0 到 1 实现文本分类/抽取/匹配

写在前面

随着ChatGPT、通义千问等大语言模型的兴起,越来越多的开发者希望在自己的应用中集成AI能力,我决定通过实践来学习大模型API的调用方法。

我使用Python作为开发语言,采用阿里云百炼的通义千问模型(qwen3-max)作为基础模型,同时也体验了本地Ollama部署的qwen3:4b模型。

主题 :围绕"科技资讯"这个方向,一步步实现文本分类信息抽取语义匹配三个常见场景。

1.环境准备

1.1 安装python

www.python.org/downloads/

验证 Python 环境是否安装成功

bash 复制代码
# 通用命令(推荐,所有系统兼容)
python3 --version
# 补充:Windows系统若已配置PATH,也可执行
python --version

验证 pip3(Python 包管理工具)pip3 是 Python3 默认的包管理工具类似于安装Nodejs中npm包管理工具,用于安装第三方库,验证命令:

bash 复制代码
# 通用命令
pip3 --version
# Windows补充命令
pip --version

安装成功

2. OpenAI 库的基础使用

Python 库已经成为了调用大模型的"事实标准"。不管是 OpenAI 官方、阿里云 DashScope、还是本地 Ollama,都提供了 OpenAI 兼容的接口。这意味着写一套代码,换个 base_url 就能切换模型。

2.1 安装openai

bash 复制代码
pip install openai

模型可以使用阿里云百炼,也可以使用 Ollama本地部署模型,先启动 Ollama 并拉取模型:

2.2 第一次调用OpenAI

最简单的调用只需要三步:创建 client → 构造 messages → 发起请求。

python 复制代码
from openai import OpenAI

# 1. 创建 client 对象
client = OpenAI(
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    # api_key="YOUR_API_KEY"  # 如果环境变量没配,这里需要手动传
)

# 2. 调用模型
response = client.chat.completions.create(
    model="qwen3-max",
    messages=[
        {"role": "system", "content": "你是一个科技资讯助手"},
        {"role": "user", "content": "2026年AI领域有哪些重要趋势?"},
    ]
)

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

api_key可以直接配置到全局环境变量中~./zshrc,就无需在创建client时明文传入了

bash 复制代码
export OPENAI_API_KEY="your key"
export DASHSCOPE_API_KEY="your key"

关键点拆解

参数 作用
base_url API 地址,换这个就能切换不同服务商
model 模型名称,不同平台名称不一样
messages 对话历史,system 设定人设,user 是用户输入,assistant 是模型回复
role 三条消息角色:system(系统设定)、user(用户)、assistant(助手)

system 消息就像是给演员的"角色剧本",告诉模型"你是谁、该怎么做"。assistant 消息可以用作 few-shot 示例,让模型"照着学"。

2.3 流式输出:让用户体验"打字机"效果

非流式调用会等模型全部生成完才返回,用户可能要等十几秒。开启 stream=True 后,模型每生成一段就返回一段,实现类似 ChatGPT 的打字机效果。

python 复制代码
from openai import OpenAI

client = OpenAI(
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)

response = client.chat.completions.create(
    model="qwen3-max",
    messages=[
        {"role": "system", "content": "你是一个科技资讯助手,回答问题时请简洁"},
        {"role": "user", "content": "什么是大语言模型?用一句话解释"},
    ],
    stream=True     # 开启流式输出
)

# 流式返回的结果需要遍历 chunk
for chunk in response:
    print(chunk.choices[0].delta.content, end="", flush=True)

流式处理要点

  • chunk.choices[0].delta.content 是每一小段文本,可能是几个字或一个词
  • end="" 避免 print 自动换行,flush=True 立即刷新到终端
  • 第一个 chunk 的 delta.content 可能为 None,生产环境需要做空值判断

2.4 附带历史消息:让模型"记住"上下文

大模型本身是无状态的,每次调用都是独立的。要实现多轮对话,需要把之前的消息一起发过去。

python 复制代码
from openai import OpenAI

client = OpenAI(
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)

# 把之前的对话历史全部带上
response = client.chat.completions.create(
    model="qwen3-max",
    messages=[
        {"role": "system", "content": "你是科技资讯助手,回答简洁"},
        {"role": "user", "content": "英伟达最新一代GPU是什么?"},
        {"role": "assistant", "content": "英伟达最新一代数据中心GPU是Blackwell架构的B200。"},
        {"role": "user", "content": "它比上一代性能提升多少?"},   # 这个问题依赖上文
    ],
    stream=True
)

for chunk in response:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

为什么需要历史消息? 第二个问题"它比上一代性能提升多少?"中的"它"指代的是前面提到的 B200。如果不带上历史消息,模型就不知道"它"是谁。

3. 提示词优化实战

提示词(Prompt)决定了模型的输出质量。下面通过三个实战案例,展示几种最常用且效果立竿见影的提示词优化技巧。

统一主题:所有案例都围绕"科技资讯处理"场景,包括科技文章分类、关键信息抽取、语义相似度判断。

3.1 案例一:科技文本分类(Few-Shot 提示)

场景:给定一段科技相关的文本,自动判断它属于哪个类别。

核心思路:Few-Shot Learning

直接让模型分类,它可能按自己的理解来。但如果给它几个"输入→输出"的示例,它就能照葫芦画瓢,准确率大幅提升。这就是 Few-Shot Prompting

python 复制代码
from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:11434/v1"  # 本地 Ollama
)

# 示例数据:类别 → 文本
examples_data = {
    'AI前沿': 'OpenAI今日发布了GPT-5,该模型在多项基准测试中超越前代,特别是在数学推理和代码生成方面表现突出。',
    '产品发布': '苹果公司在WWDC上正式推出了Vision Pro二代,售价降低至2000美元,新增手势追踪和眼动交互功能。',
    '行业分析': '据IDC最新报告,2025年Q2全球AI芯片市场规模达到180亿美元,同比增长65%,其中GPU占比超过70%。',
    '投融资': 'AI编程助手Cursor完成1亿美元C轮融资,估值达到100亿美元,红杉资本领投。'
}

# 待分类的文本
questions = [
    "今日,华为在开发者大会上发布了HarmonyOS NEXT正式版,全面支持纯血鸿蒙应用生态,不再兼容Android应用。",
    "据市场分析机构Gartner预测,到2026年全球企业级AI软件支出将突破5000亿美元,SaaS和AI Agent是主要增长点。",
    "字节跳动旗下豆包大模型团队宣布开源新一代多模态模型,支持文本、图像和视频的联合理解与生成。",
    "今天天气真不错,适合出去散步。"  # 干扰项,不属于任何科技类别
]

# 构造 messages:system 说明任务 + 示例对话
messages = [
    {
        "role": "system",
        "content": "你是科技资讯专家,请将文本分类为['AI前沿', '产品发布', '行业分析', '投融资']之一,不属于任何类别的回答'不清楚类别'。以下是示例:"
    },
]

# 把示例数据转为 user/assistant 对话对
for category, text in examples_data.items():
    messages.append({"role": "user", "content": text})
    messages.append({"role": "assistant", "content": category})

# 批量分类
for q in questions:
    response = client.chat.completions.create(
        model="qwen3:4b",
        messages=messages + [{"role": "user", "content": f"请分类:{q}"}]
    )
    print(f"文本: {q[:30]}... → 类别: {response.choices[0].message.content}")

消息构造示意图

md 复制代码
messages 最终结构:
┌─────────────────────────────────────────────────┐
│ system: 你是科技资讯专家,请分类为[...]            │
│ user:   OpenAI今日发布了GPT-5...                  │
│ assistant: AI前沿                                │
│ user:   苹果公司在WWDC上正式推出...                 │
│ assistant: 产品发布                               │
│ user:   据IDC最新报告...                          │
│ assistant: 行业分析                               │
│ user:   AI编程助手Cursor完成...                    │
│ assistant: 投融资                                 │
│ user:   请分类:今日,华为在开发者大会上...         │  ← 实际要分类的
└─────────────────────────────────────────────────┘

3.2 案例二:科技信息抽取(结构化输出)

场景:从一篇科技新闻中提取关键字段(日期、公司名、产品名、金额等),并以 JSON 格式返回。

核心思路:JSON 结构化输出 + Few-Shot 示例

直接让模型"提取信息",它可能返回自然语言描述。但如果要求它输出 JSON,并在示例中展示格式,它就能稳定返回结构化数据,方便后续程序处理。

python 复制代码
from openai import OpenAI
import json

client = OpenAI(base_url="http://localhost:11434/v1")

# 定义要抽取的字段
schema = ['日期', '公司名称', '产品名称', '融资金额', '投资方']

# 示例数据
examples_data = [
    {
        "content": "2025年3月15日,AI编程公司Cursor宣布完成1亿美元C轮融资,由红杉资本领投,Andreessen Horowitz跟投。该公司主打产品Cursor AI Editor已成为开发者热门工具。",
        "answers": {
            "日期": "2025年3月15日",
            "公司名称": "Cursor",
            "产品名称": "Cursor AI Editor",
            "融资金额": "1亿美元",
            "投资方": "红杉资本、Andreessen Horowitz"
        }
    },
    {
        "content": "昨日,华为在深圳总部正式发布Mate 70系列手机,搭载全新麒麟9100芯片,起售价5499元。",
        "answers": {
            "日期": "昨日",
            "公司名称": "华为",
            "产品名称": "Mate 70系列",
            "融资金额": "原文未提及",
            "投资方": "原文未提及"
        }
    }
]

# 待抽取的文本
questions = [
    "2025年6月1日,月之暗面科技宣布完成10亿元人民币B轮融资,高榕资本独家领投,公司将用于Kimi智能助手的产品迭代。",
    '特斯拉于上海超级工厂投产了搭载HW5.0芯片的新一代自动驾驶硬件,马斯克称这是"史上最大升级"。'
]

# 构造 messages
messages = [
    {
        "role": "system",
        "content": f"你是信息抽取专家。请从文本中提取 {schema} 这些字段,以JSON格式输出。如果某字段信息不存在,填'原文未提及'。参考以下示例:"
    },
]

# 追加示例
for example in examples_data:
    messages.append({"role": "user", "content": example["content"]})
    messages.append({
        "role": "assistant",
        "content": json.dumps(example["answers"], ensure_ascii=False)
    })

# 批量抽取
for q in questions:
    response = client.chat.completions.create(
        model="qwen3:4b",
        messages=messages + [{"role": "user", "content": f"请抽取以下文本的信息:{q}"}]
    )
    result = response.choices[0].message.content
    print(f"原文: {q[:40]}...")
    print(f"抽取结果: {result}\n")

关键技巧

  1. 明确字段列表:在 system 消息中列出要抽取的所有字段
  2. JSON 格式约束 :要求模型输出 JSON,方便后续 json.loads() 直接解析
  3. 缺失值处理:约定"原文未提及"作为默认值,避免模型编造信息
  4. 示例中展示完整格式:模型会严格模仿示例的 JSON 结构

实际使用中 ,拿到结果后建议用 json.loads() 验证一下,确保返回的是合法 JSON:

python 复制代码
parsed = json.loads(result)
print(parsed["公司名称"])  # 直接按 key 取值

3.3 案例三:科技文本匹配判断(对比推理)

场景:给定两句话,判断它们描述的是否是同一件事/同一主题。这在资讯去重、推荐系统等场景很常见。

核心思路:正负示例对比 + 格式化输入

让模型判断两句话是否"匹配",关键是要给它正面示例(匹配)负面示例(不匹配),让它学会区分。

python 复制代码
from openai import OpenAI

client = OpenAI(base_url="http://localhost:11434/v1")

# 正负示例
examples_data = {
    "是": [   # 这两句说的是同一件事
        ("英伟达发布Blackwell架构B200芯片,性能比H100提升30倍。", "英伟达推出新一代GPU B200,采用Blackwell架构,性能远超H100。"),
        ("字节跳动旗下豆包大模型团队宣布开源新一代多模态模型。", "豆包团队开源了多模态大模型。"),
    ],
    "不是": [  # 两句话各说各的
        ("英伟达股价今日下跌5%。", "苹果宣布Vision Pro二代正式发布。"),
        ("特斯拉上海工厂开始生产HW5.0芯片。", "SpaceX星舰完成第六次试飞。"),
    ]
}

# 待判断的文本对
questions = [
    ("华为发布HarmonyOS NEXT正式版,不再兼容Android。", "纯血鸿蒙系统正式发布,安卓应用将无法运行。"),
    ("AI芯片市场Q2增长65%。", "AI编程助手Cursor完成1亿美元融资。"),
    ("小米SU7交付量突破10万台。", "小米汽车市场表现强劲,累计交付超10万辆SU7。"),
]

# 构造 messages
messages = [
    {
        "role": "system",
        "content": "你帮我完成文本匹配判断。我会给你两个句子,用[]包围,请判断它们是否描述同一件事,只回答'是'或'不是'。参考以下示例:"
    },
]

# 追加正负示例
for label, pairs in examples_data.items():
    for s1, s2 in pairs:
        messages.append({"role": "user", "content": f"句子1:[{s1}],句子2:[{s2}]"})
        messages.append({"role": "assistant", "content": label})

# 批量判断
for s1, s2 in questions:
    response = client.chat.completions.create(
        model="qwen3:4b",
        messages=messages + [{"role": "user", "content": f"句子1:[{s1}],句子2:[{s2}]"}]
    )
    print(f"句子1: {s1[:35]}...")
    print(f"句子2: {s2[:35]}...")
    print(f"匹配结果: {response.choices[0].message.content}\n")

关键技巧

  1. [] 包裹句子:让模型清楚知道哪里是句子边界,避免混淆
  2. 正负示例均衡:匹配和不匹配的例子各给几个,防止模型偏向某一方
  3. 约束输出:要求"只回答'是'或'不是'",避免模型输出多余解释

4. 核心知识点总结

4.1 OpenAI SDK 调用流程

不管什么场景,调用流程都是固定的三步:

python 复制代码
# 第一步:创建 client
client = OpenAI(base_url="xxx", api_key="xxx")

# 第二步:构造 messages 并调用模型
response = client.chat.completions.create(
    model="模型名",
    messages=[...],
    stream=True/False
)

# 第三步:处理结果
# 非流式:response.choices[0].message.content
# 流式:遍历 response,每次取 chunk.choices[0].delta.content

4.2 提示词优化的三个实用技巧

技巧 适用场景 核心做法
Few-Shot 示例 分类、抽取、判断 在 messages 中塞入几个"输入→输出"的示例对
JSON 结构化 信息抽取、API 返回 要求模型输出 JSON,并在示例中展示格式
格式化输入 文本对比、多段输入 用特殊符号(如 [])标注边界,避免混淆

4.3 本地 vs 云端模型选择

本地 Ollama 云端 DashScope
base_url http://localhost:11434/v1 https://dashscope.aliyuncs.com/compatible-mode/v1
模型示例 qwen3:4b qwen3-max
优点 免费、隐私安全、离线可用 模型更强、无需本地算力
缺点 小模型能力有限 需要 API Key、按量计费

4.4 JSON 基础回顾

提示词优化案例中频繁用到 JSON 序列化/反序列化,这里简单回顾:

python 复制代码
import json

# dict → JSON 字符串
data = {"name": "张三", "age": 25}
json_str = json.dumps(data, ensure_ascii=False)
# '{"name": "张三", "age": 25}'

# JSON 字符串 → dict
parsed = json.loads(json_str)
# {'name': '张三', 'age': 25}

# list → JSON 字符串
items = [{"name": "A"}, {"name": "B"}]
json.dumps(items, ensure_ascii=False)
# '[{"name": "A"}, {"name": "B"}]'

ensure_ascii=False 很重要,否则中文会被转成 \uXXXX 编码,不方便阅读和调试。

写在最后

我们做的,并不只是"调用一个大模型 API",而是在尝试一种新的开发方式。

过去,我们习惯用代码去精确描述规则,而现在,我们开始用自然语言去"定义能力"。

这两者的区别在于:

  • 代码解决的是确定性问题
  • 大模型更擅长处理模糊、复杂、难以穷举规则的问题
相关推荐
机器之心14 小时前
WAIC现场,这家公司让一群不同的机器人共用一个大脑
人工智能·openai
新知图书15 小时前
10.1 项目背景与需求分析(智能客服智能体开发)
人工智能·agent·ai agent·智能体·扣子
赵康16 小时前
AI 写代码之后,Code Review 会议怎么开
ai·llm·skill
莫逸风16 小时前
【AgentScope 2.0】 0. 学习指南
java·llm·agent·agentscope
决战灬16 小时前
langgraph之interrupt(理论篇)
人工智能·python·agent
人间凡尔赛18 小时前
2026 AI Agent 多智能体协同编程实战指南:从 Kimi K3 到 GPT-5.6 深度解析
ai·agent·多智能体·编程实战·waic·gpt-5.6·kimik3
前端Baymax20 小时前
Memory Search索引模型不匹配故障
ai·agent·infra
谢白羽1 天前
vllm源码剖析14-vLLM 分布式推理-专家并行EP
笔记·分布式·llm·论文·vllm
wWYy.1 天前
Agent记忆压缩方法
agent