Google Gemini AI API와 JSON 형태로 원하는 구조로 통신하는데 있어 문제 발생
Google Gemini AI를 통해 질문을 내가 원하는 형태로 보내고 받는 과정에서 문제 발생
Content 기반 API 구조 - 텍스트 전용 입력
curl https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=$GOOGLE_API_KEY \
-H 'Content-Type: application/json' \
-X POST \
-d '{
"contents": [{
"parts":[{
"text": "Write a story about a magic backpack."}]}]}' 2> /dev/null
Request Body 구조
{
"contents": [
{
"parts":
{
"text": "치킨집 소개글 작성해줘"
}
}
],
"generationConfig": {
"candidate_count":1,
"max_output_tokens":1000,
"temperature": 0.7
}
}
Response Body 구조
{
"candidates": [
{
"content": {
"parts": [
{
"text": "In the quaint town of Willow Creek, nestled amidst rolling hills and whispering willows, there lived an ordinary boy named Ethan. Ethan's life took an extraordinary turn the day he stumbled upon an enigmatic backpack hidden in the depths of his attic.\n\nCuriosity ignited within Ethan as he lifted the worn leather straps and unzipped its mysterious contents. Inside lay a shimmering array of vibrant objects and peculiar trinkets. There was a glowing orb that pulsated with an ethereal glow, a feather that seemed to have a life of its own, and a small, enigmatic key.\n\nAs Ethan explored each item, he realized they possessed astonishing abilities. The orb illuminated his path, casting a warm glow in the darkest of nights. The feather granted him the power of flight, allowing him to soar through the skies with newfound freedom. And the key opened a portal to a hidden world, a realm of endless wonder.\n\nArmed with his magical backpack, Ethan embarked on countless adventures. He flew over the towering mountains of Willow Creek, exploring their hidden secrets. He navigated the treacherous depths of the Enchanted Forest, where he encountered mythical creatures and ancient spirits. And he ventured into distant, unknown lands, uncovering lost civilizations and forgotten treasures.\n\nWith each adventure, Ethan's knowledge and abilities grew. He learned to harness the power of his backpack wisely, using its magic to help others and protect the world from evil forces. The backpack became an extension of himself, a symbol of hope and wonder in the face of adversity.\n\nAs the years went by, Ethan's reputation as the boy with the magic backpack spread far and wide. People from all walks of life came to him, seeking his guidance and protection. And Ethan never hesitated to lend a helping hand, using his extraordinary abilities to make the world a better place.\n\nIn the end, the magic backpack became more than just a collection of objects. It was a representation of Ethan's unwavering spirit, his boundless imagination, and his unwavering belief in the power of dreams. And as long as Ethan carried it with him, the magic of Willow Creek would live on, illuminating the darkest corners of the world with hope, wonder, and the limitless possibilities that resided within the heart of a child."
}
],
"role": "model"
},
"finishReason": "STOP",
"index": 0,
"safetyRatings": [
{
"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
"probability": "NEGLIGIBLE"
},
{
"category": "HARM_CATEGORY_HATE_SPEECH",
"probability": "NEGLIGIBLE"
},
{
"category": "HARM_CATEGORY_HARASSMENT",
"probability": "NEGLIGIBLE"
},
{
"category": "HARM_CATEGORY_DANGEROUS_CONTENT",
"probability": "NEGLIGIBLE"
}
]
}
]
}
public GeminiRequest(String text) {
Part part = new TextPart(text);
Content content = new Content((List<Part>) part);
this.contents = Arrays.asList(content);
}
UriComponents uri = UriComponentsBuilder.newInstance()
.scheme("https")
.host("generativelanguage.googleapis.com")
.path("/v1beta/models/gemini-pro:generateContent")
.queryParam("key",GOOGLE_API_KEY)
.build();
(1) RequestDto 매핑 관련 에러
(2) Rest API 주소를 통해 Gemini API와 연동하는 URL 작성 변경
(1) RequestDto 매핑 관련 에러
public GeminiRequest(String text) {
Part part = new TextPart(text);
Content content = new Content(Collections.singletonList(part));
this.contents = Arrays.asList(content);
}
(2) Rest API 주소를 통해 Gemini API와 연동하는 URL 작성 변경
인터페이스 구성
@HttpExchange("/v1beta/models")
public interface GeminiInterface {
@PostExchange("{model}:generateContent")
GeminiResponse getCompletion(
@PathVariable String model,
@RequestBody GeminiRequest request
);
}
Config 구성
@Bean
public RestClient geminiRestClient(@Value("${gemini.baseurl}") String baseUrl,
@Value("${googleai.api.key}") String apikey) {
return RestClient.builder()
.baseUrl(baseUrl)
.defaultHeader("x-goog-api-key", apikey)
.defaultHeader("Content-Type", "application/json")
.defaultHeader("Accept", "application/json")
.build();
}
@Bean
public GeminiInterface geminiInterface(@Qualifier("geminiRestClient") RestClient restClient) {
RestClientAdapter adapter = RestClientAdapter.create(restClient);
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
return factory.createClient(GeminiInterface.class);
}
2번에서 만든 host 값 & Param 값
baseUrl : https://generativelanguage.googleapis.com
apikey : google.api.key
1번에서 만든 path 값
/v1beta/models/{model}:generateContent
2개의 URL을 합쳐 https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=$GOOGLE_API_KEY를 만들어 외부 API와 연동 가능처음으로 외부 API와 연동하면서 어떤 방식으로 구성 해야 할지 생각을 많이 해봤다.
요청하는 방식에 따라 구성하는 코드와 사용하는 라이브러리가 변경이 되고 어떤 방식으로 통신하게 되는지 조금은 알 수 있었던 것 같다.
이 외에도 다른 여러 외부 API들과 연동하면서 통신 방식에 대해 공부해 나가야겠다.