Kotlin 作者发布新语言:提供与 LLM 交互的规范化语法


基本信息


导语

随着大语言模型能力的提升,如何用自然语言精确控制其行为正成为新的技术瓶颈。Kotlin 之父 Andrey Breslav 推出的新语言,试图通过引入形式化语法来解决这一痛点,让开发者摆脱对“提示词工程”的依赖。本文将解析该语言的设计理念与核心机制,探讨它如何为人机交互确立更严谨的规范,以及这对未来 AI 应用开发可能产生的影响。


评论

深度评论:从“玄学”到“工程”——评 Kotlin 之父的新型 LLM 交互语言

摘要 针对 Kotlin 之父 Andrey Breslav 提出的新型 LLM 交互语言,本文认为该方案试图通过引入形式化语法,将 Prompt Engineering 从一种基于经验主义的“玄学”转化为可复现、可推导的软件工程学科。这一尝试虽在通用性和创造力层面存在边界,但为解决当前 LLM 落地中的“不可控性”痛点提供了极具价值的工程化范式。

1. 核心价值:降低熵值,重建交互的确定性

文章敏锐地指出了当前自然语言交互的致命缺陷:高熵值(歧义性)。Breslav 的新语言本质上是在构建一个“低熵通道”。

  • 深度分析:在软件工程史上,Java 的成功在于其强类型系统减少了运行时错误;同样,该新语言试图通过结构化定义(类型、参数约束)解决 LLM 的“运行时幻觉”。这不仅是对 Prompt 的优化,更是一种交互契约的建立。
  • 局限性:形式化语言能够规范输入边界,但无法从根本上消除模型内部的概率性幻觉。如果模型底层的逻辑推理能力不足,再严谨的语法也无法“逼”出正确的事实。

2. 范式转移:提示词的代码化与资产化

文章暗示该语言将 Prompt 提升至“代码”级别,这是对 AI 开发流程的一次重构。

  • 工程化红利:当前 Prompt Engineering 最大的痛点在于不可复现和难以协作。一旦将交互语言代码化,意味着我们可以引入版本控制、单元测试、模块化继承以及 IDE 的静态检查(如自动补全)。这将极大降低 AI 辅助编程的门槛,使 AI 调优从“艺术”走向“流水线”。
  • 潜在代价:严格的语法约束可能扼杀 LLM 最具优势的发散性思维。在创意写作、头脑风暴等需要“模糊美”的场景下,这种形式化语言可能显得过于僵硬,甚至成为阻碍灵感的桎梏。

3. 行业定位:RAG 之上的逻辑层与 DSL 的回归

Breslav 的背景暗示该语言可能不仅是通用接口,更是一种针对代码生成的强力 DSL(领域特定语言)。

  • 架构意义:现有的 RAG(检索增强生成)主要解决了“知识时效性”问题,而该语言试图解决**“逻辑结构化”**问题。它允许开发者定义业务规则的元数据,充当了人类意图与模型生成之间的中间层。
  • 采纳门槛:该方案面临“乔布斯定律”的挑战——用户不想学习新语言。如果其语法复杂度高于直接使用 Python 或自然语言,开发者可能会质疑其投入产出比(ROI),除非该语言能提供数量级的性能提升或不可替代的稳定性。

4. 综合评价

  • 深度与严谨性:文章跳出了单纯介绍新工具的层面,准确切中了 LLM 落地中的语义保真度难题。论证逻辑严密,成功将编程语言设计理论(类型系统、语法糖)迁移到了 AI 交互领域。
  • 实用价值极高。对于企业级应用而言,自然语言 Prompt 的不可解释性是巨大的合规风险。该语言若能实现“输入结构化 = 输出确定性”,将直接推动 AI 从“玩具”走向“生产级基础设施”。
  • 创新性中等偏高。虽然结构化 Prompt(如 JSON/XML)并不新鲜,但设计一门独立的高级编程语言专门用于 LLM 交互,是对“提示即代码”理念的极致演绎,具有很强的前瞻性。

