소개
앞서 작성한 KEY가 2개 이상이 필요한 API를 호출하여 GPTs 만들기 사례를 디벨롭하여 원하는 도시에서 원하는 기간에 운영하는 문화정보와 길 안내를 도와주는 GPTs를 만들어봤습니다.
GPTs에 API를 연동할 때 2개 이상의 API Key를 요구하는 경우 가운데에 통제가 가능한 API 서버를 둠으로서 해결하는 예제를 따라해보면서 활용하기에 따라 무긍무진한 챗봇이나 업무 어시스턴트를 만들 수 있을 것 같다고 생각했었는데, 구체적인 활용 방안은 아직 생각이 나지 않아 맛보기 정도로만 해봤습니다.
진행 방법
✔ 사용한 API
한국문화정보원 API 🏛 → 특정 날짜, 지역의 공 연·전시·행사 정보 가져오기
Naver Maps API 🗺 → 행사 장소까지의 최적 경로 안내
1) API 서버 구축
Express.js로 서버를 만들고, API 요청을 처리
Vercel에 배포하여 어디서든 사용할 수 있도록 설정
import express from 'express';
import axios from "axios";
const app = express();
// 환경변수 또는 직접 API 키를 입력하세요.
const NAVER_API_KEY_ID = process.env.NAVER_API_KEY_ID || 'your_api_key_id';
const NAVER_API_KEY_SECRET = process.env.NAVER_API_KEY_SECRET || 'your_api_key';
const DATA_SERVICE_KEY = process.env.DATA_SERVICE_KEY || 'your_api_key';
app.get('/', (req, res) => {
console.log("Express 앱에 '/' 요청이 들어왔습니다.");
res.send("Express on Vercel");
});
app.get('/directions', async (req, res) => {
console.log("Express 앱에 '/direction' 요청이 들어왔습니다.");
let {start, goal, option} = req.query;
try {
const url = 'https://naveropenapi.apigw.ntruss.com/map-direction/v1/driving';
const headers = {
'x-ncp-apigw-api-key-id': NAVER_API_KEY_ID,
'x-ncp-apigw-api-key': NAVER_API_KEY_SECRET
}
// Naver API 호출
const response = await axios.get(url, {
params: {start, goal, option},
headers: headers
});
console.log("Response status:", response.status);
console.log("Response data: ", response.data);
// API 응답 데이터를 그대로 반환합니다.
res.json(response.data);
} catch (error: any) {
console.error("Naver API 호출 중 에러 발생:", error.message);
res.status(500).json({error: 'Naver API 호출 중 문제가 발생했습니다.'});
}
});
app.get('/pfm-period', async (req, res) => {
console.log("Express 앱에 '/pfm-period' 요청이 들어왔습니다.");
let { from, to, serviceTp } = req.query;
const serviceKey = DATA_SERVICE_KEY;
try {
const url = 'https://apis.data.go.kr/B553457/nopenapi/rest/publicperformancedisplays/period';
// 공공 DATA API 호출
const response = await axios.get(url, {
params: { serviceKey, from, to, serviceTp },
});
console.log("Response status:", response.status);
console.log("Response data: ", response.data);
// API 응답 데이터를 그대로 반환합니다.
res.json(response.data);
} catch (error: any) {
console.error("공공 DATA API 호출 중 에러 발생:", error.message);
res.status(500).json({ error: '공공 DATA API 호출 중 문제가 발생했습니다.' });
}
});
// Vercel 서버리스 함수로 동작하므로 app.listen() 호출 불필요
export default app;
/pfm-period api를 get방식으로 받는 코드를 추가하여 vercel에 재배포하였습니다.
openapi: 3.1.0
info:
title: Direction & Performance API
description: API providing route directions and Performance period data retrieval.
version: 1.1.0
servers:
- url: https://naver-maps-test-delta.vercel.app
description: Vercel server
paths:
/directions:
get:
operationId: getDirection
summary: Get directions between two points
description: Returns route directions from a start location to a goal location, with an optional route type.
parameters:
- name: start
in: query
required: true
description: Starting point coordinates (longitude,latitude).
schema:
type: string
example: 127.0735,37.5505
- name: goal
in: query
required: true
description: Goal point coordinates (longitude,latitude).
schema:
type: string
example: 127.0291,37.5894
- name: option
in: query
required: false
description: Route preference (e.g., `trafast` for the fastest route).
schema:
type: string
example: trafast
responses:
"200":
description: Successful response with route directions.
content:
application/json:
schema:
type: object
properties:
route:
type: array
description: List of route steps.
items:
type: object
properties:
instruction:
type: string
description: Navigation instruction.
distance:
type: number
description: Distance in meters.
duration:
type: number
description: Estimated duration in seconds.
"400":
description: Bad request, invalid parameters.
"500":
description: Internal server error.
/pfm-period:
get:
operationId: getPfmPeriod
summary: Retrieve PFM period data
description: Fetches PFM period data for a specified date range.
parameters:
- name: from
in: query
required: true
description: Start date in `YYYYMMDD` format.
schema:
type: string
example: "20250201"
- name: to
in: query
required: true
description: End date in `YYYYMMDD` format.
schema:
type: string
example: "20250228"
- name: serviceTp
in: query
required: false
description: Service type filter.(A:공연/전시, B:행사/축제, C:교육/체험)
schema:
type: string
example: "A"
responses:
"200":
description: Successful response with PFM period data.
content:
application/json:
schema:
type: object
properties:
data:
type: array
description: List of PFM records.
items:
type: object
properties:
date:
type: string
description: Date in `YYMMDD` format.
example: "250201"
value:
type: number
description: Corresponding PFM value.
example: 123.45
"400":
description: Bad request, invalid parameters.
"500":
description: Internal server error.
기존에 ActionsGPT를 통해 작성한 naver maps api를 호출하는 schema에 한국문화정보원 api를 호출하는 schema를 추가하였습니다.
공공 데이터 API를 활용하여 사용자가 입력한 지역의 시작일자, 종료일자에 진행중인 문화 정보를 안내(Call the naver-maps-test-delta.vercel.app API with the getPfmPeriod operation)하고, 사용자가 입력한 출발지와 도착지를 기반으로 이동 거리와 예상 소요 시간을 제공(Call the naver-maps-test-delta.vercel.app API with the getDirection operation)하는 역할을 합니다. 문화 정보는 **A:공연/전시, B:행사/축제, C:교육/체험**으로 구분하여 사용자의 요청에 따라 **parameter를 A/B/C로 넘깁니다.** 자동차, 대중교통, 도보 등 다양한 이동 수단을 고려하며, 최적의 경로를 추천합니다. 지도 API를 활용하여 경로 안내 기능도 포함할 수 있습니다. 사용자가 입력한 정보가 부족할 경우 적절한 질문을 통해 보완하며, 직관적이고 명확한 정보를 제공하는 것이 목표입니다.
instruction은 만들기를 통해 수정한 후, api call을 테스트하는 명령어(?)를 붙여넣기 해주었더니 요청하는 정보에 맞는 api를 호출하는 것 같았습니다.
결과와 배운 점
Instruction을 프롬프트 엔지니어링하여 잘 작성하면 훨씬 좋은 결과를 얻을 수 있겠지만, 각기 다른 두 기관에서 제공하는 API를 한 개의 Action을 추가하는 것으로 결과를 얻을 수 있다는데에 주안점을 두고 만들어봤던 사례여서 추가로 고도화하지는 않았습니다.
간단히 활용방안을 테스트해 보았지만, 서버단에서 데이터를 가공하여 응답하는 방식 또한 여전히 가능할 것이므로 추후 아이디어가 떠오른다면 시도해보고 공유하겠습니다.
(대략적인 컨셉은 api 호출을 중계하는 함수를 하나 만들고, api를 호출하는 코드 안에서 함수를 호출하여 GPTs에서 한 번의 질문으로 한 번에 여러 api를 호출한 뒤, 데이터를 적절히 가공하여 응답하는 방식이면 되지 않을까 막연하게 생각해봤습니다.)
https://chatgpt.com/g/g-67adc14bf2cc8191a514f8aae2f963f6-gongyeonjang-gyeongro-annae-doumi