Skip to content

LLM API 交互

概述

与 LLM API 交互是构建 Agent 的第一步。本文以 Gemini API 为例,讲解如何初始化客户端、发送请求、处理响应。

初始化客户端

typescript
import { GoogleGenerativeAI } from '@google/generative-ai'

// 1. 创建客户端
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY)

// 2. 获取模型
const model = genAI.getGenerativeModel({
  model: 'gemini-2.5-flash',  // 或 'gemini-2.5-pro'
})

// 3. 开始对话
const chat = model.startChat()

发送消息

简单对话

typescript
const result = await chat.sendMessage('你好,请介绍一下你自己')
console.log(result.response.text())

带工具的对话

Agent 需要告诉 LLM 有哪些工具可用:

typescript
const model = genAI.getGenerativeModel({
  model: 'gemini-2.5-flash',
  tools: [{
    functionDeclarations: [
      {
        name: 'read_file',
        description: '读取文件内容',
        parameters: {
          type: 'object',
          properties: {
            path: { type: 'string', description: '文件路径' }
          },
          required: ['path']
        }
      }
    ]
  }]
})

处理响应

LLM 的响应可能是:

  1. 普通文本
  2. 工具调用请求
typescript
const result = await chat.sendMessage(userMessage)
const response = result.response

// 检查是否有工具调用
const functionCalls = response.functionCalls()

if (functionCalls && functionCalls.length > 0) {
  // LLM 想调用工具
  for (const call of functionCalls) {
    console.log('工具名:', call.name)
    console.log('参数:', call.args)
  }
} else {
  // 普通文本响应
  console.log('回复:', response.text())
}

返回工具结果

执行工具后,需要把结果告诉 LLM:

typescript
// 1. LLM 请求调用工具
const result1 = await chat.sendMessage('读取 package.json')
const functionCall = result1.response.functionCalls()[0]

// 2. 执行工具
const fileContent = await fs.readFile(functionCall.args.path, 'utf-8')

// 3. 返回结果给 LLM
const result2 = await chat.sendMessage([{
  functionResponse: {
    name: functionCall.name,
    response: { content: fileContent }
  }
}])

// 4. LLM 基于结果生成回复
console.log(result2.response.text())

gemini-cli 中的实现

gemini-cli 的 API 交互封装在 GeminiChat 类中。

源码位置packages/core/src/core/geminiChat.ts

关键代码简化版:

typescript
// packages/core/src/core/geminiChat.ts
export class GeminiChat {
  private chat: Chat

  constructor(model: GenerativeModel) {
    this.chat = model.startChat()
  }

  async send(contents: Content[]): Promise<GenerateContentResponse> {
    const result = await this.chat.sendMessage(contents)
    return result.response
  }
}

gemini-cli 还做了额外封装:

  • 流式响应处理
  • 错误重试
  • Token 计数
  • 事件发射

完整示例

typescript
import { GoogleGenerativeAI } from '@google/generative-ai'

async function main() {
  const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY!)

  const model = genAI.getGenerativeModel({
    model: 'gemini-2.5-flash',
    tools: [{
      functionDeclarations: [{
        name: 'get_time',
        description: '获取当前时间',
        parameters: { type: 'object', properties: {} }
      }]
    }]
  })

  const chat = model.startChat()

  // 第一轮:用户提问
  const result1 = await chat.sendMessage('现在几点了?')
  const functionCall = result1.response.functionCalls()?.[0]

  if (functionCall) {
    console.log('LLM 想调用:', functionCall.name)

    // 第二轮:返回工具结果
    const result2 = await chat.sendMessage([{
      functionResponse: {
        name: 'get_time',
        response: { time: new Date().toLocaleTimeString() }
      }
    }])

    console.log('最终回复:', result2.response.text())
  }
}

main()

小结

  • 使用 @google/generative-ai SDK 与 Gemini API 交互
  • 通过 tools 参数告诉 LLM 有哪些工具
  • 响应可能是文本或工具调用
  • 工具执行后需要把结果发回给 LLM

下一步

了解了基本的 API 交互,接下来学习如何构建 Prompt 和处理流式响应:Prompt 与流式响应 →

通过实际源码学习 AI Agent 开发