引言

在当今人工智能快速发展的时代,大语言模型(LLM)已经成为开发者和研究人员不可或缺的工具。然而,许多用户面临两个主要挑战:一是云API服务的成本和隐私问题,二是本地部署的复杂性。Ollama 正是为解决这些问题而生的开源工具,它让在本地运行大型语言模型变得简单高效。

本文将为您提供一份全面的 Ollama API 使用指南,从基础概念到高级技巧,帮助您快速掌握本地大模型接口调用。无论您是开发者、研究人员还是AI爱好者,都能通过本文学会如何利用 Ollama 在本地环境中高效调用大模型。

1. Ollama 简介

1.1 什么是 Ollama?

Ollama 是一个开源项目,旨在简化在本地运行大型语言模型的过程。它提供了一个简单的命令行界面和 REST API,让用户能够轻松地在自己的计算机上运行各种开源模型,如 Llama 2、Mistral、CodeLlama 等。

1.2 Ollama 的核心优势

  1. 本地运行:所有计算都在本地完成,无需依赖云端服务,保护数据隐私
  2. 简单易用:通过简单的命令即可安装和运行模型
  3. 模型丰富:支持多种开源大模型,包括最新的 Llama 3、Mistral 等
  4. API 友好:提供标准的 REST API,便于集成到各种应用中
  5. 跨平台支持:支持 macOS、Linux 和 Windows

1.3 适用场景

  • 隐私敏感应用:处理敏感数据时,避免数据上传到云端
  • 离线环境:在网络不稳定或无法联网的环境中使用
  • 成本控制:避免云API的持续费用,一次性投入硬件成本
  • 开发测试:快速原型开发和模型测试
  • 教育研究:学习和研究大语言模型的工作原理

2. 安装与配置

2.1 系统要求

在安装 Ollama 之前,请确保您的系统满足以下要求:

  • 操作系统:macOS 10.15+、Linux(各种发行版)、Windows 1011
  • 内存:至少 8GB RAM(推荐 16GB+)
  • 存储空间:至少 20GB 可用空间(取决于模型大小)
  • CPU:现代多核处理器(推荐 Intel i5 或 AMD Ryzen 5 及以上)
  • GPU(可选但推荐):NVIDIA GPU(支持 CUDA)可显著提升性能

2.2 安装步骤

macOS 安装

# 使用 Homebrew 安装
brew install ollama

# 或者直接下载安装包
curl -fsSL https://ollama.ai/install.sh | sh

Linux 安装

# 一键安装脚本
curl -fsSL https://ollama.ai/install.sh | sh

# 或者手动安装
# 下载二进制文件
curl -L https://ollama.ai/download/ollama-linux-amd64 -o /usr/local/bin/ollama
chmod +x /usr/local/bin/ollama

Windows 安装

  1. 访问 Ollama 官网
  2. 下载 Windows 安装程序
  3. 运行安装程序并按照提示完成安装

2.3 验证安装

安装完成后,打开终端并运行以下命令验证安装:

ollama --version

如果看到版本号输出,说明安装成功。

2.4 启动 Ollama 服务

Ollama 默认在后台运行。您可以通过以下命令检查服务状态:

# 查看 Ollama 进程
ps aux | grep ollama

# 或者使用系统命令
systemctl status ollama  # Linux systemd
brew services list       # macOS Homebrew

如果服务未运行,可以手动启动:

ollama serve

3. 模型管理

3.1 模型仓库

Ollama 维护了一个模型仓库,包含各种开源模型。您可以通过以下命令查看可用模型:

ollama list

3.2 下载模型

基本命令

# 下载 Llama 2 7B 模型
ollama pull llama2

# 下载特定版本
ollama pull llama2:7b
ollama pull llama2:13b
ollama pull llama2:70b

# 下载其他模型
ollama pull mistral
ollama pull codellama
ollama pull phi

模型大小参考

模型名称 参数量 磁盘空间 推荐内存
phi 2.7B ~1.6GB 4GB
llama2 7B ~3.8GB 8GB
llama2 13B ~7.3GB 16GB
llama2 70B ~39GB 64GB
mistral 7B ~4.1GB 8GB

3.3 查看已安装模型

ollama list

输出示例:

NAME            ID              SIZE    MODIFIED
llama2:latest   78e26419b446    3.8GB   2 hours ago
mistral:latest  61e88e884507    4.1GB   1 day ago

3.4 删除模型

# 删除特定模型
ollama rm llama2

# 删除所有模型(谨慎使用)
ollama rm *

3.5 自定义模型

Ollama 支持通过 Modelfile 创建自定义模型。创建一个名为 Modelfile 的文件:

# 使用 Llama 2 作为基础模型
FROM llama2

# 设置系统提示词
SYSTEM """你是一个专业的助手,总是以中文回答问题。"""

# 设置参数
PARAMETER temperature 0.7
PARAMETER top_p 0.9
PARAMETER max_tokens 2048

然后创建模型:

ollama create my-custom-model -f Modelfile

4. Ollama API 基础

4.1 API 端点

