惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
GbyAI
GbyAI
Jina AI
Jina AI
博客园_首页
Y
Y Combinator Blog
美团技术团队
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
M
MIT News - Artificial intelligence
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
MyScale Blog
MyScale Blog
MongoDB | Blog
MongoDB | Blog
雷峰网
雷峰网
罗磊的独立博客
博客园 - Franky
Last Week in AI
Last Week in AI
Vercel News
Vercel News
Martin Fowler
Martin Fowler
Stack Overflow Blog
Stack Overflow Blog
Microsoft Security Blog
Microsoft Security Blog
月光博客
月光博客
WordPress大学
WordPress大学
W
WeLiveSecurity
Apple Machine Learning Research
Apple Machine Learning Research
TaoSecurity Blog
TaoSecurity Blog
阮一峰的网络日志
阮一峰的网络日志
博客园 - 聂微东
Schneier on Security
Schneier on Security
Engineering at Meta
Engineering at Meta
Simon Willison's Weblog
Simon Willison's Weblog
博客园 - 【当耐特】
宝玉的分享
宝玉的分享
大猫的无限游戏
大猫的无限游戏
S
SegmentFault 最新的问题
P
Proofpoint News Feed
C
Cyber Attacks, Cyber Crime and Cyber Security
博客园 - 叶小钗
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
L
LINUX DO - 最新话题
S
Security @ Cisco Blogs
B
Blog RSS Feed
B
Blog
爱范儿
爱范儿
D
Darknet – Hacking Tools, Hacker News & Cyber Security
T
Tailwind CSS Blog
Attack and Defense Labs
Attack and Defense Labs
V
Visual Studio Blog
NISL@THU
NISL@THU
U
Unit 42
Hugging Face - Blog
Hugging Face - Blog
A
Arctic Wolf

Vercel News

Vercel Open Source Program: Winter 2026 cohort How Notion Workers run untrusted code at scale with Vercel Sandbox How we run Vercel's CDN in front of Discourse From idea to secure checkout in minutes with Stripe Building Slack agents can be easy Scaling redirects to infinity on Vercel Advancing Python typing Gamma builds design-first agents with Vercel How Avalara turns pipe dreams into patent-pending with v0 Keeping community human while scaling with agents How OpenEvidence built a healthcare AI that physicians actually trust Security boundaries in agentic architectures Skills Night: 69,000+ ways agents are getting smarter Video Generation with AI Gateway We Ralph Wiggumed WebStreams to make them 10x faster How Stably ships AI testing agents in hours, not weeks How we built AEO tracking for coding agents Anyone can build agents, but it takes a platform to run them Introducing Geist Pixel The Vercel AI Accelerator is back with $6m in credits Making agent-friendly pages with content negotiation The Vercel OSS Bug Bounty program is now available Introducing the new v0 Run untrusted code with Vercel Sandbox, now generally available How Stripe built a game-changing app in a single flight with v0 How Sensay went from zero to product in six weeks AGENTS.md outperforms skills in our agent evals Agent skills explained: An FAQ Testing if "bash is all you need" AWS databases are now live on the Vercel Marketplace and v0 Use Perplexity Web Search with Vercel AI Gateway Introducing: React Best Practices Nick Bogaty joins Vercel as Chief Revenue Officer How Mux shipped durable video workflows with their @mux/ai SDK How to build agents with filesystems and bash How we made v0 an effective coding agent Stopping the slow death of internal tools Building AI-Generated Pixel Trading Cards with Vercel AI Gateway We removed 80% of our agent’s tools AI SDK 6 Our $1 million hacker challenge for React2Shell Cline now runs on Vercel AI Gateway How to prompt v0 Build smarter workflows with Notion and v0 Vercel launches partner certification Inside Workflow DevKit: How framework integrations work React2Shell Security Bulletin | Vercel Knowledge Base Billions of requests: Black Friday-Cyber Monday 2025 Investing in the Python ecosystem AWS Databases coming to the Vercel Marketplace How we built the v0 iOS app Workflow Builder: Build your own workflow automation platform Vercel Open Source Program: Fall 2025 cohort Self-driving infrastructure Vercel collaborates with Google for Gemini 3 Pro Preview launch Vercel: The anti-vendor-lock-in cloud How Nous Research used BotID to block automated abuse at scale How AI Gateway runs on Fluid compute What we learned building agents at Vercel Build and deploy data applications on Snowflake with v0 BotID Deep Analysis catches a sophisticated bot network in real-time Vercel achieves TISAX AL2 compliance to serve automotive partners Bun runtime on Vercel Functions David Totten Joins Vercel to Lead Global Field Engineering Vercel Ship AI 2025 recap You can just ship agents AI agents and services on the Vercel Marketplace Built-in durability: Introducing Workflow Development Kit Zero-config backends on Vercel AI Cloud Introducing Vercel Agent: Your new Vercel teammate Update regarding Vercel service disruption on October 20, 2025 Agents at work, a partnership with Salesforce and Slack Running Next.js in ChatGPT: How to Build ChatGPT Apps Talha Tariq joins Vercel as CTO of Security Just another (Black) Friday Server rendering benchmarks: Fluid Compute and Cloudflare Workers Towards the AI Cloud: Our Series F Collaborating with Anthropic on Claude Sonnet 4.5 to power intelligent coding agents Preventing the stampede: Request collapsing in the Vercel CDN BotID uncovers hidden SEO poisoning How we made global routing faster with Bloom filters What you need to know about vibe coding Scale to one: How Fluid solves cold starts Addressing security & quality issues with MCP tools - Vercel AI agents at scale: Rox’s Vercel-powered revenue operating system Agentic Infrastructure Zero Data Retention on AI Gateway Optimizing Vercel Sandbox snapshots How Waldium made a blog platform work for humans and AI alike How FLORA shipped a creative agent on Vercel's AI stack Agent responsibly Making Turborepo 96% faster with agents, sandboxes, and humans Unified reporting for all AI Gateway usage new.website joins forces with v0 SERHANT.'s playbook for rapid AI iteration Two startups at global scale without DevOps Chat SDK brings agents to your users 360 billion tokens, 3 million customers, 6 engineers Meet the 2026 Vercel AI Accelerator Cohort Build knowledge agents without embeddings
Build a GPT-3 app with Next.js and Vercel Edge Functions - Vercel – Vercel
Hassan El Mghari · 2023-02-01 · via Vercel News

