基于ollama的deepseek基础入门代码示例

基于ollama的deepseek基础入门代码示例

Ollama 是一个开源的 AI 代理框架,用于与各种语言模型进行交互。
DeepSeek 是一个基于 Ollama 的模型或服务。
在 Ollama 的 API 中,
http://localhost:11434/api/chathttp://localhost:11434/api/generate是两个不同的接口,
它们的主要区别如下:

1.功能用途

http://localhost:11434/api/chat

• 用途:主要用于对话式交互。它通常用于实现聊天机器人或类似的应用场景,能够处理自然语言输入,并以自然语言的形式返回回复。

• 特点:通常会维护对话状态(context),能够根据上下文生成连贯的对话内容。例如,用户可以与模型进行多轮对话,模型会记住之前的对话内容,从而生成更符合语境的回复。

• 应用场景:适合聊天机器人、客服系统、智能助手等需要与用户进行交互的场景。

http://localhost:11434/api/generate

• 用途:主要用于文本生成任务。它接收一个输入提示(prompt),并根据提示生成文本内容。

• 特点:不维护对话状态,每次请求都是独立的。它更侧重于生成高质量的文本,而不是对话的连贯性。生成的文本可以是文章、故事、代码片段等。

• 应用场景:适合写作辅助、内容生成、代码生成等场景。

2.输入和输出

http://localhost:11434/api/chat

• 输入:通常是一个用户的自然语言输入,可能包含上下文信息(如之前的对话历史)。

• 输出:返回一个自然语言的回复,通常是对话式的回答。

http://localhost:11434/api/generate

• 输入:是一个提示(prompt),可以是一个句子、段落或更复杂的文本结构。

• 输出:返回生成的文本内容,内容的长度和格式根据提示和模型的配置而定。

3.内部处理逻辑

http://localhost:11434/api/chat

• 内部会处理对话的上下文信息,可能使用特定的对话管理机制来维护对话状态。

• 生成的回复会考虑对话的连贯性和语境。

http://localhost:11434/api/generate

• 主要基于输入的提示进行文本生成,不考虑对话状态。

• 更注重生成文本的质量和相关性。

4.配置和参数

http://localhost:11434/api/chat

• 可能支持对话相关的参数,如对话历史长度、上下文窗口大小等。

• 参数配置更倾向于优化对话的流畅性和连贯性。

http://localhost:11434/api/generate

• 支持文本生成相关的参数,如生成长度、温度(temperature)、Top-K、Top-P 等。

• 参数配置更侧重于控制生成文本的质量和多样性。

总结

• 如果你需要实现一个聊天机器人或需要与模型进行多轮对话,建议使用 http://localhost:11434/api/chat

• 如果你需要生成文本内容(如文章、故事、代码等),建议使用http://localhost:11434/api/generate

chat对话式交互

# 通过 requests 向 ollama 发生http请求,ollama 调用本地 deepseek 进行推理 并将推理结果返回
# pip install requests

# 导入 requests 模块,用于发送 HTTP 请求
import requests

# 使用 requests.post 方法向 Ollama 的本地服务发送 POST 请求
response = requests.post(
  url="http://localhost:11434/api/chat",  # 指定请求的 URL,Ollama 服务运行在本地的 11434 端口
  json={  # 请求体的内容,以 JSON 格式发送
    "model": "deepseek-r1:1.5b",  # 指定要使用的模型名称和版本
    "messages": [  # 包含用户的消息
      {"role": "user", "content": "帮我写首关于夏天的诗"}  # 用户发送的消息,角色为 "user",内容为 "帮我写首关于夏天的诗"
    ],
    "stream": False  # 设置是否以流式响应返回结果,这里设置为 False,表示一次性返回完整结果
  }
)

# 检查 HTTP 请求的返回状态码
if response.status_code != 200:  # 如果状态码不是 200(表示请求成功)
  print("请求失败,请重试!")  # 输出错误提示