Ollama 提供以下主要 API 端点:

  • POST /api/generate - 生成文本
  • POST /api/chat - 聊天对话
  • GET /api/tags - 获取可用模型列表
  • GET /api/version - 获取 Ollama 版本
  • POST /api/pull - 下载模型
  • POST /api/create - 创建模型
  • POST /api/delete - 删除模型
  • POST /api/embeddings - 生成嵌入向量

4.2 基本请求格式

所有 API 请求都使用 JSON 格式,通过 HTTP POST 方法发送。

生成文本请求示例

{
  "model": "llama2",
  "prompt": "为什么天空是蓝色的?",
  "stream": false,
  "options": {
    "temperature": 0.7,
    "top_p": 0.9,
    "max_tokens": 1024
  }
}

聊天请求示例

{
  "model": "llama2",
  "messages": [
    {
      "role": "user",
      "content": "你好,今天天气怎么样?"
    }
  ],
  "stream": false
}

4.3 响应格式

生成文本响应

{
  "model": "llama2",
  "created_at": "2024-01-01T12:00:00Z",
  "response": "天空呈现蓝色是因为大气中的气体分子对太阳光的散射作用...",
  "done": true,
  "context": [1, 2, 3, 4, 5],
  "total_duration": 123456789,
  "load_duration": 12345678,
  "prompt_eval_count": 10,
  "prompt_eval_duration": 1234567,
  "eval_count": 150,
  "eval_duration": 123456789
}

聊天响应

{
  "model": "llama2",
  "created_at": "2024-01-01T12:00:00Z",
  "message": {
    "role": "assistant",
    "content": "今天天气晴朗,温度适宜,适合户外活动。"
  },
  "done": true,
  "total_duration": 123456789,
  "load_duration": 12345678,
  "prompt_eval_count": 10,
  "prompt_eval_duration": 1234567,
  "eval_count": 150,
  "eval_duration": 123456789
}

5. 使用 cURL 调用 API

5.1 基础调用

生成文本

curl -X POST http://localhost:11434/api/generate \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama2",
    "prompt": "解释量子计算的基本原理",
    "stream": false
  }'

聊天对话

curl -X POST http://localhost:11434/api/chat \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama2",
    "messages": [
      {
        "role": "user",
        "content": "你好,请介绍一下自己"
      }
    ],
    "stream": false
  }'

5.2 流式响应

流式响应可以实时获取生成的内容:

curl -X POST http://localhost:11434/api/generate \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama2",
    "prompt": "写一首关于春天的诗",
    "stream": true
  }'

流式响应会返回多个 JSON 对象,每个对象包含部分生成的内容。

5.3 高级参数

curl -X POST http://localhost:11434/api/generate \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama2",
    "prompt": "用Python写一个快速排序算法",
    "stream": false,
    "options": {
      "temperature": 0.7,
      "top_p": 0.9,
      "top_k": 40,
      "num_predict": 512,
      "num_ctx": 2048,
      "repeat_penalty": 1.1,
      "seed": 42
    }
  }'

6. 使用 Python 调用 API

6.1 安装依赖

pip install requests

6.2 基础调用示例

import requests
import json

def generate_text(prompt, model="llama2", stream=False):
    """生成文本"""
    url = "http://localhost:11434/api/generate"
    
    payload = {
        "model": model,
        "prompt": prompt,
        "stream": stream
    }
    
    response = requests.post(url, json=payload)
    
    if response.status_code == 200:
        result = response.json()
        return result.get("response", "")
    else:
        print(f"Error: {response.status_code}")
        return None

# 使用示例
if __name__ == "__main__":
    prompt = "解释什么是机器学习"
    response = generate_text(prompt)
    print(response)

6.3 聊天对话示例

import requests

def chat_with_model(messages, model="llama2", stream=False):
    """与模型进行对话"""
    url = "http://localhost:11434/api/chat"
    
    payload = {
        "model": model,
        "messages": messages,
        "stream": stream
    }
    
    response = requests.post(url, json=payload)
    
    if response.status_code == 200:
        result = response.json()
        return result.get("message", {}).get("content", "")
    else:
        print(f"Error: {response.status_code}")
        return None

# 使用示例
if __name__ == "__main__":
    messages = [
        {"role": "user", "content": "你好,我需要帮助学习Python"},
        {"role": "assistant", "content": "很高兴帮助你学习Python!你想从哪个方面开始?"},
        {"role": "user", "content": "请解释一下列表推导式"}
    ]
    
    response = chat_with_model(messages)
    print(response)

6.4 流式响应处理

import requests
import json

def generate_text_stream(prompt, model="llama2"):
    """生成文本(流式)"""
    url = "http://localhost:11434/api/generate"
    
    payload = {
        "model": model,
        "prompt": prompt,
        "stream": True
    }
    
    response = requests.post(url, json=payload, stream=True)
    
    if response.status_code == 200:
        full_response = ""
        for line in response.iter_lines():
            if line:
                try:
                    data = json.loads(line.decode('utf-8'))
                    if "response" in data:
                        print(data["response"], end="", flush=True)
                        full_response += data["response"]
                except json.JSONDecodeError:
                    continue
        print()  # 换行
        return full_response
    else:
        print(f"Error: {response.status_code}")
        return None