6 min read

A full-stack template for building fast GPT-3 apps.

The field of artificial intelligence continues to take the world by storm. Huge strides have been made in text and image generation through tools like ChatGPT, GPT-3, DALL-E, and Stable Diffusion. It’s spawned a wave of exciting AI startups, many of which we’re seeing built with Vercel and Next.js.

One of the most exciting developments in the AI space is GPT-3, a cutting-edge natural language processing model developed by OpenAI. With its ability to understand and generate human-like text, GPT-3 has the potential to disrupt how we perform many of our tasks.

In this blog post, we’re going to break down how to build GPT-3 Apps with OpenAI, Next.js, and Vercel Edge Functions. We’ll do this by building twitterbio.com—first with serverless functions, then rebuilding it with Edge Functions and streaming to showcase the speed and UX benefits. By the end, you should be able to build your own GPT-3-powered applications.

Screenshot of the site we’re going to be building.

Screenshot of the site we’re going to be building.

Link to headingThe frontend

The Next.js frontend consists of a few elements:

  • A text box for users to copy their current bio or write a few sentences about themselves

  • A dropdown where they can select the tone of the bio they want to be generated

  • A submit button for generating their bio, which when clicked calls an API route that uses OpenAI’s GPT-3 model and returns two generated bios

  • Two containers to display the generated bios after we get them back from the API route

Here’s what the code for our index page looks like. We have a few pieces of state that correspond to the elements mentioned above. We’re also defining a prompt—like ChatGPT, we need to send a prompt to GPT-3 to instruct it to generate the new bios. Finally, we ask GPT-3 to generate two bios clearly labeled (so we can parse them correctly) using the user-provided bio and vibe as context.

const prompt = `Generate 2 ${vibe} twitter bios with no hashtags and clearly labeled "1."

and "2.". Make sure each generated bio is at least 14 words and at max 20 words and base

them on this context: ${bio}`;

The rest of our index page is comprised of the UI elements themselves: our text box, dropdown, submit button, and two containers on the bottom that we display when we get the generated bios. There's also some loading logic for the button to show a loading indicator when clicked.

GenerateBio.tsx

<textarea

value={bio}

onChange={(e) => setBio(e.target.value)}

rows={4}

className="..."

placeholder={"e.g. Senior Engineer @vercel. Tweeting about web dev & AI."}

/>

<div className="...">

<Image src="/2-black.png" width={30} height={30} alt="1 icon" />

<p className="...">Select your vibe.</p>

</div>

<div className="block">

