Description Comment
import { ILlmApplication, ILlmFunction } from "@samchon/openapi";
import typia, { tags } from "typia";
const app: ILlmApplication<"chatgpt"> = typia.llm.application<
BbsArticleController,
"chatgpt"
>();
const func: ILlmFunction<"chatgpt"> | undefined = app.functions.find(
func => func.name === "create"
);
console.log(func?.description);
interface BbsArticleController {
/**
* Create a new article.
*
* Writes a new article and archives it into the DB.
*
* @param props Properties of create function
* @returns Newly created article
*/
create(props: {
/**
* Information of the article to create
*/
input: IBbsArticle.ICreate;
}): Promise<IBbsArticle>;
/**
* Update an article.
*
* Updates an article with new content.
*
* @param props Properties of update function
* @param input New content to update
*/
update(props: {
/**
* Target article's {@link IBbsArticle.id}.
*/
id: string & tags.Format<"uuid">;
/**
* New content to update.
*/
input: IBbsArticle.IUpdate;
}): Promise<void>;
/**
* Erase an article.
*
* Erases an article from the DB.
*
* @param props Properties of erase function
*/
erase(props: {
/**
* Target article's {@link IBbsArticle.id}.
*/
id: string & tags.Format<"uuid">;
}): Promise<void>;
}
/**
* Article entity.
*
* `IBbsArticle` is an entity representing an article in the BBS (Bulletin Board System).
*/
interface IBbsArticle extends IBbsArticle.ICreate {
/**
* Primary Key.
*/
id: string & tags.Format<"uuid">;
/**
* Creation time of the article.
*/
created_at: string & tags.Format<"date-time">;
/**
* Last updated time of the article.
*/
updated_at: string & tags.Format<"date-time">;
}
namespace IBbsArticle {
/**
* Information of the article to create.
*/
export interface ICreate {
/**
* Title of the article.
*
* Representative title of the article.
*/
title: string;
/**
* Content body.
*
* Content body of the article writtn in the markdown format.
*/
body: string;
/**
* Thumbnail image URI.
*
* Thumbnail image URI which can represent the article.
*
* If configured as `null`, it means that no thumbnail image in the article.
*/
thumbnail:
| null
| (string & tags.Format<"uri"> & tags.ContentMediaType<"image/*">);
}
/**
* Information of the article to update.
*
* Only the filled properties will be updated.
*/
export type IUpdate = Partial<ICreate>;
}
Here is the example code utilizing the typia.llm.application<App, Model>()
function.
As you can see, above example code is writing detailed descriptions for every functions and their parameter/return types. Such detailed descriptions are very important to teach the purpose of the function to the LLM (Language Large Model), and LLM actually determines which function to call by the description. Therefore, don’t forget to writing detailed descriptions. It’s very import feature for the LLM function calling.
Also, ILlmFunction
type which has only description
property about the comment, but ILlmSchema
has two descriptive properties; description
and title
. The title
property of the ILlmSchema
can be filled by two ways. The first way is closing the first line of the description comment with a period (.
). By the way, this way’s description
property would be the entire description comment even including the first line.
If you don’t want that, you can adapt the second way that writing @title {string}
comment tag. In that case, the title
value would not be contained in the description
value. For reference, it is possible to fill the description
property of the ILlmSchema
by the comment tag @description
, but you have to take care of the indentation like below.
interface IMember {
/**
* Primary Key.
*
* Above "Primary Key" would be the title of LLM schema.
*/
id: string;
/**
* Below "Age of the member" would be the title of LLM schema.
*
* @title Age of the member
*/
age: number;
/**
* @title Email address of the member
* @description The description property also can be filled by
* the comment tag `@description`. Instead, be
* careful about the indentation.
*/
email: string;
}
Namespace Strategy
import { ILlmApplication, ILlmFunction } from "@samchon/openapi";
import typia, { tags } from "typia";
const app: ILlmApplication<"chatgpt"> = typia.llm.application<
BbsArticleController,
"chatgpt",
>();
const func: ILlmFunction<"chatgpt"> | undefined = app.functions.find(
func => func.name === "create"
);
console.log(func?.parameters.properties.input?.description);
/**
* Article entity.
*
* `IBbsArticle` is an entity representing an article in the BBS (Bulletin Board System).
*/
interface IBbsArticle extends IBbsArticle.ICreate {
/**
* Primary Key.
*/
id: string & tags.Format<"uuid">;
/**
* Creation time of the article.
*/
created_at: string & tags.Format<"date-time">;
/**
* Last updated time of the article.
*/
updated_at: string & tags.Format<"date-time">;
}
namespace IBbsArticle {
/**
* Information of the article to create.
*/
export interface ICreate {
/**
* Title of the article.
*
* Representative title of the article.
*/
title: string;
/**
* Content body.
*
* Content body of the article writtn in the markdown format.
*/
body: string;
/**
* Thumbnail image URI.
*
* Thumbnail image URI which can represent the article.
*
* If configured as `null`, it means that no thumbnail image in the article.
*/
thumbnail:
| null
| (string & tags.Format<"uri"> & tags.ContentMediaType<"image/*">);
}
/**
* Information of the article to update.
*
* Only the filled properties will be updated.
*/
export type IUpdate = Partial<ICreate>;
}
interface BbsArticleController {
/**
* Create a new article.
*
* Writes a new article and archives it into the DB.
*
* @param props Properties of create function
* @returns Newly created article
*/
create(props: {
/**
* Information of the article to create
*/
input: IBbsArticle.ICreate;
}): Promise<IBbsArticle>;
/**
* Update an article.
*
* Updates an article with new content.
*
* @param props Properties of update function
* @param input New content to update
*/
update(props: {
/**
* Target article's {@link IBbsArticle.id}.
*/
id: string & tags.Format<"uuid">;
/**
* New content to update.
*/
input: IBbsArticle.IUpdate;
}): Promise<void>;
/**
* Erase an article.
*
* Erases an article from the DB.
*
* @param props Properties of erase function
*/
erase(props: {
/**
* Target article's {@link IBbsArticle.id}.
*/
id: string & tags.Format<"uuid">;
}): Promise<void>;
}
typia.llm.application<App, Model>()
copies the parent namespaced type description comment to the children types. typia
calls this comment writing strategy as namespace documentation, and it is recommended for the efficient documentation.
As you can see from the above example, BbsArticleController
has many CRUD functions about the IBbsArticle
namespaced type. By the way, the above IBbsArticle.ICreate
and IBbsArticle.IUpdate
types are not repeating same description comments about the IBbsArticle
type. Instead, just writing the short description comment about them, and just compose the LLM function calling application schema.
In that case, the IBbsArticle
type’s description comment would be copied to the IBbsArticle.ICreate
and IBbsArticle.IUpdate
types like above “Console Output” case. It’s a good strategy to avoid repeating same description comments, and also to deliver enough information to the LLM function calling.
Function Hiding
import {
ClaudeTypeChecker,
ILlmApplication,
ILlmSchema,
} from "@samchon/openapi";
import typia, { tags } from "typia";
const app: ILlmApplication<"chatgpt"> = typia.llm.application<
BbsArticleController,
"chatgpt"
>();
console.log(app);
interface BbsArticleController {
/**
* Create a new article.
*
* Writes a new article and archives it into the DB.
*
* @param props Properties of create function
* @returns Newly created article
*/
create(props: {
/**
* Information of the article to create
*/
input: IBbsArticle.ICreate;
}): Promise<IBbsArticle>;
/**
* Read an article.
*
* Reads an article from the DB.
*
* @param props Properties of read function
* @returns The article
* @hidden
*/
at(props: {
/**
* Target article's {@link IBbsArticle.id}.
*/
id: string & tags.Format<"uuid">;
}): Promise<IBbsArticle>;
/**
* Update an article.
*
* Updates an article with new content.
*
* @param props Properties of update function
* @param input New content to update
* @internal
*/
update(props: {
/**
* Target article's {@link IBbsArticle.id}.
*/
id: string & tags.Format<"uuid">;
/**
* New content to update.
*/
input: IBbsArticle.IUpdate;
}): Promise<void>;
/**
* Erase an article.
*
* Erases an article from the DB.
*
* @param props Properties of erase function
* @human
*/
erase(props: {
/**
* Target article's {@link IBbsArticle.id}.
*/
id: string & tags.Format<"uuid">;
}): Promise<void>;
}
Hiding some functions by comment tag.
If you write @hidden
, @human
or @internal
tag onto a function description comment, the function would not participate in the LLM (Large Language Model) function calling application composition. ILlmFunction
schema does not be genrated in the ILlmApplication.functions
collection.
It’s a good feature to hide some internal functions, so that avoiding the LLM function calling.
Specialization
import { IChatGptSchema } from "@samchon/openapi";
import typia, { tags } from "typia";
export const schema: IChatGptSchema = typia.llm.schema<Special, "claude">();
interface Special {
/**
* Deprecated tags are just used for marking.
*
* @title Unsigned integer
* @deprecated
*/
type: number & tags.Type<"int32">;
/**
* Internal tagged property never be shown in JSON schema.
*
* It even doesn't be shown in other `typia` functions like `assert<T>()`.
*
* @internal
*/
internal: number[];
/**
* Hidden tagged property never be shown in JSON schema.
*
* However, it would be shown in other `typia` functions like `stringify<T>()`.
*
* @hidden
*/
hidden: boolean;
/**
* You can limit the range of number.
*
* @exclusiveMinimum 19
* @maximum 100
* @default 30
*/
number?: number;
/**
* You can limit the length of string.
*
* Also, multiple range conditions are also possible.
*/
string: string &
(
| (tags.MinLength<3> & tags.MaxLength<24>)
| (tags.MinLength<40> & tags.MaxLength<100>)
);
/**
* You can limit the pattern of string.
*
* @pattern ^[a-z]+$
*/
pattern: string;
/**
* You can limit the format of string.
*
* @format date-time
*/
format: string | null;
/**
* In the Array case, possible to restrict its elements.
*/
array: Array<string & tags.Format<"uuid">> & tags.MinItems<3>;
}
You can utilize type tags (or validator’s comment tags) to constructing special fields of JSON schema.
If you write any comment on a property, it would fill the IJsonSchema.description
value. Also, there’re special comment tags only for JSON schema definition that are different with validator’s comment tags like below.
@deprecated
@hidden
@internal
@title {string}
@default {value}
Let’s see how those type tags, comment tags and description comments are working with example code.
Customization
If what you want is not just filling regular properties of LLM schema specification, but to adding custom properties into the JSON schema definition, you can do it through the tags.TagBase.schema
property type or tags.JsonSchemaPlugin
type.
For reference, the custom property must be started with x-
prefix. It’s a rule of LLM schema.
import typia, { tags } from "typia";
type Monetary<Value extends string> = tags.TagBase<{
target: "number";
kind: "monetary";
value: Value;
schema: {
"x-monetary": Value;
};
}>;
type Placeholder<Value extends string> = tags.JsonSchemaPlugin<{
"x-placeholder": Value;
}>;
interface IAccount {
code: string & Placeholder<"Write you account code please">;
balance: number & Monetary<"dollar">;
};
typia.llm.schema<IAccount, "chatgpt">();