# 使用示例
if __name__ == "__main__":
    prompt = "写一个Python函数计算斐波那契数列"
    response = generate_text_stream(prompt)

6.5 高级参数配置

import requests

def generate_with_options(prompt, model="llama2"):
    """使用高级参数生成文本"""
    url = "http://localhost:11434/api/generate"
    
    payload = {
        "model": model,
        "prompt": prompt,
        "stream": False,
        "options": {
            "temperature": 0.7,      # 温度参数,控制随机性
            "top_p": 0.9,            # 核采样概率
            "top_k": 40,             # 顶部k个token
            "num_predict": 512,      # 最大生成token数
            "num_ctx": 2048,         # 上下文窗口大小
            "repeat_penalty": 1.1,   # 重复惩罚
            "seed": 42               # 随机种子
        }
    }
    
    response = requests.post(url, json=payload)
    
    if response.status_code == 200:
        result = response.json()
        return result.get("response", "")
    else:
        print(f"Error: {response.status_code}")
        return None

# 使用示例
if __name__ == "__main__":
    prompt = "用Python实现一个简单的神经网络"
    response = generate_with_options(prompt)
    print(response)

6.6 错误处理与重试机制

import requests
import time
from typing import Optional

def generate_with_retry(prompt: str, model: str = "llama2", 
                       max_retries: int = 3, 
                       retry_delay: float = 1.0) -> Optional[str]:
    """
    带重试机制的文本生成
    
    Args:
        prompt: 输入提示
        model: 模型名称
        max_retries: 最大重试次数
        retry_delay: 重试延迟(秒)
    
    Returns:
        生成的文本或None(失败时)
    """
    url = "http://localhost:11434/api/generate"
    
    for attempt in range(max_retries):
        try:
            payload = {
                "model": model,
                "prompt": prompt,
                "stream": False
            }
            
            response = requests.post(url, json=payload, timeout=30)
            
            if response.status_code == 200:
                result = response.json()
                return result.get("response", "")
            elif response.status_code == 404:
                print(f"模型 {model} 未找到,请先下载模型")
                return None
            else:
                print(f"请求失败,状态码: {response.status_code}")
                
        except requests.exceptions.Timeout:
            print(f"请求超时,尝试 {attempt + 1}/{max_retries}")
        except requests.exceptions.ConnectionError:
            print(f"连接错误,尝试 {attempt + 1}/{max_retries}")
        except Exception as e:
            print(f"未知错误: {e},尝试 {attempt + 1}/{max_retries}")
        
        if attempt < max_retries - 1:
            time.sleep(retry_delay)
    
    print("所有重试均失败")
    return None

# 使用示例
if __name__ == "__main__":
    prompt = "解释什么是深度学习"
    response = generate_with_retry(prompt)
    if response:
        print(response)

7. 使用 JavaScript/Node.js 调用 API

7.1 安装依赖

npm install axios

7.2 基础调用示例

const axios = require('axios');

async function generateText(prompt, model = 'llama2', stream = false) {
    const url = 'http://localhost:11434/api/generate';
    
    const payload = {
        model: model,
        prompt: prompt,
        stream: stream
    };
    
    try {
        const response = await axios.post(url, payload);
        
        if (response.status === 200) {
            return response.data.response || '';
        } else {
            console.error(`Error: ${response.status}`);
            return null;
        }
    } catch (error) {
        console.error('Error:', error.message);
        return null;
    }
}

// 使用示例
async function main() {
    const prompt = '解释什么是人工智能';
    const response = await generateText(prompt);
    console.log(response);
}

main();

7.3 聊天对话示例

const axios = require('axios');

async function chatWithModel(messages, model = 'llama2', stream = false) {
    const url = 'http://localhost:11434/api/chat';
    
    const payload = {
        model: model,
        messages: messages,
        stream: stream
    };
    
    try {
        const response = await axios.post(url, payload);
        
        if (response.status === 200) {
            return response.data.message.content || '';
        } else {
            console.error(`Error: ${response.status}`);
            return null;
        }
    } catch (error) {
        console.error('Error:', error.message);
        return null;
    }
}

// 使用示例
async function main() {
    const messages = [
        { role: 'user', content: '你好,我想学习JavaScript' },
        { role: 'assistant', content: '很高兴帮助你学习JavaScript!你想了解什么?' },
        { role: 'user', content: '请解释async/await的工作原理' }
    ];
    
    const response = await chatWithModel(messages);
    console.log(response);
}

main();

7.4 流式响应处理

const axios = require('axios');

async function generateTextStream(prompt, model = 'llama2') {
    const url = 'http://localhost:11434/api/generate';
    
    const payload = {
        model: model,
        prompt: prompt,
        stream: true
    };
    
    try {
        const response = await axios.post(url, payload, {
            responseType: 'stream',
            headers: {
                'Accept': 'text/event-stream',
                'Cache-Control': 'no-cache',
                'Connection': 'keep-alive'
            }
        });
        
        let fullResponse = '';
        
        response.data.on('data', (chunk) => {
            const lines = chunk.toString().split('\n');
            lines.forEach(line => {
                if (line.trim()) {
                    try {
                        const data = JSON.parse(line);
                        if (data.response) {
                            process.stdout.write(data.response);
                            fullResponse += data.response;
                        }
                    } catch (e) {
                        // 忽略解析错误
                    }
                }
            });
        });
        
        response.data.on('end', () => {
            console.log('\n');
            return fullResponse;
        });
        
        response.data.on('error', (error) => {
            console.error('Stream error:', error);
        });
        
    } catch (error) {
        console.error('Error:', error.message);
        return null;
    }
}

