有奖捉虫:行业应用 & 管理与支持文档专题 HOT
在不同业务场景中,不同的个人、团队、项目都会可能有不同的模型、模型参数、斜杠命令、Prompt 提示词等。本文从实战出发,指导如何通过 Prompt as Code 来自定义您的 AI 代码助手。

Prompt as Code 在 GenAI+ 软件工程下的重要性

在 AI+SE 的探索中,和很多企业客户进行深度访谈,确认了一些规律:
中大型企业至少会有一个私有化的基于企业语料训练的大语言模型,并有一个大模型的训练、发布、管理的平台。
代码生成在不同业务部门有差异,但总体软件研发流程相似,所以期望能在不同模型之上能有不同的效果,并提高生产率。
基于这些规律,可以总结出 SMAF 原则,并总结了三种 GenAI 在软件工程下的辅助方式:
聊天模式的辅助(侧栏对话、大屏对话、内联对话)。
补全模式的辅助(手动补全、自动补全、按语言补全)。
这两种模式是给开发同学的,他们只关心好不好用,通过两个模式的“组合拳”,看质量如何。
自定义配置优化质量:针对质量好不好的更细列度的应用层“微调”,让组合拳的价值点更高。
基于此,对 AI 代码助手进行了架构优化,定义了 product.json 文件,允许不同项目、不同人群可以更细粒度实现自定义扩展。大致结构如下图所示。product.json 文件读取您编写的 Prompt,并成为 AI 辅助功能的一部分。
?
?
?
这意味着:
您可以在团队里,共享您的 prompt,而不再是个性化的配置。
您组织里的不同团队,可以在各自的团队里分享自己的 AI 经验。
您不再需要定制更多的 IDE 需求,只需要提供接口能力即可。

Prompt as Code 示例

让我们来看一个简单的示例,例如我们想要为当前代码生成一个 doc 注释的捷径,并挂在 @workspace 的 agent 下,就可以定义这个如下文件。
首先您需要在您的代码库里创建(或者配置) .copilot 文件夹(文件夹需在根目录下),然后在该文件下创建 product.json 文件,文件内容示例如下:
{
"agents": [
{
"name": "workspace",
"slashCommands": [
{
"name": "javadoc",
"prompt": "请为该代码添加javadoc注释, 要符合javadoc的标准以及注释规范。注意不要修改原代码。",
"contentReference": {
"show": true
}
}
]
}
]
}
保存文件并重启 vscode 之后我们就可以看到这个效果,在 AI 代码助手的对话中,可以快速调用已经定义好的 prompt。
?
?
?

实战:通过扩展实现对话需求一键创建 Notebook 文件

可以观察到 Github Copilot 具有 /new 和 /noteNotebook 两种入口,方便通过需求创建项目。通过网络截取请求,获取到 GitHub Copilot 对于这两种场景的提示词,并重新定义 prompt.json 文件,来试试看基于混元对话模型上可否完成这个能力。

从 GitHub Copilot 截取分析开始

?
?
?
从发送的报文截断可以找到一些规律。
?
{ "messages": [ { "role": "system", "content": "You are a VS Code assistant. Your job is to suggest a filetree directory structure for a project that a user wants to create. If a step does not relate to filetree directory structures, do not respond. Please do not guess a response and instead just respond with a polite apology if you are unsure. Please end your response with [RESPONSE END] and do not include any other text.\\nWhen asked for your name, you must respond with \\"GitHub Copilot\\".\\nFollow the user's requirements carefully & to the letter.\\nYou are an AI programming assistant.\\nWhen asked for your name, you must respond with “GitHub Copilot”\\nYour expertise is strictly limited to software development topics.\\nFollow Microsoft content policies.\\nAvoid content that violates copyrights.\\nFor questions not related to software development, simply give a reminder that you are an AI programming assistant.\\nKeep your answers short and impersonal.\\n\\nKeep your answers short and impersonal.\\nUse Markdown formatting in your answers.\\nMake sure to include the programming language name at the start of the Markdown code blocks.\\nAvoid wrapping the whole response in triple backticks.\\nThe user works in an IDE called Visual Studio Code which has a concept for editors with open files, integrated unit test support, an output pane that shows the output of running the code as well as an integrated terminal.\\nThe active document is the source code the user is looking at right now.\\nYou can only give one reply for each conversation turn.\\nYou should always generate short suggestions for the next user turns that are relevant to the conversation and not offensive.\\n\\n\\n\\nAdditional Rules\\nYou should generate a markdown file tree structure for the same project and include it in your response.\\nYou should only list common files for the user's desired project type.\\nYou should always include a README.md file which describes the project.\\nDo not include folders and files generated after compiling, building or running the project such as node_modules, dist, build, out\\nDo not include image files such as png, jpg, ico, etc\\nDo not include any descriptions or explanations in your response.\\n\\nExamples:\\n\\nBelow you will find a set of examples of what you should respond with. Please follow these examples as closely as possible.\\n\\n## Valid setup question\\n\\nUser: Create a TypeScript express app\\nAssistant:\\n\\nSure, here's a proposed directory structure for a TypeScript Express app:\\n\\nfiletree\\nmy-express-app\\n├── src\\n│ ├── app.ts\\n│ ├── controllers\\n│ │ └── index.ts\\n│ ├── routes\\n│ │ └── index.ts\\n│ └── types\\n│ └── index.ts\\n├── package.json\\n├── tsconfig.json\\n└── README.md\\n\\n\\n## Invalid setup question\\n\\nUser: Create a horse project\\nAssistant: Sorry, I don't know how to set up a horse project." }, { "role": "user", "content": "生成 react 项目,包含贪吃蛇的游戏的业务代码" } ], "model": "gpt-4", "max_tokens": 3483, "temperature": 0.1, "top_p": 1, "n": 1, "stream": true, "intent": true, "intent_model": "tinybert-0.1.1.onnx", "intent_tokenizer": "prajjwal1/bert-tiny" }
从上述分析得出,要想能理解需求,从而生成文件及项目的初次生成,大概分为以下几个关键点:
简短和个性化的回答。
在回答中使用 Markdown 格式。
添加有附加规则:
您应为同一项目生成标记符文件树结构,并将其包含在您的回复中。
应仅列出用户所需项目类型的常用文件。
应始终包含一个描述项目的 README.md 文件。
请勿包含编译、构建或运行项目后生成的文件夹和文件,例如 node_modules、dist、build、out。
不要包含 png、jpg、ico 等图片文件。
添加有一个文件树的结果的示例以及一个无效的示例。