else:
  print(response.json())  # 如果请求成功,打印返回的 JSON 数据


# 定义一个函数,用于提取思考过程和推理结果
def extract_thinking_and_response(data):
  """
  提取思考过程和推理结果。

  参数:
      data (dict): Ollama 返回的 JSON 数据。

  返回:
      tuple: 包含思考过程和推理结果的元组。
  """
  # 初始化思考过程和推理结果变量
  thinking_process = ""
  response_content = ""

  # 检查返回数据中是否包含消息内容
  if "message" in data and "content" in data["message"]:
    # 提取消息内容
    content = data["message"]["content"]

    # 检查是否包含思考过程
    if "<think>" in content and "</think>" in content:
      # 提取思考过程,去除标签
      start = content.find("<think>") + len("<think>")  # 找到 "<think>" 标签的起始位置
      end = content.find("</think>")  # 找到 "</think>" 标签的结束位置
      thinking_process = content[start:end].strip()  # 提取标签内的内容并去除首尾空格

    # 提取推理结果(即消息的其余部分)
    response_content = content.split("</think>")[-1].strip()  # 从 "</think>" 标签之后的内容中提取推理结果

  # 返回思考过程和推理结果
  return thinking_process, response_content


thinking_process, response_content = extract_thinking_and_response(response.json())

print("\n=== 模型思考过程 ===")
print(thinking_process)
print("\n=== 模型推理结果 ===")
print(response_content)

generate 文本生成任务

# 通过 requests 向 ollama 发生http请求,ollama 调用本地 deepseek 进行推理 并将推理结果返回
# pip install requests

# 导入 requests 模块,用于发送 HTTP 请求
import requests

# 使用 requests.post 方法向 Ollama 的本地服务发送 POST 请求
response = requests.post(
  url="http://localhost:11434/api/generate",  # 指定请求的 URL,Ollama 服务运行在本地的 11434 端口
  json={  # 请求体的内容,以 JSON 格式发送
    "model": "deepseek-r1:1.5b",  # 指定要使用的模型名称和版本
    "prompt": "写一首关于夏天的诗",  # 提示文本,用于引导模型生成内容
    "stream": False  # 设置是否以流式响应返回结果,这里设置为 False,表示一次性返回完整结果
  }
)

# 检查 HTTP 请求的返回状态码
if response.status_code != 200:  # 如果状态码不是 200(表示请求成功)
  print("请求失败,请重试!")  # 输出错误提示
else:
  print(response.json())  # 如果请求成功,打印返回的 JSON 数据


# 以下是一个函数,用于提取代码中的思考过程和推理结果,并整合完整的上下文。同时,我会逐行注释代码,解释每一行的作用。
def extract_thinking_and_response(data):
  """
  提取思考过程和推理结果。

  参数:
      data (dict): Ollama 返回的 JSON 数据。

  返回:
      tuple: 包含思考过程和推理结果的元组。
  """
  # 初始化思考过程和推理结果变量
  thinking_process = ""
  response_content = ""

  # 检查返回数据中是否包含响应内容
  if "response" in data:
    # 提取响应内容
    response = data["response"]

    # 检查是否包含思考过程
    if "<think>" in response and "</think>" in response:
      # 提取思考过程,去除标签
      start = response.find("<think>") + len("<think>")
      end = response.find("</think>")
      thinking_process = response[start:end].strip()

    # 提取推理结果(即响应的其余部分)
    response_content = response.split("</think>")[-1].strip()

  # 返回思考过程和推理结果
  return thinking_process, response_content


thinking_process, response_content = extract_thinking_and_response(response.json())
print("\n=== 模型思考过程 ===")
print(thinking_process)
print("\n=== 模型推理结果 ===")
print(response_content)

提取模型思考过程和推理结果工具函数

ai_utils.py

import re  # 用于正则表达式处理文本