// 使用示例
async function main() {
    const prompt = '写一个简单的Node.js HTTP服务器';
    await generateTextStream(prompt);
}

main();

8. 高级功能与技巧

8.1 嵌入向量生成

Ollama 支持生成文本的嵌入向量,这对于语义搜索、聚类等任务非常有用。

import requests
import numpy as np

def generate_embeddings(texts, model="nomic-embed-text"):
    """生成文本嵌入向量"""
    url = "http://localhost:11434/api/embeddings"
    
    payload = {
        "model": model,
        "input": texts if isinstance(texts, list) else [texts]
    }
    
    response = requests.post(url, json=payload)
    
    if response.status_code == 200:
        result = response.json()
        embeddings = result.get("embedding", [])
        return np.array(embeddings)
    else:
        print(f"Error: {response.status_code}")
        return None

# 使用示例
if __name__ == "__main__":
    # 首先下载嵌入模型
    # ollama pull nomic-embed-text
    
    texts = [
        "机器学习是人工智能的一个分支",
        "深度学习使用神经网络",
        "Python是一种编程语言"
    ]
    
    embeddings = generate_embeddings(texts)
    print(f"生成的嵌入向量形状: {embeddings.shape}")
    print(f"第一个嵌入向量的前5个值: {embeddings[0][:5]}")

8.2 模型性能监控

import requests
import time
from datetime import datetime

def monitor_model_performance(model="llama2", prompt="你好", iterations=10):
    """监控模型性能"""
    url = "http://localhost:11434/api/generate"
    
    results = []
    
    for i in range(iterations):
        payload = {
            "model": model,
            "prompt": prompt,
            "stream": False
        }
        
        start_time = time.time()
        response = requests.post(url, json=payload)
        end_time = time.time()
        
        if response.status_code == 200:
            result = response.json()
            latency = end_time - start_time
            
            results.append({
                "iteration": i + 1,
                "latency": latency,
                "tokens_generated": result.get("eval_count", 0),
                "tokens_per_second": result.get("eval_count", 0) / latency if latency > 0 else 0,
                "total_duration": result.get("total_duration", 0) / 1e9,  # 纳秒转秒
                "prompt_eval_duration": result.get("prompt_eval_duration", 0) / 1e9,
                "eval_duration": result.get("eval_duration", 0) / 1e9
            })
            
            print(f"迭代 {i+1}: 延迟 {latency:.2f}s, 生成 {result.get('eval_count', 0)} tokens")
    
    # 计算统计信息
    if results:
        avg_latency = sum(r["latency"] for r in results) / len(results)
        avg_tokens_per_second = sum(r["tokens_per_second"] for r in results) / len(results)
        
        print(f"\n性能统计({iterations}次迭代):")
        print(f"平均延迟: {avg_latency:.2f}s")
        print(f"平均吞吐量: {avg_tokens_per_second:.2f} tokens/s")
        
        return results
    
    return None

# 使用示例
if __name__ == "__main__":
    monitor_model_performance(model="llama2", prompt="解释什么是机器学习", iterations=5)

8.3 批量处理

import requests
import json
from concurrent.futures import ThreadPoolExecutor, as_completed
from typing import List, Dict

def batch_generate(prompts: List[str], model: str = "llama2", max_workers: int = 3) -> List[Dict]:
    """
    批量生成文本(并发处理)
    
    Args:
        prompts: 提示词列表
        model: 模型名称
        max_workers: 最大并发数
    
    Returns:
        结果列表,每个元素包含提示词和生成的文本
    """
    url = "http://localhost:11434/api/generate"
    
    def generate_single(prompt: str) -> Dict:
        """单个生成任务"""
        payload = {
            "model": model,
            "prompt": prompt,
            "stream": False
        }
        
        try:
            response = requests.post(url, json=payload, timeout=60)
            
            if response.status_code == 200:
                result = response.json()
                return {
                    "prompt": prompt,
                    "response": result.get("response", ""),
                    "success": True
                }
            else:
                return {
                    "prompt": prompt,
                    "response": "",
                    "success": False,
                    "error": f"HTTP {response.status_code}"
                }
                
        except Exception as e:
            return {
                "prompt": prompt,
                "response": "",
                "success": False,
                "error": str(e)
            }
    
    results = []
    
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        # 提交所有任务
        future_to_prompt = {
            executor.submit(generate_single, prompt): prompt 
            for prompt in prompts
        }
        
        # 收集结果
        for future in as_completed(future_to_prompt):
            try:
                result = future.result()
                results.append(result)
                print(f"完成: {result['prompt'][:50]}...")
            except Exception as e:
                print(f"任务异常: {e}")
    
    return results

