promaid


Namepromaid JSON
Version 0.1.0 PyPI version JSON
download
home_page
SummaryA markup language that can fill data into prompt
upload_time2023-05-07 11:50:02
maintainer
docs_urlNone
authorEterance
requires_python>=3.6
license
keywords prompt markup language nlp ai gpt
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # ProMaid Language

## 这有什么用?

Prompt 的构建一般使用代码(如 Python) 的字符串拼接。

这样的缺点是:

- 构建时不够直观,不能直接看到 Template / Prompt 长什么样;
- 换行的处理非常麻烦;
- 想要修改 Template 就要修改代码,一不小心容易改错。

使用 **ProMaid Language**(以下简称 **PML** ),你可以将 Template 的构建与主代码分离,并且能直观地构建它———事实上,写 PML 就是在写一个文本文件,而不是费力地做字符串拼接。

---

## 一个例子

> 以下示例可以在文件 [pml_builder_demo.py](demos\simple_demo\pml_builder_demo.py) 中找到。

现在你手头有这样一份数据:

```python
# 3 个上下文样本
incontext_samples = \
[
    {
        "lang": "C#",
        "code": "public class Test { public static void Main() { Console.WriteLine(\"Hello World!\"); } }"
    },
    {
        "lang": "C",
        "code": "int main() { printf(\"Hello World!\"); return 0; }"
    },
    {
        "lang": "Visual Basic",
        "code": "Module Module1 Sub Main() Console.WriteLine(\"Hello World!\") End Sub End Module"
    }
]
# 1 个输入,这里的 code 是 Ground-Truth
query_samples = \
{
    "lang": "Python",
    "code": "print(\"Hello World!\")"
}
```

请注意,虽然这份数据有 3 个上下文样本,但是应该假定你不知道 `incontext_samples` 数组里有多少个元素,你只知道单个元素里面有 `"lang"` 和 `"code"`。

你想构造出下面的 Prompt:

>-- Answer the following questions about the code snippet below.
>
>-- Question 1  
>
>Question: Write a C# program that prints "Hello World!" to the console.  
Code: public class Test { public static void Main() { Console.WriteLine("Hello World!"); } }  
>
>-- Question 2  
>
>Question: Write a C program that prints "Hello World!" to the console.  
Code: int main() { printf("Hello World!"); return 0; }  
>
>-- Question 3  
>
>Question: Write a Visual Basic program that prints "Hello World!" to the console.  
Code: Module Module1 Sub Main() Console.WriteLine("Hello World!") End Sub End Module  
>
>-- Question 4  
>
>Question: Write a Python program that prints "Hello World!" to the console.  
Code:

如果使用 Python ,代码会是这样的:

```python
prompt = "-- Answer the following questions about the code snippet below.\n\n"
count = 1
for index, sample in enumerate(incontext_samples):
    prompt += f"-- Question {count}\n\n"
    prompt += f"Question: Write a {sample['lang']} program that prints \"Hello World!\" to the console.\n"
    prompt += f"Code: {sample['code']}\n\n"
    count += 1
prompt += f"-- Question {count}\n\n"
prompt += f"Question: Write a {query_samples['lang']} program that prints \"Hello World!\" to the console.\n"
prompt += f"Code:"
```

看起来并不是很直观。那么怎么改成使用 PML 呢?

首先,构造 PML 文件。假设你将其保存到了 [demo_template.pml](demos\simple_demo\demo_template.pml) 中。

我们先弄一个上下文样本的枚举/循环:

```python
-- Answer the following questions about the code snippet below.

# 枚举 incontext_samples 里面的元素
{loop:incontext_samples}
-- Question {print:index+1}

Question: Write a {print:data(~.lang)} program that prints "Hello World!" to the console.
Code: {print:data(~.code)}

# 结束循环体
{end}
```

然后添加其他部分:

```python
-- Answer the following questions about the code snippet below.

# 定义一个全局变量 count
{var:count=1}
# 枚举 incontext_samples 里面的元素
{loop:incontext_samples}
-- Question {print:index+1}

Question: Write a {print:data(~.lang)} program that prints "Hello World!" to the console.
Code: {print:data(~.code)}

# 全局变量 count 自增 1
{var:count+=1}
# 结束循环体
{end}
-- Question {print:count}

Question: Write a {print:data(query_samples.lang)} program that prints "Hello World!" to the console.
Code:
```

>有关 PML 的语法,请参阅 [PML 语法手册](PML语法手册.md)。

最后,运行 [pml_builder_demo.py](demos\simple_demo\pml_builder_demo.py):

得到的 Prompt 应该和使用 Python 字符串拼接的一致。

---

## 错误处理

PML Parser 拥有完善的错误提示系统。

为了演示如何处理错误,我们将上一步的 demo 中的 template 第 7 行的 `{print:data(~.lang)}` 改为 `{print:data(~.language)}`。

```python
-- Answer the following questions about the code snippet below.

{var:count=1}
{loop:incontext_samples}
-- Question {print:index+1}

Question: Write a {print:data(~.language)} program that prints "Hello World!" to the console.
Code: {print:data(~.code)}

{var:count+=1}
{end}
-- Question {print:count}

Question: Write a {print:data(query_samples.lang)} program that prints "Hello World!" to the console.
Code:
```

运行 [pml_builder_demo.py](demos\simple_demo\pml_builder_demo.py) ,Python 控制台会提示类似下面的错误:

```python
PathNotFoundError at Line 7: Path "language" not found, error path "language", already found path ""
```

错误提示告诉我们,template 的第 7 行有误:找不到叫 `language` 的数据名称————实际上,正确的名称是 `lang`。

---

## PML Parser 怎么把 template 构建为 prompt 的?