def extract_think_and_response(response_data):
  """从API响应中分别提取<think>思考部分和最终回答部分"""
  try:
    # 从响应数据中提取模型返回的原始内容
    content = response_data["message"]["content"]

    # 使用正则表达式提取<think>标签内的思考内容
    think_match = re.search(r'<think>(.*?)</think>', content, re.DOTALL)
    think_content = think_match.group(1).strip() if think_match else ""

    # 移除<think>标签及其内容,得到最终回答部分
    response_content = re.sub(r'<think>.*?</think>', '', content, flags=re.DOTALL).strip()

    return {
      "think_content": think_content,  # 思考过程内容
      "response_content": response_content  # 最终回答内容
    }
  except Exception as e:
    print(f"内容提取错误: {e}")
    return {"think_content": "", "response_content": ""}


# 定义一个函数,用于提取思考过程和推理结果
def extract_thinking_and_response_chat(data):
  """
  提取思考过程和推理结果,并整合完整上下文。

  参数:
      data (dict): Ollama 返回的 JSON 数据。

  返回:
      tuple: 包含思考过程和推理结果的元组。
  """
  # 初始化思考过程和推理结果变量
  thinking_process = ""
  response_content = ""

  # 检查返回数据中是否包含消息内容
  if "message" in data and "content" in data["message"]:
    # 提取消息内容
    content = data["message"]["content"]

    # 检查是否包含思考过程
    if "<think>" in content and "</think>" in content:
      # 提取思考过程,去除标签
      start = content.find("<think>") + len("<think>")  # 找到 "<think>" 标签的起始位置
      end = content.find("</think>")  # 找到 "</think>" 标签的结束位置
      thinking_process = content[start:end].strip()  # 提取标签内的内容并去除首尾空格

    # 提取推理结果(即消息的其余部分)
    response_content = content.split("</think>")[-1].strip()  # 从 "</think>" 标签之后的内容中提取推理结果

  # 返回思考过程和推理结果
  return thinking_process, response_content


# 以下是一个函数,用于提取代码中的思考过程和推理结果,并整合完整的上下文。同时,我会逐行注释代码,解释每一行的作用。
def extract_thinking_and_response_prompt(data):
  """
  提取思考过程和推理结果。

  参数:
      data (dict): Ollama 返回的 JSON 数据。

  返回:
      tuple: 包含思考过程和推理结果的元组。
  """
  # 初始化思考过程和推理结果变量
  thinking_process = ""
  response_content = ""

  # 检查返回数据中是否包含响应内容
  if "response" in data:
    # 提取响应内容
    response = data["response"]

    # 检查是否包含思考过程
    if "<think>" in response and "</think>" in response:
      # 提取思考过程,去除标签
      start = response.find("<think>") + len("<think>")
      end = response.find("</think>")
      thinking_process = response[start:end].strip()

    # 提取推理结果(即响应的其余部分)
    response_content = response.split("</think>")[-1].strip()

  # 返回思考过程和推理结果
  return thinking_process, response_content


def extract_ai_history(response_data):
  """从DeepSeek API响应中提取并格式化AI发展历程的内容"""
  try:
    # 从响应数据中提取模型返回的原始内容
    content = response_data["message"]["content"]

    # 使用正则表达式移除<think>标签及其包含的所有内容(非贪婪模式)
    cleaned_content = re.sub(r'<think>.*?</think>', '', content, flags=re.DOTALL).strip()

    # 使用正则表达式按###标题分割内容为多个章节
    sections = re.split(r'###\s*', cleaned_content)

    # 提取主体内容(第一个部分)
    main_content = sections[0].strip()
    chapters = []  # 用于存储各章节内容的列表

    # 处理每个章节(从第二个部分开始)
    for section in sections[1:]:
      if not section.strip():  # 跳过空部分
        continue
      # 分割章节标题和内容(按第一个换行符分割)
      lines = section.split('\n', 1)
      if len(lines) == 2:  # 确保有标题和内容
        title, content = lines
        chapters.append({  # 将章节信息添加到列表
          "title": title.strip(),  # 章节标题
          "content": content.strip()  # 章节内容
        })

    # 返回结构化的提取结果
    return {
      "main_content": main_content,  # 主体内容
      "chapters": chapters  # 章节列表
    }
  except Exception as e:
    print(f"提取内容时出错: {e}")  # 处理异常
    return None