# 使用示例
if __name__ == "__main__":
    prompts = [
        "解释什么是机器学习",
        "Python中如何处理异常",
        "什么是REST API",
        "如何优化数据库查询",
        "介绍深度学习的基本概念"
    ]
    
    results = batch_generate(prompts, model="llama2", max_workers=2)
    
    # 保存结果
    with open("batch_results.json", "w", encoding="utf-8") as f:
        json.dump(results, f, ensure_ascii=False, indent=2)
    
    print(f"\n批量处理完成,共处理 {len(results)} 个提示词")

8.4 与 LangChain 集成

from langchain.llms import Ollama
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain

# 初始化 Ollama LLM
llm = Ollama(model="llama2")

# 创建提示模板
prompt_template = PromptTemplate(
    input_variables=["topic"],
    template="请详细解释 {topic} 的基本原理和应用场景。"
)

# 创建链
chain = LLMChain(llm=llm, prompt=prompt_template)

# 执行
result = chain.run(topic="量子计算")
print(result)

8.5 与 Hugging Face Transformers 集成

from transformers import AutoTokenizer, AutoModelForCausalLM
import torch

# 注意:这里展示的是如何在本地使用Transformers,而不是直接调用Ollama API
# 如果您想在本地运行模型而不使用Ollama,可以使用以下方法

def load_local_model(model_name="meta-llama/Llama-2-7b-hf"):
    """加载本地模型(需要先下载)"""
    tokenizer = AutoTokenizer.from_pretrained(model_name)
    model = AutoModelForCausalLM.from_pretrained(
        model_name,
        torch_dtype=torch.float16,
        device_map="auto"
    )
    return tokenizer, model

def generate_with_transformers(tokenizer, model, prompt, max_length=200):
    """使用Transformers生成文本"""
    inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
    
    with torch.no_grad():
        outputs = model.generate(
            **inputs,
            max_length=max_length,
            do_sample=True,
            temperature=0.7,
            top_p=0.9
        )
    
    return tokenizer.decode(outputs[0], skip_special_tokens=True)

# 使用示例
if __name__ == "__main__":
    # 注意:需要先安装transformers和torch
    # pip install transformers torch
    # 并下载模型权重
    
    # tokenizer, model = load_local_model()
    # response = generate_with_transformers(tokenizer, model, "解释什么是机器学习")
    # print(response)
    
    print("注意:此示例需要先下载模型权重,实际使用时请取消注释")

9. 实际应用案例

9.1 构建本地聊天机器人

import requests
import json
from datetime import datetime

class LocalChatBot:
    """本地聊天机器人"""
    
    def __init__(self, model="llama2", system_prompt=None):
        self.model = model
        self.system_prompt = system_prompt or "你是一个友好的助手,总是以中文回答问题。"
        self.conversation_history = []
        
    def add_system_prompt(self):
        """添加系统提示"""
        if self.system_prompt:
            self.conversation_history.append({
                "role": "system",
                "content": self.system_prompt
            })
    
    def chat(self, user_input, stream=False):
        """进行对话"""
        # 添加用户输入
        self.conversation_history.append({
            "role": "user",
            "content": user_input
        })
        
        # 调用API
        url = "http://localhost:11434/api/chat"
        payload = {
            "model": self.model,
            "messages": self.conversation_history,
            "stream": stream
        }
        
        try:
            response = requests.post(url, json=payload)
            
            if response.status_code == 200:
                result = response.json()
                assistant_response = result.get("message", {}).get("content", "")
                
                # 添加助手回复到历史
                self.conversation_history.append({
                    "role": "assistant",
                    "content": assistant_response
                })
                
                return assistant_response
            else:
                return f"错误: HTTP {response.status_code}"
                
        except Exception as e:
            return f"错误: {str(e)}"
    
    def save_conversation(self, filename=None):
        """保存对话历史"""
        if not filename:
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            filename = f"conversation_{timestamp}.json"
        
        with open(filename, "w", encoding="utf-8") as f:
            json.dump(self.conversation_history, f, ensure_ascii=False, indent=2)
        
        return filename
    
    def load_conversation(self, filename):
        """加载对话历史"""
        try:
            with open(filename, "r", encoding="utf-8") as f:
                self.conversation_history = json.load(f)
            return True
        except Exception as e:
            print(f"加载失败: {e}")
            return False

# 使用示例
if __name__ == "__main__":
    bot = LocalChatBot(model="llama2")
    
    print("本地聊天机器人已启动!输入 'quit' 退出")
    print("=" * 50)
    
    while True:
        user_input = input("你: ").strip()
        
        if user_input.lower() == 'quit':
            # 保存对话
            filename = bot.save_conversation()
            print(f"对话已保存到 {filename}")
            break
        
        if user_input.lower() == 'save':
            filename = bot.save_conversation()
            print(f"对话已保存到 {filename}")
            continue
        
        if user_input.lower() == 'load':
            filename = input("请输入文件名: ").strip()
            if bot.load_conversation(filename):
                print(f"已加载对话历史: {filename}")
            continue
        
        response = bot.chat(user_input)
        print(f"助手: {response}")
        print("-" * 30)

9.2 代码生成与调试助手