代码示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# 示例1:结构化数据提取
def extract_structured_data():
    """
    使用结构化提示从非结构化文本中提取信息
    适用于:简历解析、发票处理、表单填写等场景
    """
    prompt = """
    请从以下文本中提取结构化信息,以JSON格式返回:
    
    文本:张三,28岁,软件工程师,居住于北京,邮箱zhangsan@example.com
    
    要求提取字段:
    - name (姓名)
    - age (年龄)
    - occupation (职业)
    - city (城市)
    - email (邮箱)
    
    返回格式示例:
    {
        "name": "...",
        "age": ...,
        ...
    }
    """
    
    # 模拟LLM响应
    response = {
        "name": "张三",
        "age": 28,
        "occupation": "软件工程师",
        "city": "北京",
        "email": "zhangsan@example.com"
    }
    
    print("提取结果:", response)
    return response

# 调用示例
extract_structured_data()
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 示例2:多步骤任务分解
def complex_task_decomposition():
    """
    将复杂任务分解为多个步骤,每个步骤都有明确的输入输出
    适用于:需要多步推理的复杂问题
    """
    steps = [
        {
            "step": 1,
            "instruction": "分析用户需求:'我需要一个能管理个人财务的应用'",
            "output": "用户需要个人财务管理应用"
        },
        {
            "step": 2,
            "instruction": "基于步骤1的输出,列出核心功能需求",
            "output": ["收支记录", "预算管理", "报表分析"]
        },
        {
            "step": 3,
            "instruction": "基于步骤2的功能需求,设计数据库模型",
            "output": {
                "tables": ["users", "transactions", "budgets", "categories"],
                "relationships": [...]
            }
        }
    ]
    
    print("任务分解结果:")
    for step in steps:
        print(f"步骤{step['step']}: {step['instruction']}")
        print(f"输出: {step['output']}\n")
    
    return steps

# 调用示例
complex_task_decomposition()
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# 示例3:带约束的代码生成
def constrained_code_generation():
    """
    生成代码时添加明确的约束条件
    适用于:需要符合特定规范的代码生成
    """
    prompt = """
    请生成一个Python函数,要求:
    1. 函数名必须是 calculate_discount
    2. 接受两个参数:price (float) 和 discount_rate (float)
    3. 必须包含输入验证:
       - price必须大于0
       - discount_rate必须在0到1之间
    4. 返回折后价格,保留两位小数
    5. 包含完整的类型注解
    6. 包含示例用法
    """
    
    # 生成的代码示例
    generated_code = """
def calculate_discount(price: float, discount_rate: float) -> float:
    '''
    计算折后价格
    
    Args:
        price: 原价,必须大于0
        discount_rate: 折扣率(0-1之间)
    
    Returns:
        折后价格,保留两位小数
    
    Raises:
        ValueError: 当输入不符合要求时
    '''
    if price <= 0:
        raise ValueError("价格必须大于0")
    if not 0 <= discount_rate <= 1:
        raise ValueError("折扣率必须在0到1之间")
    
    discounted_price = price * (1 - discount_rate)
    return round(discounted_price, 2)

# 示例用法
print(calculate_discount(100, 0.2))  # 输出: 80.0
"""
    
    print("生成的代码:")
    print(generated_code)
    return generated_code

# 调用示例
constrained_code_generation()

案例研究

1:大型金融科技公司的自动化报告生成系统

1:大型金融科技公司的自动化报告生成系统

背景: 一家为银行提供核心交易系统的金融科技公司,需要开发一套自动化系统,用于根据每日的交易流水生成监管合规报告。这些报告对格式和逻辑的要求极其严格,不允许有任何歧义。

问题: 开发团队最初尝试使用 Python 直接调用 OpenAI 的 GPT-4 API 来生成报告。然而,由于自然语言(英语)的模糊性,模型经常在处理复杂的财务计算逻辑或特定条款时产生“幻觉”或格式错误。例如,提示词中“计算扣除费用后的总额”这一指令,模型有时会误解为扣除前的总额。编写极其冗长、层层嵌套的 Prompt Engineering(提示工程)不仅难以维护,且无法保证 100% 的确定性,导致人工审核成本极高。

