Next.js AI SDK 生成 UI 与 Together AI 和 Mixtral 8x7B 不支持函数调用

问题描述 投票:0回答:1

我正在尝试让人工智能根据用户输入生成 UI 组件,例如 vercel 在他们最新的聊天示例中所做的事情这里。 Mixtral 支持函数调用,但似乎无法与 vercel AI SDK 中的

render
函数一起工作:
import { render } from "ai/rsc";

在下面的代码中,我尝试按照文档中的方式进行操作,并遵循 AI 聊天示例中的实际存储库。

import "server-only";

import { Message } from "@/components/message";
import { getMutableAIState, render, createAI } from "ai/rsc";
import OpenAI from "openai";
import { PiSpinnerGap } from "react-icons/pi";
import { z } from "zod";
import { sleep } from "@/lib/utils";

const togetherai = new OpenAI({
  apiKey: process.env.TOGETHER_AI_API_KEY,
  baseURL: "https://api.together.xyz/v1",
});

//export const runtime = "edge";

async function getWeather() {
  return {weather: "30º"}
}

async function submitUserMessage(input: string) {
  "use server";
  const aiState = getMutableAIState();

  // Update AI state with new message.
  aiState.update([
    ...aiState.get(),
    {
      role: "user",
      content: input,
    },
  ]);

  const ui = render({
    provider: togetherai,
    model: "mistralai/Mixtral-8x7B-Instruct-v0.1",
    messages: [
      {
        role: "system",
        content: `You are a helpful assistant that can access external functions when the user asks for. Your name is MistralAI.
          If the user asks for the weather and passes the location, call \`get_weather_info\` to show current weather at that location.`,
      },
      {
        role: "user",
        content: input,
      },
    ],
    text: ({ content, done }) => {
      if (done) {
        aiState.done([
          ...aiState.get(),
          {
            role: "assistant",
            content,
          },
        ]);
      }

      return (
        <div className="flex w-full">
          <Message from="ai">{content}</Message>
        </div>
      );
    },
    initial: (
      <div>
        <PiSpinnerGap className="animate-spin text-muted" size={25} />
      </div>
    ),
    functions: {
      getWeatherInfo: {
        description:
          "Get the information for the weather according to a certain location.",
        parameters: z
          .object({
            location: z
              .string()
              .describe("The location to get the weather from."),
          })
          .required(),
        render: async function* ({ location }) {
          yield (
            <div>
              <PiSpinnerGap className="animate-spin text-muted" size={25} />
            </div>
          );

          //can call from other func to get information from an external api
          const weatherInfo = await getWeather();
          
          await sleep(1000);

          aiState.done([
            ...aiState.get(),
            {
              role: "function",
              name: "getWeatherInfo",
              content: JSON.stringify(weatherInfo),
            },
          ]);

          return (
            <div className="bg-red-500">
              <h1>
                The weather in <span className="font-bold">{location}</span>
              </h1>
              <div>is {weatherInfo.weather}</div>
            </div>
          );
        },
      },
    },
  });

  return {
    id: Date.now(),
    display: ui,
  };
}

// Define the initial state of the AI. It can be any JSON object.
const initialAIState: {
  role: "user" | "assistant" | "system" | "function";
  content: string;
  id?: string;
  name?: string;
}[] = [];

// The initial UI state that the client will keep track of, which contains the message IDs and their UI nodes.
const initialUIState: {
  id: number;
  display: React.ReactNode;
}[] = [];

export const AI = createAI({
  actions: {
    submitUserMessage,
  },
  initialAIState,
  initialUIState,
});

但它给了我以下错误:

Console Error Message

只有当 AI 实际尝试调用该函数时才会出现问题:

Client chat interaction

这是客户端

import { AI } from "../action";
import { GenerativeUIChat } from "./fragments/generative-ui-chat";

export default function GenerativeUIPage() {
  return (
    <AI>
      <GenerativeUIChat />
    </AI>
  );
}

这是

GenerativeUIChat
组件:

"use client";

import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { cn } from "@/lib/utils";
import { PiPaperPlaneTilt, PiRobotThin } from "react-icons/pi";
import { useUIState, useAIState, useActions } from "ai/rsc";
import { useState } from "react";
import { AI } from "@/app/action";
import { Message } from "@/components/message";

export function GenerativeUIChat() {
  const [messages, setMessages] = useUIState<typeof AI>();
  const { submitUserMessage } = useActions<typeof AI>();
  // const [aiState, setAIState] = useAIState<typeof AI>();
  const [input, setInput] = useState<string>('');

  async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();

    // Add user message to UI state
    setMessages((curr) => [
      ...curr,
      {
        id: Date.now(),
        display: (
          <div className="flex w-full justify-end">
            <Message from="user">{input}</Message>
          </div>
        ),
      },
    ]);

    // Submit and get response message
    const responseMessage = await submitUserMessage(input);
    setMessages((currentMessages) => [...currentMessages, responseMessage]);

    setInput('');
  }

  return (
    <div className="flex flex-col w-full max-w-xl px-4 h-[calc(100vh-4rem)] justify-between items-center mx-auto">
      <div className="flex flex-col w-full max-w-xl max-h-[calc(100%-4.5rem)] pt-6">
        <span className="w-full text-center text-sm text-muted">Mistral</span>
        {messages.length === 0 ? (
          <div className="flex flex-col gap-8 w-full items-center">
            <span className="text-2xl font-semibold text-center">
              Start a conversation with the AI.
            </span>
            <PiRobotThin size={100} />
          </div>
        ) : (
          <div
            className={cn(
              "[&::-webkit-scrollbar]:w-[0.35rem] [&::-webkit-scrollbar-track]:bg-accent [&::-webkit-scrollbar-thumb]:bg-primary [&::-webkit-scrollbar-thumb]:rounded-lg [&::-webkit-scrollbar-thumb:hover]:bg-primary/50",
              "p-2 px-6 pr-3 flex flex-col gap-4 border border-input rounded-lg mb-2 overflow-auto shadow-sm shadow-black/30 transition duration-300 hover:shadow-lg"
            )}
          >
            {
              // View messages in UI state
              messages.map((message) => message.display)
            }
          </div>
        )}
      </div>
      <form className="w-full" onSubmit={handleSubmit}>
        <div className="flex gap-2 w-full py-4">
          <Input
            className="p-2 border border-input rounded shadow-sm bg-background"
            value={input}
            placeholder="Say something..."
            onChange={(event) => {
              setInput(event.target.value);
            }}
          />
          <Button size="icon">
            <PiPaperPlaneTilt size={20} />
          </Button>
        </div>
      </form>
    </div>
  );
}

欢迎任何解决方案或建议😁。

node.js next.js artificial-intelligence vercel
1个回答
0
投票

我已经解决了这个问题,如果有人遇到这个问题,你可以查看我的存储库这里并查看有关

Generative UI
的文档。

我遇到的主要问题是流媒体,现在已禁用并且工作正常,您也可以像我一样使用 Vercel 的 Google Gemini Chatbot 作为信息来源。

© www.soinside.com 2019 - 2024. All rights reserved.