def format_ai_history(extracted_data):
  """将提取的内容格式化为易读的文本"""
  if not extracted_data:  # 检查提取数据是否有效
    return "未能提取有效内容"

  # 初始化格式化文本,先添加主体内容
  formatted = extracted_data["main_content"] + "\n\n"

  # 遍历每个章节,按序号和标题格式添加
  for i, chapter in enumerate(extracted_data["chapters"], 1):
    formatted += f"### {chapter['title']}\n{chapter['content']}\n\n"

  return formatted  # 返回格式化后的完整文本


def extract_ai_result(response_data):
  """从DeepSeek API响应中提取并格式化AI发展历程的内容"""
  try:
    # 从响应数据中提取模型返回的原始内容
    content = response_data["message"]["content"]

    # 提取模型思考过程
    think_match = re.search(r'<think>(.*?)</think>', content, flags=re.DOTALL)
    thought_process = think_match.group(1).strip() if think_match else "未找到模型思考过程"

    # 移除思考过程标签,保留实际回答内容
    cleaned_content = re.sub(r'<think>.*?</think>', '', content, flags=re.DOTALL).strip()

    # 使用正则表达式按###标题分割内容为多个章节
    sections = re.split(r'###\s*', cleaned_content)

    # 提取主体内容(第一个部分)
    main_content = sections[0].strip()
    chapters = []  # 用于存储各章节内容的列表

    # 处理每个章节(从第二个部分开始)
    for section in sections[1:]:
      if not section.strip():  # 跳过空部分
        continue
      # 分割章节标题和内容(按第一个换行符分割)
      lines = section.split('\n', 1)
      if len(lines) == 2:  # 确保有标题和内容
        title, content = lines
        chapters.append({  # 将章节信息添加到列表
          "title": title.strip(),  # 章节标题
          "content": content.strip()  # 章节内容
        })

    # 返回结构化的提取结果,拆分为两个独立参数
    return {
      "thought_process": thought_process  # 模型思考过程
    }, {
      "main_content": main_content,  # 主体内容
      "chapters": chapters  # 章节列表
    }
  except Exception as e:
    print(f"提取内容时出错: {e}")  # 处理异常
    return None, None


def format_thought_process(thought_data):
  """将模型思考过程格式化为易读的文本"""
  if not thought_data:
    return "未找到模型思考过程"

  return f"=== 模型思考过程 ===\n{thought_data['thought_process']}\n\n"


def format_inference_result(result_data):
  """将推理结果格式化为易读的文本"""
  if not result_data:
    return "未能提取有效内容"

  # 初始化格式化文本,先添加主体内容
  formatted = "=== 主体内容 ===\n"
  formatted += result_data["main_content"] + "\n\n"

  # 遍历每个章节,按序号和标题格式添加
  formatted += "=== 详细章节 ===\n"
  for i, chapter in enumerate(result_data["chapters"], 1):
    formatted += f"### {chapter['title']}\n{chapter['content']}\n\n"

  return formatted


def save_to_file(content, filename="ai_history.md"):
  """将内容保存到文件"""
  try:
    # 以写入模式打开文件(自动创建或覆盖)
    with open(filename, 'w', encoding='utf-8') as file:
      file.write(content)  # 写入内容
    print(f"内容已保存到 {filename}")  # 提示保存成功
  except Exception as e:
    print(f"保存文件时出错: {e}")  # 处理保存异常

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李昊哲小课

桃李不言下自成蹊

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值