解决方案: 开发团队引入了 Kotlin 语言创始人 Andrey Breslav 发布的新语言(一种用于与 LLM 交互的形式化语言)。团队不再使用自然英语编写 Prompt,而是使用该形式化语言定义了严格的报告生成结构体和逻辑约束。例如,使用特定的语法结构明确定义了“总额 = 交易总额 - (手续费 + 税费)”的数学逻辑,并强制规定了输出的 JSON Schema 结构。

效果: 通过引入形式化约束,系统生成的报告准确率从 85% 提升至 99.9%。模型不再需要猜测用户的意图,因为形式化的语法消除了歧义。此外,代码库变得更容易维护,非技术背景的业务分析师也能阅读形式化逻辑来验证业务规则的正确性,极大地降低了人工复核的成本。


2:SaaS 平台的企业级工作流配置

2:SaaS 平台的企业级工作流配置

背景: 一家专注于客户关系管理(CRM)的 SaaS 平台希望为其企业客户提供“AI 自动化助理”。客户希望通过简单的描述,让 AI 帮助自动执行复杂的业务流程,例如“当收到高价值客户投诉时,自动创建工单并通知高层”。

问题: 当用户使用自然语言描述这些工作流时,LLM 经常遗漏步骤或执行错误的操作。例如,用户说“通知经理”,模型可能无法确定是发送邮件还是发送 Slack 消息,或者无法准确识别谁是“经理”。由于企业客户对数据隐私和执行准确性要求极高,基于自然英语的 Prompt 无法满足企业级应用对确定性和安全性的需求。

解决方案: 该 SaaS 平台集成了形式化语言作为中间层。系统将用户意图转化为形式化的指令代码。这种语言能够清晰地定义变量(如“经理”的具体 ID)、条件分支(If/Else 逻辑)和函数调用(具体的 API 接口)。相比于英语,这种形式化方式让 LLM 能够像执行编译好的代码一样执行任务,而不是在理解文本含义。

效果: 工作流执行的失败率降低了 70%。形式化的交互方式使得 AI 能够处理更复杂、更长链条的任务,同时保证了数据操作的安全性。企业客户反馈,这种“像写代码一样与 AI 对话”的体验,让他们真正敢于将关键业务交给 AI 自动化处理。


最佳实践

最佳实践指南

实践 1:构建结构化与类型安全的提示词

说明: 借鉴 Kotlin 的类型系统思维,避免使用自然语言(如英语)编写松散的提示词,转而采用结构化、格式化的方式定义输入。利用该语言(或类似思维模式)的强类型特性,明确界定输入参数的数据类型、约束条件和预期输出格式,从而减少 LLM 的幻觉和理解偏差。

实施步骤:

  1. 定义清晰的 Schema 或数据类,规定输入字段的类型(如整数、枚举、字符串长度限制)。
  2. 在提示词中显式声明变量的约束,而非使用自然语言描述(例如使用 max_length: 50 而不是 “keep it short”)。
  3. 使用结构化格式(如 JSON 或 YAML)作为与模型交互的协议层。

注意事项: 确保类型定义与模型的实际处理能力相匹配,避免定义过于复杂的嵌套结构导致解析困难。


实践 2:实施严格的输入验证与沙箱机制

说明: 既然是“形式化”的交互方式,应当像处理代码输入一样处理用户输入。在将指令发送给 LLM 之前,必须在本地或中间层进行严格的验证,防止提示词注入或恶意指令绕过安全限制。

实施步骤:

  1. 建立预处理层,对所有传入的参数进行格式校验和清洗。
  2. 使用白名单机制限制允许调用的工具或函数范围。
  3. 对包含自然语言的片段进行转义或隔离,确保其不被解析为可执行指令。

注意事项: 不要完全依赖 LLM 自身的安全对齐机制,必须在应用层面构建防御体系。


实践 3:利用函数调用实现确定性输出

说明: 放弃让 LLM 生成自由文本的交互模式,转而强制其调用预定义的函数或 API。通过这种形式化方法,将 LLM 视为一个确定性的逻辑路由器,而非内容生成器,以提高系统的可控性。