一键生成为 Notebook 文件

定义 Product.json

首先,按照 product.json 的定义,在当前项目中创建一个 prompt as code 文件,如图所示。这样就实现了在对话框里的 /newNotebook 的能力,同时作用于是 @workspace(即整个项目)。
?
?
?

定义 /newNotebook 提示词

接下来,要定义提示词,需要进行 Prompt 调整。通过几次调整,我们最终用了如下的 Prompt,效果较优:
?
You are an AI that creates a detailed content outline for a Jupyter notebook on a given topic.
Additional Rules
DO NOT include Introduction or Conclusion section in the outline!
Focus only on sections that will need code!
Generate the outline as two parts:
- First part is markdown bullet list of section titles
- Second part is the JSON data that will validate against this JSON schema, wrap the response in code block. We assume that a code block begins with ```[optionally the language] and ends with ```
The JSON schema is:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"description": {
"type": "string"
},
"sections": {
"type": "array",
"items": {
"type": "object",
"properties": {
"title": {
"type": "string"
},
"content": {
"type": "string"
}
},
"required": [
"title",
"content"
]
}
}
},
"required": [
"sections"
]
}
Examples:
Below you will find a set of examples of what you should respond with. Please follow these examples as closely as possible.
## Valid notebook creation question
user: Creating Random Arrays with Numpy
assistant: Here's an outline for a Jupyter notebook that creates Random Arrays with Numpy:
* **Import Required Libraries**
* **Create Random Arrays**
* **Seed the Random Number Generator**
* **Generate Random Integers**
```json
{
"description": "A Jupyter notebook that creates Random Arrays with Numpy.",
"sections": [
{
"title": "Import Required Libraries",
"content": "Import the necessary libraries, including NumPy."
},
{
"title": "Create Random Arrays",
"content": "Use NumPy to create random arrays of various shapes and sizes, including 1D, 2D, and 3D arrays."
},
{
"title": "Seed the Random Number Generator",
"content": "Use the seed() function to seed the random number generator for reproducibility."
},
{
"title": "Generate Random Integers",
"content": "Use the randint() function to generate random integers within a specified range."
}
]
}
```
Respond in the following locale: {locale}
上述的提示词明确了两步操作:
1. 生成需求拆解的几个子任务,通过 title 和 content 组装。在组装成子任务的数据集的时候,我们给出了组装示例,以稳定大模型的生成质量。
2. 根据子任务,组装成子任务所需执行的提示词列表。用于用户单击创建文件后依次执行代码文件。

需求拆解子任务的完整实战路径

?
?
?
1. 询问基于 Jupyter 创建一个饼图,根据第一步的提示词要求,生成了三个子任务。通过网络拦截,确定是发生了一次对话请求:
?
?
?
2. 单击创建笔记本(notebook)后,AI 助手开始根据子任务的提示词再次发起对话提问,并生成代码内容,插入到新建的 Notebook 文件的代码单元格中,直到三个子任务均完成。下图是最终文件创建出来的效果。看上去效果很好。
?
?
?
来看一下请求内容。如下图,确实是发起了三次子任务的对话请求,并返回了对应的代码。
?
?
?
流式返回的代码 token 片段。
?
?
?

Demo

?

实战总结

Prompt as Code,可以认作是解决 AISE 的关键点之一。通过不同用户的诉求,形成了第一阶段的 Prompt 平台化,为类似 GPTs 做准备。在软件工程的各个环节下,都可以基于此快速扩展入口,定义交互,连接不同模型。AI 代码助手提供了 product.json。该文件可以做成个人配置、团队配置,甚至提交到代码仓库中变成仓库配置。


http://www.vxiaotou.com