TypeScript 类型定义

Ollama SDK 提供了完整的 TypeScript 类型定义,让开发更安全、更高效。

基本类型

Message 类型

interface Message {
  role: 'system' | 'user' | 'assistant'
  content: string
  images?: Uint8Array[]
}

ChatRequest 类型

interface ChatRequest {
  model: string
  messages: Message[]
  stream?: boolean
  format?: 'json'
  options?: ModelOptions
  system?: string
  template?: string
  keep_alive?: string
  tools?: Tool[]
}

ChatResponse 类型

interface ChatResponse {
  model: string
  created_at: string
  message: Message
  done: boolean
  total_duration?: number
  load_duration?: number
  prompt_eval_count?: number
  prompt_eval_duration?: number
  eval_count?: number
  eval_duration?: number
}

使用类型

类型安全的聊天

import ollama, { Message, ChatResponse } from 'ollama'

async function chat(messages: Message[]): Promise<string> {
  const response: ChatResponse = await ollama.chat({
    model: 'llama3.2',
    messages,
    stream: false
  })
  
  return response.message.content
}

const messages: Message[] = [
  { role: 'user', content: '你好' }
]

const reply = await chat(messages)
console.log(reply)

类型安全的流式

import ollama, { ChatResponse } from 'ollama'

async function* streamChat(
  model: string,
  messages: Message[]
): AsyncGenerator<string> {
  const stream = await ollama.chat({
    model,
    messages,
    stream: true
  })
  
  for await (const chunk of stream) {
    if (chunk.message.content) {
      yield chunk.message.content
    }
  }
}

// 使用
for await (const text of streamChat('llama3.2', [{ role: 'user', content: '写一首诗' }])) {
  process.stdout.write(text)
}

ModelOptions 类型

interface ModelOptions {
  temperature?: number
  num_ctx?: number
  num_predict?: number
  top_p?: number
  top_k?: number
  stop?: string[]
  repeat_penalty?: number
  seed?: number
  num_gpu?: number
}

使用示例:

import ollama, { ModelOptions } from 'ollama'

const options: ModelOptions = {
  temperature: 0.7,
  num_ctx: 4096,
  top_p: 0.9,
  stop: ['###']
}

const response = await ollama.chat({
  model: 'llama3.2',
  messages: [{ role: 'user', content: '写一首诗' }],
  options
})

Tool 类型

interface Tool {
  type: 'function'
  function: {
    name: string
    description: string
    parameters: {
      type: 'object'
      properties: Record<string, {
        type: string
        description?: string
        enum?: string[]
      }>
      required?: string[]
    }
  }
}

使用示例:

import ollama, { Tool } from 'ollama'

const tools: Tool[] = [
  {
    type: 'function',
    function: {
      name: 'get_weather',
      description: '获取城市天气',
      parameters: {
        type: 'object',
        properties: {
          city: {
            type: 'string',
            description: '城市名称'
          }
        },
        required: ['city']
      }
    }
  }
]

const response = await ollama.chat({
  model: 'llama3.2',
  messages: [{ role: 'user', content: '北京今天天气怎么样?' }],
  tools
})

自定义类型扩展

对话会话类

import ollama, { Message, ChatResponse, ModelOptions } from 'ollama'

class ChatSession {
  private model: string
  private messages: Message[]
  private options?: ModelOptions
  
  constructor(model: string, system?: string, options?: ModelOptions) {
    this.model = model
    this.options = options
    this.messages = system ? [{ role: 'system', content: system }] : []
  }
  
  async send(content: string): Promise<string> {
    this.messages.push({ role: 'user', content })
    
    const response: ChatResponse = await ollama.chat({
      model: this.model,
      messages: this.messages,
      options: this.options
    })
    
    const reply = response.message.content
    this.messages.push({ role: 'assistant', content: reply })
    
    return reply
  }
  
  async sendStream(content: string, callback: (text: string) => void): Promise<string> {
    this.messages.push({ role: 'user', content })
    
    const stream = await ollama.chat({
      model: this.model,
      messages: this.messages,
      options: this.options,
      stream: true
    })
    
    let fullResponse = ''
    
    for await (const chunk of stream) {
      const text = chunk.message.content
      if (text) {
        fullResponse += text
        callback(text)
      }
    }
    
    this.messages.push({ role: 'assistant', content: fullResponse })
    return fullResponse
  }
  
  getHistory(): Message[] {
    return [...this.messages]
  }
  
  clear(): void {
    const systemMessage = this.messages.find(m => m.role === 'system')
    this.messages = systemMessage ? [systemMessage] : []
  }
}

// 使用
const session = new ChatSession('llama3.2', '你是一个友好的助手', {
  temperature: 0.7
})

await session.sendStream('你好', (text) => process.stdout.write(text))

泛型响应处理

interface GenerateResult<T> {
  content: T
  raw: string
  tokens: number
  duration: number
}

async function generateJSON<T>(
  prompt: string,
  model: string = 'llama3.2'
): Promise<GenerateResult<T>> {
  const response = await ollama.generate({
    model,
    prompt,
    format: 'json'
  })
  
  return {
    content: JSON.parse(response.response) as T,
    raw: response.response,
    tokens: response.eval_count || 0,
    duration: (response.total_duration || 0) / 1e9
  }
}

// 使用
interface UserInfo {
  name: string
  age: number
  email: string
}

const result = await generateJSON<UserInfo>('生成一个用户信息')
console.log(result.content.name)

类型守卫

import { ChatResponse } from 'ollama'

function isChatResponse(value: unknown): value is ChatResponse {
  return (
    typeof value === 'object' &&
    value !== null &&
    'model' in value &&
    'message' in value &&
    'done' in value
  )
}

async function safeChat(messages: Message[]): Promise<string | null> {
  try {
    const response = await ollama.chat({
      model: 'llama3.2',
      messages
    })
    
    if (isChatResponse(response)) {
      return response.message.content
    }
    
    return null
  } catch (error) {
    console.error('Chat failed:', error)
    return null
  }
}