import requests
import re
import ast

class CodeAssistant:
    """代码生成与调试助手"""
    
    def __init__(self, model="codellama"):
        self.model = model
    
    def generate_code(self, prompt, language="python"):
        """生成代码"""
        full_prompt = f"请用{language}编写代码实现以下功能:{prompt}"
        
        url = "http://localhost:11434/api/generate"
        payload = {
            "model": self.model,
            "prompt": full_prompt,
            "stream": False
        }
        
        response = requests.post(url, json=payload)
        
        if response.status_code == 200:
            result = response.json()
            code = result.get("response", "")
            
            # 提取代码块
            code_blocks = re.findall(r'```(?:python|py|code)?\n(.*?)```', code, re.DOTALL)
            if code_blocks:
                return code_blocks[0]
            else:
                return code
        else:
            return None
    
    def debug_code(self, code, error_message):
        """调试代码"""
        prompt = f"""我有一段Python代码,运行时出现错误:
        
代码:
```python
{code}

错误信息: {error_message}

请分析错误原因并提供修复后的代码。”“”

    url = "http://localhost:11434/api/generate"
    payload = {
        "model": self.model,
        "prompt": prompt,
        "stream": False
    }

    response = requests.post(url, json=payload)

    if response.status_code == 200:
        result = response.json()
        return result.get("response", "")
    else:
        return None

def explain_code(self, code):
    """解释代码"""
    prompt = f"""请详细解释以下Python代码的功能和工作原理:
{code}
```"""
        
        url = "http://localhost:11434/api/generate"
        payload = {
            "model": self.model,
            "prompt": prompt,
            "stream": False
        }
        
        response = requests.post(url, json=payload)
        
        if response.status_code == 200:
            result = response.json()
            return result.get("response", "")
        else:
            return None

# 使用示例
if __name__ == "__main__":
    assistant = CodeAssistant(model="codellama")
    
    # 生成代码
    print("=== 代码生成 ===")
    code = assistant.generate_code("计算斐波那契数列的前10项")
    if code:
        print("生成的代码:")
        print(code)
        
        # 尝试执行代码
        try:
            exec(code)
        except Exception as e:
            print(f"\n执行错误: {e}")
            
            # 调试代码
            print("\n=== 代码调试 ===")
            debug_result = assistant.debug_code(code, str(e))
            if debug_result:
                print(debug_result)
    
    print("\n" + "="*50 + "\n")
    
    # 解释代码
    print("=== 代码解释 ===")
    test_code = """
def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quick_sort(left) + middle + quick_sort(right)
"""
    
    explanation = assistant.explain_code(test_code)
    if explanation:
        print(explanation)

9.3 文档处理与摘要生成

import requests
import json
from typing import List

class DocumentProcessor:
    """文档处理与摘要生成"""
    
    def __init__(self, model="llama2"):
        self.model = model
    
    def summarize_document(self, document: str, max_length: int = 500) -> str:
        """生成文档摘要"""
        prompt = f"""请为以下文档生成一个简洁的摘要,摘要长度不超过{max_length}个字:

文档内容:
{document}"""
        
        url = "http://localhost:11434/api/generate"
        payload = {
            "model": self.model,
            "prompt": prompt,
            "stream": False,
            "options": {
                "max_tokens": max_length * 2  # 估算token数
            }
        }
        
        response = requests.post(url, json=payload)
        
        if response.status_code == 200:
            result = response.json()
            return result.get("response", "")
        else:
            return None
    
    def extract_key_points(self, document: str) -> List[str]:
        """提取关键点"""
        prompt = f"""请从以下文档中提取关键点,每个关键点用一句话概括:

文档内容:
{document}

请按以下格式返回:
1. 关键点1
2. 关键点2
..."""
        
        url = "http://localhost:11434/api/generate"
        payload = {
            "model": self.model,
            "prompt": prompt,
            "stream": False
        }
        
        response = requests.post(url, json=payload)
        
        if response.status_code == 200:
            result = response.json()
            response_text = result.get("response", "")
            
            # 解析关键点
            key_points = []
            for line in response_text.split('\n'):
                if line.strip() and re.match(r'^\d+\.', line.strip()):
                    key_points.append(line.strip())
            
            return key_points
        else:
            return []
    
    def translate_document(self, document: str, target_language: str = "English") -> str:
        """翻译文档"""
        prompt = f"""请将以下文档翻译成{target_language}:

文档内容:
{document}"""
        
        url = "http://localhost:11434/api/generate"
        payload = {
            "model": self.model,
            "prompt": prompt,
            "stream": False
        }
        
        response = requests.post(url, json=payload)
        
        if response.status_code == 200:
            result = response.json()
            return result.get("response", "")
        else:
            return None

# 使用示例
if __name__ == "__main__":
    processor = DocumentProcessor(model="llama2")
    
    # 示例文档
    document = """
    机器学习是人工智能的一个重要分支,它使计算机能够从数据中学习并做出预测或决策,而无需明确编程。
    机器学习算法可以分为监督学习、无监督学习和强化学习三大类。
    监督学习使用标记数据训练模型,常见的应用包括分类和回归。
    无监督学习处理未标记数据,用于聚类和降维。
    强化学习通过与环境交互来学习最优策略。
    近年来,深度学习作为机器学习的一个子领域取得了巨大成功,特别是在图像识别、自然语言处理等领域。
    """
    
    print("=== 文档摘要 ===")
    summary = processor.summarize_document(document, max_length=200)
    print(summary)
    
    print("\n=== 关键点提取 ===")
    key_points = processor.extract_key_points(document)
    for i, point in enumerate(key_points, 1):
        print(f"{i}. {point}")
    
    print("\n=== 文档翻译 ===")
    translation = processor.translate_document(document, "English")
    print(translation)

10. 性能优化与最佳实践

10.1 硬件配置建议

组件 最低配置 推荐配置 高性能配置
CPU 4核 8核 16核+
内存 8GB 16GB 32GB+
GPU NVIDIA RTX 3060 (12GB) NVIDIA RTX 4090 (24GB)
存储 20GB SSD 50GB NVMe SSD 100GB+ NVMe SSD

10.2 模型选择策略

def select_model_by_task(task_type: str, available_memory: int) -> str:
    """
    根据任务类型和可用内存选择模型
    
    Args:
        task_type: 任务类型 ('general', 'coding', 'math', 'multilingual')
        available_memory: 可用内存(GB)
    
    Returns:
        推荐的模型名称
    """
    model_recommendations = {
        'general': {
            'low': 'phi',      # 2.7B
            'medium': 'llama2:7b',  # 7B
            'high': 'llama2:13b'    # 13B
        },
        'coding': {
            'low': 'codellama:7b',
            'medium': 'codellama:13b',
            'high': 'codellama:34b'
        },
        'math': {
            'low': 'phi',
            'medium': 'llama2:7b',
            'high': 'llama2:13b'
        },
        'multilingual': {
            'low': 'mistral:7b',
            'medium': 'llama2:13b',
            'high': 'llama2:70b'
        }
    }
    
    if available_memory < 8:
        memory_level = 'low'
    elif available_memory < 16:
        memory_level = 'medium'
    else:
        memory_level = 'high'
    
    return model_recommendations.get(task_type, {}).get(memory_level, 'llama2')

# 使用示例
if __name__ == "__main__":
    # 假设系统有12GB可用内存
    available_memory = 12
    
    # 编程任务
    coding_model = select_model_by_task('coding', available_memory)
    print(f"编程任务推荐模型: {coding_model}")
    
    # 通用任务
    general_model = select_model_by_task('general', available_memory)
    print(f"通用任务推荐模型: {general_model}")

10.3 参数调优指南

def optimize_parameters(task_type: str, model_size: str) -> dict:
    """
    根据任务类型和模型大小优化参数
    
    Args:
        task_type: 任务类型
        model_size: 模型大小 ('7b', '13b', '70b')
    
    Returns:
        优化后的参数字典
    """
    base_params = {
        'temperature': 0.7,
        'top_p': 0.9,
        'top_k': 40,
        'num_predict': 512,
        'repeat_penalty': 1.1
    }
    
    # 根据任务类型调整
    if task_type == 'creative':
        base_params['temperature'] = 0.9
        base_params['top_p'] = 0.95
    elif task_type == 'precise':
        base_params['temperature'] = 0.1
        base_params['top_p'] = 0.9
    elif task_type == 'code':
        base_params['temperature'] = 0.2
        base_params['top_p'] = 0.95
        base_params['repeat_penalty'] = 1.2
    
    # 根据模型大小调整
    if model_size == '7b':
        base_params['num_ctx'] = 2048
    elif model_size == '13b':
        base_params['num_ctx'] = 4096
    elif model_size == '70b':
        base_params['num_ctx'] = 8192
    
    return base_params

# 使用示例
if __name__ == "__main__":
    # 创意写作
    creative_params = optimize_parameters('creative', '7b')
    print("创意写作参数:", creative_params)
    
    # 代码生成
    code_params = optimize_parameters('code', '13b')
    print("代码生成参数:", code_params)
    
    # 精确问答
    precise_params = optimize_parameters('precise', '7b')
    print("精确问答参数:", precise_params)

10.4 内存管理技巧

import psutil
import os

class MemoryManager:
    """内存管理器"""
    
    @staticmethod
    def get_available_memory_gb():
        """获取可用内存(GB)"""
        return psutil.virtual_memory().available / (1024**3)
    
    @staticmethod
    def get_model_memory_estimate(model_name: str) -> float:
        """估算模型所需内存(GB)"""
        model_sizes = {
            'phi': 1.6,
            'llama2:7b': 3.8,
            'llama2:13b': 7.3,
            'llama2:70b': 39.0,
            'mistral:7b': 4.1,
            'codellama:7b': 3.8,
            'codellama:13b': 7.3,
            'codellama:34b': 19.5
        }
        return model_sizes.get(model_name, 4.0)
    
    @staticmethod
    def check_memory_sufficiency(model_name: str, safety_margin: float = 2.0) -> bool:
        """检查内存是否足够"""
        available = MemoryManager.get_available_memory_gb()
        required = MemoryManager.get_model_memory_estimate(model_name)
        
        # 安全边际:模型大小 + 运行时开销
        required_with_margin = required * safety_margin
        
        return available >= required_with_margin
    
    @staticmethod
    def suggest_model_for_memory(available_memory_gb: float) -> str:
        """根据可用内存推荐模型"""
        if available_memory_gb < 4:
            return 'phi'
        elif available_memory_gb < 8:
            return 'llama2:7b'
        elif available_memory_gb < 16:
            return 'llama2:13b'
        elif available_memory_gb < 32:
            return 'mistral:7b'
        else:
            return 'llama2:70b'

# 使用示例
if __name__ == "__main__":
    manager = MemoryManager()
    
    available = manager.get_available_memory_gb()
    print(f"当前可用内存: {available:.2f} GB")
    
    # 检查模型内存需求
    models_to_check = ['llama2:7b', 'llama2:13b', 'llama2:70b']
    for model in models_to_check:
        required = manager.get_model_memory_estimate(model)
        sufficient = manager.check_memory_sufficiency(model)
        print(f"{model}: 需要 {required:.2f} GB, 足够: {sufficient}")
    
    # 推荐模型
    recommended = manager.suggest_model_for_memory(available)
    print(f"推荐模型: {recommended}")

11. 常见问题与解决方案

11.1 安装与启动问题

问题1:Ollama 服务无法启动

# 检查端口占用
netstat -tulpn | grep 11434

# 如果端口被占用,可以修改端口
OLLAMA_HOST=0.0.0.0:11435 ollama serve

# 或者在环境变量中设置
export OLLAMA_HOST=0.0.0.0:11435

问题2:模型下载失败

# 检查网络连接
ping ollama.ai

# 使用代理下载
export HTTP_PROXY=http://your-proxy:port
export HTTPS_PROXY=http://your-proxy:port
ollama pull llama2

# 或者手动下载模型文件
# 访问 https://ollama.ai/library 查看模型文件

11.2 API 调用问题

问题1:连接被拒绝

import requests
import time

def check_ollama_service():
    """检查Ollama服务是否运行"""
    try:
        response = requests.get("http://localhost:11434/api/version", timeout=5)
        if response.status_code == 200:
            print("Ollama服务运行正常")
            return True
    except:
        print("Ollama服务未运行,请启动服务")
        return False

# 使用示例
if __name__ == "__main__":
    if not check_ollama_service():
        print("请先启动Ollama服务: ollama serve")

问题2:模型未找到

def check_model_exists(model_name: str) -> bool:
    """检查模型是否已安装"""
    try:
        response = requests.get("http://localhost:11434/api/tags")
        if response.status_code == 200:
            models = response.json().get("models", [])
            model_names = [m["name"] for m in models]
            return model_name in model_names
    except:
        pass
    return False

# 使用示例
if __name__ == "__main__":
    model_name = "llama2"
    if not check_model_exists(model_name):
        print(f"模型 {model_name} 未安装,请先下载: ollama pull {model_name}")

11.3 性能问题

问题1:生成速度慢

def optimize_generation_speed():
    """优化生成速度的建议"""
    suggestions = [
        "1. 使用更小的模型(如phi代替llama2:7b)",
        "2. 减少num_ctx参数(上下文窗口大小)",
        "3. 降低temperature和top_p参数",
        "4. 使用GPU加速(如果可用)",
        "5. 关闭其他占用资源的程序",
        "6. 增加系统内存",
        "7. 使用量化模型(如果支持)"
    ]
    
    print("优化生成速度的建议:")
    for suggestion in suggestions:
        print(suggestion)

# 使用示例
if __name__ == "__main__":
    optimize_generation_speed()

问题2:内存不足

def handle_memory_error(model_name: str):
    """处理内存不足错误"""
    print(f"模型 {model_name} 运行时内存不足")
    
    # 建议更小的模型
    smaller_models = {
        'llama2:70b': 'llama2:13b',
        'llama2:13b': 'llama2:7b',
        'llama2:7b': 'phi',
        'mistral:7b': 'phi',
        'codellama:34b': 'codellama:13b',
        'codellama:13b': 'codellama:7b'
    }
    
    if model_name in smaller_models:
        print(f"建议使用更小的模型: {smaller_models[model_name]}")
    
    print("\n其他解决方案:")
    print("1. 增加系统内存")
    print("2. 使用GPU加速")
    print("3. 关闭其他占用内存的程序")
    print("4. 使用量化模型")

# 使用示例
if __name__ == "__main__":
    handle_memory_error("llama2:70b")

12. 高级主题

12.1 自定义模型创建

”`dockerfile

Modelfile 示例:创建一个专业的Python助手

FROM llama2

设置系统提示词

SYSTEM “”“你是一个专业的Python编程助手。你精通Python语法、最佳实践、设计模式和各种库的使用。 请总是提供清晰、可运行的代码示例,并解释关键概念。”“”

设置参数

PARAMETER temperature 0.2 PARAMETER top_p 0.95 PARAMETER max_tokens 1024 PARAMETER repeat_penalty 1.1

添加示例对话(可选)

TEMPLATE “”“{{ if .System }}system

{{ .System }}