1. 构造函数 `PmlParser()` 输入 PML ,分词并判断每一块片段的类型。
2. 构造语法树。
3. `PmlParser.build_prompt()` 输入数据,前序遍历语法树,为每个非空结点填充对应的数据。
4. 数据填充完成后,前序遍历所有非终结符,得到 Prompt。

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "promaid",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": "",
    "keywords": "Prompt,Markup Language,NLP,AI,GPT",
    "author": "Eterance",
    "author_email": "",
    "download_url": "https://files.pythonhosted.org/packages/fc/a5/2c28419110d1d961a0dc41f16938371369fa830081c3bbddf815f998c669/promaid-0.1.0.tar.gz",
    "platform": null,
    "description": "# ProMaid Language\n\n## \u8fd9\u6709\u4ec0\u4e48\u7528\uff1f\n\nPrompt \u7684\u6784\u5efa\u4e00\u822c\u4f7f\u7528\u4ee3\u7801\uff08\u5982 Python\uff09 \u7684\u5b57\u7b26\u4e32\u62fc\u63a5\u3002\n\n\u8fd9\u6837\u7684\u7f3a\u70b9\u662f\uff1a\n\n- \u6784\u5efa\u65f6\u4e0d\u591f\u76f4\u89c2\uff0c\u4e0d\u80fd\u76f4\u63a5\u770b\u5230 Template / Prompt \u957f\u4ec0\u4e48\u6837\uff1b\n- \u6362\u884c\u7684\u5904\u7406\u975e\u5e38\u9ebb\u70e6\uff1b\n- \u60f3\u8981\u4fee\u6539 Template \u5c31\u8981\u4fee\u6539\u4ee3\u7801\uff0c\u4e00\u4e0d\u5c0f\u5fc3\u5bb9\u6613\u6539\u9519\u3002\n\n\u4f7f\u7528 **ProMaid Language**\uff08\u4ee5\u4e0b\u7b80\u79f0 **PML** \uff09\uff0c\u4f60\u53ef\u4ee5\u5c06 Template \u7684\u6784\u5efa\u4e0e\u4e3b\u4ee3\u7801\u5206\u79bb\uff0c\u5e76\u4e14\u80fd\u76f4\u89c2\u5730\u6784\u5efa\u5b83\u2014\u2014\u2014\u4e8b\u5b9e\u4e0a\uff0c\u5199 PML \u5c31\u662f\u5728\u5199\u4e00\u4e2a\u6587\u672c\u6587\u4ef6\uff0c\u800c\u4e0d\u662f\u8d39\u529b\u5730\u505a\u5b57\u7b26\u4e32\u62fc\u63a5\u3002\n\n---\n\n## \u4e00\u4e2a\u4f8b\u5b50\n\n> \u4ee5\u4e0b\u793a\u4f8b\u53ef\u4ee5\u5728\u6587\u4ef6 [pml_builder_demo.py](demos\\simple_demo\\pml_builder_demo.py) \u4e2d\u627e\u5230\u3002\n\n\u73b0\u5728\u4f60\u624b\u5934\u6709\u8fd9\u6837\u4e00\u4efd\u6570\u636e\uff1a\n\n```python\n# 3 \u4e2a\u4e0a\u4e0b\u6587\u6837\u672c\nincontext_samples = \\\n[\n    {\n        \"lang\": \"C#\",\n        \"code\": \"public class Test { public static void Main() { Console.WriteLine(\\\"Hello World!\\\"); } }\"\n    },\n    {\n        \"lang\": \"C\",\n        \"code\": \"int main() { printf(\\\"Hello World!\\\"); return 0; }\"\n    },\n    {\n        \"lang\": \"Visual Basic\",\n        \"code\": \"Module Module1 Sub Main() Console.WriteLine(\\\"Hello World!\\\") End Sub End Module\"\n    }\n]\n# 1 \u4e2a\u8f93\u5165\uff0c\u8fd9\u91cc\u7684 code \u662f Ground-Truth\nquery_samples = \\\n{\n    \"lang\": \"Python\",\n    \"code\": \"print(\\\"Hello World!\\\")\"\n}\n```\n\n\u8bf7\u6ce8\u610f\uff0c\u867d\u7136\u8fd9\u4efd\u6570\u636e\u6709 3 \u4e2a\u4e0a\u4e0b\u6587\u6837\u672c\uff0c\u4f46\u662f\u5e94\u8be5\u5047\u5b9a\u4f60\u4e0d\u77e5\u9053 `incontext_samples` \u6570\u7ec4\u91cc\u6709\u591a\u5c11\u4e2a\u5143\u7d20\uff0c\u4f60\u53ea\u77e5\u9053\u5355\u4e2a\u5143\u7d20\u91cc\u9762\u6709 `\"lang\"` \u548c `\"code\"`\u3002\n\n\u4f60\u60f3\u6784\u9020\u51fa\u4e0b\u9762\u7684 Prompt\uff1a\n\n>-- Answer the following questions about the code snippet below.\n>\n>-- Question 1  \n>\n>Question: Write a C# program that prints \"Hello World!\" to the console.  \nCode: public class Test { public static void Main() { Console.WriteLine(\"Hello World!\"); } }  \n>\n>-- Question 2  \n>\n>Question: Write a C program that prints \"Hello World!\" to the console.  \nCode: int main() { printf(\"Hello World!\"); return 0; }  \n>\n>-- Question 3  \n>\n>Question: Write a Visual Basic program that prints \"Hello World!\" to the console.  \nCode: Module Module1 Sub Main() Console.WriteLine(\"Hello World!\") End Sub End Module  \n>\n>-- Question 4  \n>\n>Question: Write a Python program that prints \"Hello World!\" to the console.  \nCode:\n\n\u5982\u679c\u4f7f\u7528 Python \uff0c\u4ee3\u7801\u4f1a\u662f\u8fd9\u6837\u7684\uff1a\n\n```python\nprompt = \"-- Answer the following questions about the code snippet below.\\n\\n\"\ncount = 1\nfor index, sample in enumerate(incontext_samples):\n    prompt += f\"-- Question {count}\\n\\n\"\n    prompt += f\"Question: Write a {sample['lang']} program that prints \\\"Hello World!\\\" to the console.\\n\"\n    prompt += f\"Code: {sample['code']}\\n\\n\"\n    count += 1\nprompt += f\"-- Question {count}\\n\\n\"\nprompt += f\"Question: Write a {query_samples['lang']} program that prints \\\"Hello World!\\\" to the console.\\n\"\nprompt += f\"Code:\"\n```\n\n\u770b\u8d77\u6765\u5e76\u4e0d\u662f\u5f88\u76f4\u89c2\u3002\u90a3\u4e48\u600e\u4e48\u6539\u6210\u4f7f\u7528 PML \u5462\uff1f\n\n\u9996\u5148\uff0c\u6784\u9020 PML \u6587\u4ef6\u3002\u5047\u8bbe\u4f60\u5c06\u5176\u4fdd\u5b58\u5230\u4e86 [demo_template.pml](demos\\simple_demo\\demo_template.pml) \u4e2d\u3002\n\n\u6211\u4eec\u5148\u5f04\u4e00\u4e2a\u4e0a\u4e0b\u6587\u6837\u672c\u7684\u679a\u4e3e/\u5faa\u73af\uff1a\n\n```python\n-- Answer the following questions about the code snippet below.\n\n# \u679a\u4e3e incontext_samples \u91cc\u9762\u7684\u5143\u7d20\n{loop:incontext_samples}\n-- Question {print:index+1}\n\nQuestion: Write a {print:data(~.lang)} program that prints \"Hello World!\" to the console.\nCode: {print:data(~.code)}\n\n# \u7ed3\u675f\u5faa\u73af\u4f53\n{end}\n```\n\n\u7136\u540e\u6dfb\u52a0\u5176\u4ed6\u90e8\u5206\uff1a\n\n```python\n-- Answer the following questions about the code snippet below.\n\n# \u5b9a\u4e49\u4e00\u4e2a\u5168\u5c40\u53d8\u91cf count\n{var:count=1}\n# \u679a\u4e3e incontext_samples \u91cc\u9762\u7684\u5143\u7d20\n{loop:incontext_samples}\n-- Question {print:index+1}\n\nQuestion: Write a {print:data(~.lang)} program that prints \"Hello World!\" to the console.\nCode: {print:data(~.code)}\n\n# \u5168\u5c40\u53d8\u91cf count \u81ea\u589e 1\n{var:count+=1}\n# \u7ed3\u675f\u5faa\u73af\u4f53\n{end}\n-- Question {print:count}\n\nQuestion: Write a {print:data(query_samples.lang)} program that prints \"Hello World!\" to the console.\nCode:\n```\n\n>\u6709\u5173 PML \u7684\u8bed\u6cd5\uff0c\u8bf7\u53c2\u9605 [PML \u8bed\u6cd5\u624b\u518c](PML\u8bed\u6cd5\u624b\u518c.md)\u3002\n\n\u6700\u540e\uff0c\u8fd0\u884c [pml_builder_demo.py](demos\\simple_demo\\pml_builder_demo.py)\uff1a\n\n\u5f97\u5230\u7684 Prompt \u5e94\u8be5\u548c\u4f7f\u7528 Python \u5b57\u7b26\u4e32\u62fc\u63a5\u7684\u4e00\u81f4\u3002\n\n---\n\n## \u9519\u8bef\u5904\u7406\n\nPML Parser \u62e5\u6709\u5b8c\u5584\u7684\u9519\u8bef\u63d0\u793a\u7cfb\u7edf\u3002\n\n\u4e3a\u4e86\u6f14\u793a\u5982\u4f55\u5904\u7406\u9519\u8bef\uff0c\u6211\u4eec\u5c06\u4e0a\u4e00\u6b65\u7684 demo \u4e2d\u7684 template \u7b2c 7 \u884c\u7684 `{print:data(~.lang)}` \u6539\u4e3a `{print:data(~.language)}`\u3002\n\n```python\n-- Answer the following questions about the code snippet below.\n\n{var:count=1}\n{loop:incontext_samples}\n-- Question {print:index+1}\n\nQuestion: Write a {print:data(~.language)} program that prints \"Hello World!\" to the console.\nCode: {print:data(~.code)}\n\n{var:count+=1}\n{end}\n-- Question {print:count}\n\nQuestion: Write a {print:data(query_samples.lang)} program that prints \"Hello World!\" to the console.\nCode:\n```\n\n\u8fd0\u884c [pml_builder_demo.py](demos\\simple_demo\\pml_builder_demo.py) \uff0cPython \u63a7\u5236\u53f0\u4f1a\u63d0\u793a\u7c7b\u4f3c\u4e0b\u9762\u7684\u9519\u8bef\uff1a\n\n```python\nPathNotFoundError at Line 7: Path \"language\" not found, error path \"language\", already found path \"\"\n```\n\n\u9519\u8bef\u63d0\u793a\u544a\u8bc9\u6211\u4eec\uff0ctemplate \u7684\u7b2c 7 \u884c\u6709\u8bef\uff1a\u627e\u4e0d\u5230\u53eb `language` \u7684\u6570\u636e\u540d\u79f0\u2014\u2014\u2014\u2014\u5b9e\u9645\u4e0a\uff0c\u6b63\u786e\u7684\u540d\u79f0\u662f `lang`\u3002\n\n---\n\n## PML Parser \u600e\u4e48\u628a template \u6784\u5efa\u4e3a prompt \u7684\uff1f\n\n1. \u6784\u9020\u51fd\u6570 `PmlParser()` \u8f93\u5165 PML \uff0c\u5206\u8bcd\u5e76\u5224\u65ad\u6bcf\u4e00\u5757\u7247\u6bb5\u7684\u7c7b\u578b\u3002\n2. \u6784\u9020\u8bed\u6cd5\u6811\u3002\n3. `PmlParser.build_prompt()` \u8f93\u5165\u6570\u636e\uff0c\u524d\u5e8f\u904d\u5386\u8bed\u6cd5\u6811\uff0c\u4e3a\u6bcf\u4e2a\u975e\u7a7a\u7ed3\u70b9\u586b\u5145\u5bf9\u5e94\u7684\u6570\u636e\u3002\n4. \u6570\u636e\u586b\u5145\u5b8c\u6210\u540e\uff0c\u524d\u5e8f\u904d\u5386\u6240\u6709\u975e\u7ec8\u7ed3\u7b26\uff0c\u5f97\u5230 Prompt\u3002\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "A markup language that can fill data into prompt",
    "version": "0.1.0",
    "project_urls": null,
    "split_keywords": [
        "prompt",
        "markup language",
        "nlp",
        "ai",
        "gpt"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "3ca400e52e65214bda4503f1cc9c14e8cf161450fefe1774c7256228081c0e2d",
                "md5": "20ed81534f6fd20a315be7ce3ca34b77",
                "sha256": "1d95e2bbeee17497cb71032796438586eb8312e86a4a705844a7c78ca594ff5f"
            },
            "downloads": -1,
            "filename": "promaid-0.1.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "20ed81534f6fd20a315be7ce3ca34b77",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6",
            "size": 13200,
            "upload_time": "2023-05-07T11:49:58",
            "upload_time_iso_8601": "2023-05-07T11:49:58.506310Z",
            "url": "https://files.pythonhosted.org/packages/3c/a4/00e52e65214bda4503f1cc9c14e8cf161450fefe1774c7256228081c0e2d/promaid-0.1.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "fca52c28419110d1d961a0dc41f16938371369fa830081c3bbddf815f998c669",
                "md5": "8c881c807f89e31bbdffa67a1c4fdbfd",
                "sha256": "6472e21cc4ea9fd5f9b2fbece83b53e1ac2d1c17971428bf0ed8f3afb9ef6b15"
            },
            "downloads": -1,
            "filename": "promaid-0.1.0.tar.gz",
            "has_sig": false,
            "md5_digest": "8c881c807f89e31bbdffa67a1c4fdbfd",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6",
            "size": 23727,
            "upload_time": "2023-05-07T11:50:02",
            "upload_time_iso_8601": "2023-05-07T11:50:02.935252Z",
            "url": "https://files.pythonhosted.org/packages/fc/a5/2c28419110d1d961a0dc41f16938371369fa830081c3bbddf815f998c669/promaid-0.1.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-05-07 11:50:02",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "promaid"
}
        
Elapsed time: 0.11447s