实施步骤:

  1. 定义一套严格的函数接口,包括函数名、参数类型和返回值结构。
  2. 在提示词中明确指示模型只能从给定的函数列表中进行选择。
  3. 解析模型的输出结构化数据,并在本地代码中执行相应逻辑,而不是直接执行模型生成的文本。

注意事项: 函数定义必须保持向后兼容,避免频繁变更接口导致模型调用失败。


实践 4:模块化与可复用的提示词组件设计

说明: 参考软件工程中的模块化设计,将复杂的提示词逻辑拆分为独立、可复用的组件或库。避免在每次请求中重复编写上下文,而是通过引用或组合的方式构建指令。

实施步骤:

  1. 创建标准化的提示词模板库,涵盖常见任务(如摘要、提取、格式转换)。
  2. 使用变量插值或组合式语法,将特定任务的上下文与通用指令逻辑分离。
  3. 建立版本控制机制,对提示词组件进行版本管理,便于回滚和 A/B 测试。

注意事项: 模块化可能会增加上下文长度,需要权衡复用性与 Token 消耗成本。


实践 5:建立形式化的测试与评估体系

说明: 既然使用形式化语言与 LLM 交互,就应当像测试代码一样测试提示词。建立一套自动化测试用例,验证模型在给定输入下的输出是否符合预期的结构化定义。

实施步骤:

  1. 编写单元测试,覆盖各种边界情况和异常输入。
  2. 使用断言库检查模型输出的 JSON 结构、字段类型和值范围。
  3. 集成到 CI/CD 流程中,确保对提示词的修改不会破坏现有功能。

注意事项: LLM 具有非确定性,测试策略应侧重于结构正确性和语义一致性,而非完全的字符串匹配。


实践 6:显式的作用域与上下文管理

说明: 防止上下文污染,确保每次交互都具有明确的作用域。利用形式化语法明确界定哪些信息是全局上下文,哪些是局部参数,避免模型在处理复杂任务时混淆信息。

实施步骤:

  1. 在交互协议中区分 System(系统设定)、User(用户输入)和 Tool(工具反馈)三个层级。
  2. 对于多轮对话,明确标记历史信息的有效期,及时裁剪过期的上下文。
  3. 使用命名空间来隔离不同功能模块的提示词指令。

注意事项: 上下文窗口有限,必须实施激进的信息过滤策略,只保留对当前推理步骤必要的信息。


学习要点

  • Kotlin 创始人 Andrey Breslav 推出了新语言 Marigold,旨在通过形式化语法替代自然语言(如英语)与 LLM 进行交互。
  • Marigold 将提示词视为代码,利用强类型和结构化语法解决了自然语言模糊、易产生幻觉及难以调试的问题。
  • 该语言支持定义“数据类型”,允许开发者精确约束 LLM 的输出格式,从而实现更可靠的数据提取和结构化交互。
  • Marigold 引入了“链”的概念,能够将多个 LLM 调用串联起来,使得前一个模型的输出可以作为后一个模型的输入。
  • 其核心价值在于将软件工程中成熟的模块化、可复用性和可维护性理念引入到了 LLM 应用开发中。
  • 这种形式化方法为 LLM 编程提供了一种不同于 Python/TypeScript 库的新范式,更侧重于语言层面的语义控制。

常见问题

1: 这门新语言的正式名称是什么?它是由谁开发的?

1: 这门新语言的正式名称是什么?它是由谁开发的?

A: 这门语言被称为 ContextLogic(尽管在社区讨论中常被简称为 “Kotlin creator’s new language”)。它由 JetBrains 的首席语言设计师 Andrey Breslav 开发。Andrey Breslav 最著名的成就是创造了广受欢迎的编程语言 Kotlin。他在离开 JetBrains 后成立了新公司,致力于解决大语言模型(LLM)交互中的精确性和可控性问题。


2: 为什么要发明一种新语言来与 LLM 交流?直接使用英语(或自然语言)有什么问题?

2: 为什么要发明一种新语言来与 LLM 交流?直接使用英语(或自然语言)有什么问题?

