{"id":49325533,"url":"https://github.com/CJGroup/langchain4kt","last_synced_at":"2026-05-29T21:00:53.830Z","repository":{"id":258272830,"uuid":"865443132","full_name":"CJGroup/langchain4kt","owner":"CJGroup","description":"A Kotlin version of langchain. Support for Kotlin Multiplatform.","archived":false,"fork":false,"pushed_at":"2025-07-23T06:30:08.000Z","size":670,"stargazers_count":25,"open_issues_count":2,"forks_count":6,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-23T08:27:07.104Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CJGroup.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-09-30T14:37:59.000Z","updated_at":"2025-07-23T06:30:11.000Z","dependencies_parsed_at":"2024-10-22T20:48:31.520Z","dependency_job_id":"f4766323-84fa-466e-bc32-a7d4f9354b19","html_url":"https://github.com/CJGroup/langchain4kt","commit_stats":null,"previous_names":["cjgroup/langchain4kt"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/CJGroup/langchain4kt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CJGroup%2Flangchain4kt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CJGroup%2Flangchain4kt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CJGroup%2Flangchain4kt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CJGroup%2Flangchain4kt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CJGroup","download_url":"https://codeload.github.com/CJGroup/langchain4kt/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CJGroup%2Flangchain4kt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33670211,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-29T02:00:06.066Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-26T20:00:31.588Z","updated_at":"2026-05-29T21:00:53.818Z","avatar_url":"https://github.com/CJGroup.png","language":"Kotlin","funding_links":[],"categories":["人工智能"],"sub_categories":["LLM框架"],"readme":"# Langchain4kt2\n\nThis library is reimplemented to provide support for the future of LLM.\n\n## Why to remake?\n\nIt's a hard decision to remake langchain4kt.\n\nThe original idea is to provide a universal and KMP way to use the text-central functionality of LLM. And It faced several issues:\n\n### The difference between LLMs\n\nDifferent LLMs have very different APIs that sometimes there is no way to unify them. For example, multimodal LLMs from OpenAI and Google Gemini have very different ways to structure the input and output of the model.\n\n### More complexity of the LLMs' input/output types\n\nWith the rapid development of LLM technology, the input and output types of LLMs are becoming more and more complex. \n\nText, document in certain format, image, audio, video, tool calling, and even more types such as reasoning process, action, parallel tool calling and composed tool calling are involved in the context of LLMs.\n\nFacing this issue, we need a type-safe and easy-to-use way to handle these types. The solution is **union type**. Langchain4kt2 is reimplemented with [KUnion](https://github.com/Stream29/KUnion) to handle these types.\n\n### Need for abstraction and composability\n\nThe old OOP style of the original library lacks conciseness and expressiveness of Kotlin, making it more similar to old plain Java code.\n\nThe new functional style of Langchain4kt2 allows you to easily compose functionalities and abstract them into reusable components with type-safe and concise code.\n\n## Principles of Langchain4kt2\n\n### Functional style\n\nFunctional style make the functionalities more composable with better discoverability and readability.\n\nThe core concepts of langchain4kt2 is completely a function:\n\n```kotlin\npublic typealias Generator\u003cRequest, Response\u003e = suspend (Request) -\u003e Response\n```\n\nAnd we have a bunch of extension function to compose the functionalities. \nThey are too many to list here. (some are provided in 2 version for suspend and normal function)\n\n### Provide a very similar type-safe API to every model provider, but keep the differences\n\nWe have common items for chat history. But the type can be different for some models.\n\nFor example, the `OpenAiToolCallRequest` data class is with a `id` field to support the `ChatCompletion` API:\n\n```kotlin\npublic data class OpenAiToolCallRequest(\n    val id: String,\n    val name: String,\n    val param: String,\n)\n```\n\nWith this, the input/output type of OpenAI API models can be expressed into a union type:\n\n```kotlin\npublic typealias OpenAiInputContentPartUnion = Union2\u003c\n        UserTextMessage,\n        UserUrlImageMessage\n        \u003e\n\npublic typealias OpenAiOutputContentPartUnion = Union2\u003c\n        ModelTextMessage,\n        ModelUrlImageMessage\n        \u003e\n\npublic typealias OpenAiHistoryMessageUnion = Union8\u003c\n        UserTextMessage,\n        SystemTextMessage,\n        ModelTextMessage,\n        ListInputMessage\u003cOpenAiInputContentPartUnion\u003e,\n        ListOutputMessage\u003cOpenAiOutputContentPartUnion\u003e,\n        OpenAiToolCallRequest,\n        OpenAiToolCallRequestListMessage,\n        OpenAiToolCallResultMessage\n        \u003e\n\npublic typealias OpenAiOutputMessageUnion = Union4\u003c\n        ModelTextMessage,\n        ListOutputMessage\u003cOpenAiOutputContentPartUnion\u003e,\n        OpenAiToolCallRequest,\n        OpenAiToolCallRequestListMessage\n        \u003e\n```\n\nIt's up to you to use `ChatCompletion` or `Union`. (See example below)\n\n### Support `kotlinx.serialization` and `kotlinx.coroutine` at best effort\n\nWe all need to serialize and deserialize the chat history in some use cases. Langchain4kt2 provide a `Serializable` chat history for every LLM that you can serialize it without information lost.\n\nAll the generation API are `suspend fun`, and cooperative with `kotlinx.coroutine`.\n\nThe `Union` type is also serializable with `kotlinx.serialization`.\n\n### Reuse existing libraries to make it more usable for now\n\nIt's not a good idea to reinvent the wheel. Also, before the support from the community, we need to make the library more usable for more models.\n\nLangchain4kts has bridged APIs from [langchain4j](https://github.com/langchain4j/langchain4j), [openai-kotlin](https://github.com/aallam/openai-kotlin), [Spring AI](https://github.com/spring-projects/spring-ai) and [google-generative-ai-KMP](https://github.com/PatilShreyas/generative-ai-kmp). Thanks for the contributors of these libraries. Developers can use `langchain4kt2` with these libraries to use the models more more simply and typesafe.\n\nLangchain4kt is not going to be only a bridge library. Providing KMP implementations for models is a meaningful thing for the KMP community. But for now, to be realistic, we need to bridge existing libraries first, and implement other model providers' KMP APIs in the future.\n\n## Example\n\nYou can use the raw input/output type of the model:\n\n```kotlin\nval generate = openAi.asGenerator()\n    .configure { model = ModelId(\"qwen-turbo\") }\n    .generateByMessages()\n    .mapInputFromText()\n    .mapOutput { it.singleTextOrNull()!! } // assuming model should return a single text\nrunBlocking(Dispatchers.IO) {\n    val response = generate(\"hello\")\n    println(response)\n}\n```\n\nOr you can use the `mapUnion` to make the type in a serializable union form:\n\n```kotlin\nval generateSingle = openAi.asGenerator()\n    .configure { model = ModelId(\"qwen-turbo\") }\n    .mapUnion()\n    .mapInputFromSingle()\nval response = generateSingle(SafeUnion8(UserTextMessage(\"hello\")))\nresponse // handling the possible output types of model type-safely\n    .consume0 { modelTextMessage -\u003e println(\"Model: ${modelTextMessage.text}\") }\n    .consume1 { listOutputMessage -\u003e \n        println(\"Model:\")\n        listOutputMessage.list.forEach { item -\u003e\n            item.consume0 { modelTextMessage -\u003e println(modelTextMessage.text) }\n                .consume1 { modelUrlImageMessage -\u003e println(\"[image](${modelUrlImageMessage.url})\") }\n        }\n    }.consume2 { toolCallRequest -\u003e println(\"Model requests to call tool: ${toolCallRequest.name}\") }\n    .consume3 { toolCallRequestList -\u003e println(\"Model requests to call tool: ${toolCallRequestList.list.joinToString{ it.name }}\") }\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FCJGroup%2Flangchain4kt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FCJGroup%2Flangchain4kt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FCJGroup%2Flangchain4kt/lists"}