<DropDown vibe={vibe} setVibe={(newVibe) => setVibe(newVibe)} />

</div>

<button className="..." onClick={(e) => generateBio(e)}>

Generate your bio &rarr;

</button>

<hr className="..." />

<div className="...">

{generatedBios && (

<>

<div>

<h2 className="...">Your generated bios</h2>

</div>

<div className="...">

{generatedBios

.substring(generatedBios.indexOf("1") + 3)

.split("2.")

.map((generatedBio: any) => {

return (

<div className="..." key={generatedBio}>

<p>{generatedBio}</p>

</div>

);

})}

</div>

</>

)}

</div>

In addition to the UI elements and the loading logic, we have a generateBio function that’s called when the user clicks the submit button. This sends a POST request to our /api/generate API route with the prompt in the body.

GenerateBio.tsx

const generateBio = async (e: any) => {

e.preventDefault();

setGeneratedBios("");

setLoading(true);

const response = await fetch("/api/generate", {

method: "POST",

headers: {

"Content-Type": "application/json",

},

body: JSON.stringify({

prompt,

}),

});

if (!response.ok) {

throw new Error(response.statusText);

}

let answer = await response.json();

setGeneratedBios(answer.choices[0].text);

setLoading(false);

};

We get the generated bios back from the API route, save it to the generatedBios state, then display it to the user. Because we asked GPT-3 to return the text in a specific numbered format, we can split it based on the “2.” to show the user the two bios separated nicely into containers as seen below.

Screenshot of the site showing two generated bios.

Screenshot of the site showing two generated bios.

Link to headingThe backend

A great advantage of using Next.js is being able to handle both our frontend and backend in a single application. We can spin up an API route just by creating a file called generate.ts in our api folder. Let’s take a look at our /api/generate API Route.

We get the prompt from the request body that’s passed in on the frontend, then construct a payload to send to OpenAI. In this payload, we specify some important information like the exact model (GPT-3) and how many tokens we want OpenAI to respond with (a token is approximately 4 characters). In this case, we’re limiting the max tokens because Twitter bios have a character constraint.

After the payload is constructed, we send it in a POST request to OpenAI, await the result to get back the generated bios, then send them back to the client as JSON.

generate.js

export default async function handler(req, res) {

const { prompt } = req.body;

const payload = {

model: "text-davinci-003",

prompt,

temperature: 0.7,

top_p: 1,

frequency_penalty: 0,

presence_penalty: 0,

max_tokens: 200,

n: 1,

};

const response = await fetch("https://api.openai.com/v1/completions", {

headers: {

"Content-Type": "application/json",

Authorization: `Bearer ${process.env.OPENAI_API_KEY ?? ""}`,

},

method: "POST",

body: JSON.stringify(payload),

});

const json = await response.json();

res.status(200).json(json);

}

There we have it! We built the first version of our application. Feel free to check out the code and demo for this approach.

Link to headingLimitations of the serverless function approach

While this serverless approach works, there are some limitations that make edge a better fit for this kind of application:

  1. If we’re building an app where we want to await longer responses, such as generating entire blog posts, responses will likely take over 10 seconds which can lead to serverless timeout issues on Vercel’s Hobby tier. Vercel's Pro tier has a 60-second timeout which is usually enough for GPT-3 applications.

  2. Waiting several seconds before seeing any data isn't a good user experience. Ideally, we want to incrementally show the user data as it’s being generated—similar to how ChatGPT works.

  3. The responses may take even longer due to the cold start that’s present in serverless lambda functions.

Thankfully, there is a better way to build this application that addresses all three of these problems: Vercel Edge Functions with streaming. Edge Functions may not always be the answer, especially if you're replying on specific Node.js libraries that are not edge compatible. In this case however, they will work great.

Let’s explore what Edge Functions are and how we can migrate our app to use them for faster generations and a better user experience.

Link to headingEdge Functions vs. Serverless Functions

You can think of Edge Functions as serverless functions with a more lightweight runtime. They have a smaller code size limit, smaller memory, and don’t support all Node.js libraries. So you may be thinking—why would I want to use them?

Three answers: speed, UX, and longer timeouts.

  1. Because Edge Functions use a smaller edge runtime and run very close to users on the edge, they’re also fast. They have virtually no cold starts and are significantly faster than serverless functions.

  2. They allow for a great user experience, especially when paired with streaming. Streaming a response breaks it down into small chunks and progressively sends them to the client, as opposed to waiting for the entire response before sending it.

  3. Edge Functions have a timeout of 25 seconds and even longer when streaming, which far exceeds the timeout limit for serverless functions on Vercel’s Hobby plan. Using these can allow you to get past timeout issues when using AI APIs that take longer to respond. As an added benefit, Edge Functions are also cheaper to run.