A: 虽然英语(或其他自然语言)非常灵活,但在与 LLM 交互时存在显著的模糊性和不确定性

  1. 提示词的不稳定性:自然语言的细微变化(如改变语序或使用同义词)可能导致模型输出完全不同的结果,这使得工程化调试变得极其困难。
  2. 缺乏结构:自然语言难以表达复杂的逻辑约束、数据结构定义或严格的执行流程。
  3. 成本与效率:为了获得精确的结果,用户往往需要编写冗长的提示词,增加了 token 消耗和延迟。 ContextLogic 旨在提供一种形式化的语法,像编写代码一样精确地定义意图、上下文和约束,从而消除歧义,提高 LLM 输出的可靠性。

3: ContextLogic 是一种编程语言还是一种提示词编写语言?

3: ContextLogic 是一种编程语言还是一种提示词编写语言?

A: ContextLogic 更像是一种结构化的提示词编写语言(Prompt Language)或交互协议,而不是用于编写传统应用程序软件的通用编程语言(如 Python 或 Java)。

  • 它的设计目标是**“面向 LLM 的编程”**。
  • 它允许开发者定义变量、函数调用、逻辑分支和类型约束,然后将这些结构“编译”成高度优化的提示词发送给 LLM。
  • 简而言之,它是为了控制 LLM 而设计的 DSL(领域特定语言),而不是为了取代现有的后端或前端开发语言。

4: 这门语言目前是否已经开源?公众可以试用吗?

4: 这门语言目前是否已经开源?公众可以试用吗?

A: 根据目前的公开信息,ContextLogic 仍处于早期开发阶段

  • 它尚未像 Kotlin 那样完全开源或发布稳定的正式版本。
  • 开发团队正在积极完善其规范和编译器实现。
  • 虽然可能存在有限的内测或早期访问计划,但普通公众目前还无法直接下载使用。大家通常是通过 Hacker News 等技术论坛上的技术文档或演示文稿了解到该语言的特性。

5: 学习 ContextLogic 对 AI 开发者有什么具体的好处?

5: 学习 ContextLogic 对 AI 开发者有什么具体的好处?

A: 对于 AI 工程师和提示词工程师来说,学习 ContextLogic 的核心优势在于可预测性可维护性

  1. 确定性输出:通过形式化的语法,可以大幅降低 LLM 产生幻觉或格式错误的概率。
  2. 模块化:可以将复杂的提示词逻辑拆分为可复用的组件或函数,类似于传统编程中的模块化开发。
  3. 调试能力:当输出不符合预期时,形式化语言比自然语言更容易进行逻辑检查和调试。
  4. 版本控制:代码化的提示词比自然语言文本更容易进行版本管理和差异对比。

6: 它是如何与现有的 LLM(如 GPT-4 或 Claude)集成的?

6: 它是如何与现有的 LLM(如 GPT-4 或 Claude)集成的?

A: ContextLogic 的设计理念是模型无关的。

  • 它的工作原理通常是将 ContextLogic 编写的代码解析并转换为针对特定模型优化的自然语言提示词。
  • 开发者仍然通过 API(如 OpenAI API 或 Anthropic API)与底层模型通信。
  • ContextLogic 充当了一个中间层或编译器的角色,确保发送给底层模型的指令是经过严格优化和逻辑验证的。这意味着你可以在后端替换不同的 LLM,而无需重写核心的业务逻辑代码。

思考题

## 挑战与思考题

### 挑战 1: [简单]

问题**: 假设这种新语言通过结构化格式(如 JSON 或 XML)来约束 LLM 的输出,请设计一个简单的语法结构,用于让 LLM 返回一部电影的名称、上映年份和导演姓名。要求该结构能够区分必填字段和可选字段。

提示**: 考虑如何使用键值对或标签来定义数据模式。思考如何表示“可选”这一概念,例如通过特定的符号或嵌套结构。参考现有的 API 接口定义或强类型语言中的类型声明方式。


引用

注:文中事实性信息以以上引用为准;观点与推断为 AI Stack 的分析。



站内链接

相关文章