To see a demo of Serverless vs Edge Functions in action, check out the video below, specifically from 4:05 to 4:40.

Link to headingEdge Functions with streaming

Now that we understand the benefits and cost-effectiveness of using Edge Functions, let’s refactor our existing code to use them. Let’s start with our backend's API route.

The first thing we do is define a config variable and set the runtime to "edge". This is all you need to define this API route as an Edge Function. We also added an extra variable to our payload, stream: true, to make sure OpenAI streams in chunks back to the client.

Finally, the last major change to this file is to define the stream variable after specifying the payload. We used a helper function, OpenAIStream, to enable us to incrementally stream responses to the client as we get data from OpenAI.

generate.ts

import { OpenAIStream } from "../../utils/OpenAIStream";

export const config = {

runtime: "edge",

};

const handler = async (req: Request): Promise<Response> => {

const { prompt } = (await req.json()) as {

prompt?: string;

};

const payload = {

model: "text-davinci-003",

prompt,

temperature: 0.7,

top_p: 1,

frequency_penalty: 0,

presence_penalty: 0,

max_tokens: 200,

stream: true,

n: 1,

};

const stream = await OpenAIStream(payload);

return new Response(stream);

};

export default handler;

Let’s take a look at the helper function we used. It sends a POST request to OpenAI with the payload, similar to how we did it in the serverless version, but this is where the similarities stop. We create a stream to continuously parse the data we’re receiving from OpenAI, all while waiting for the [DONE] token to be sent since this signifies the end. When this happens, we close the stream.

OpenAIStream.ts

import { createParser, ParsedEvent, ReconnectInterval } from "eventsource-parser";

export async function OpenAIStream(payload) {

const encoder = new TextEncoder();

const decoder = new TextDecoder();

let counter = 0;

const res = await fetch("https://api.openai.com/v1/completions", {

headers: {

"Content-Type": "application/json",

Authorization: `Bearer ${process.env.OPENAI_API_KEY ?? ""}`,

},

method: "POST",

body: JSON.stringify(payload),

});

const stream = new ReadableStream({

async start(controller) {

function onParse(event: ParsedEvent | ReconnectInterval) {

if (event.type === "event") {

const data = event.data;

if (data === "[DONE]") {

controller.close();

return;

}

try {

const json = JSON.parse(data);

const text = json.choices[0].text;

if (counter < 2 && (text.match(/\n/) || []).length) {

return;

}

const queue = encoder.encode(text);

controller.enqueue(queue);

counter++;

} catch (e) {

controller.error(e);

}

}

}

// stream response (SSE) from OpenAI may be fragmented into multiple chunks

// this ensures we properly read chunks & invoke an event for each SSE event stream

const parser = createParser(onParse);

// https://web.dev/streams/#asynchronous-iteration

for await (const chunk of res.body as any) {

parser.feed(decoder.decode(chunk));

}

},

});

return stream;

}

In our frontend, the only code that changes is our generateBio function. Specifically, we define a reader using the native web API, getReader(), and progressively add data to our generatedBio state as it’s streamed in.

GenerateBio.tsx

const generateBio = async (e: any) => {

e.preventDefault();

setGeneratedBios("");

setLoading(true);

const response = await fetch("/api/generate", {

method: "POST",

headers: {

"Content-Type": "application/json",

},

body: JSON.stringify({

prompt,

}),

});

if (!response.ok) {

throw new Error(response.statusText);

}

const data = response.body;

if (!data) {

return;

}

const reader = data.getReader();

const decoder = new TextDecoder();

let done = false;

while (!done) {

const { value, done: doneReading } = await reader.read();

done = doneReading;

const chunkValue = decoder.decode(value);

setGeneratedBios((prev) => prev + chunkValue);

}

setLoading(false);

};

We’ve now refactored our app to use Edge Functions with streaming, making it faster and greatly improving the user experience by incrementally displaying data as it comes in.

Link to headingResources

We hope this walkthrough helps you build incredible GPT-3 powered applications. We’ve already seen several sites built with this template such as Rephraser, GenzTranslator, and ChefGPT—some of which have thousands of users. Visit the Twitter Bio site to see everything we talked about in action, check out our other AI templates, or start optimizing prompts across various models with Vercel's AI Playground.