Skip to content

Commit 05feab8

Browse files
committed
增加文档
1 parent 94d97fa commit 05feab8

File tree

1 file changed

+362
-0
lines changed

1 file changed

+362
-0
lines changed

prompt/improvePrompt.txt

Lines changed: 362 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,362 @@
1+
2+
/**
3+
* 调用 DeepSeek API
4+
* @param userContent 用户输入内容
5+
* @param systemContent 系统提示内容
6+
* @param outputChannel 输出通道,用于实时显示流式内容
7+
* @param streamMode 是否启用流式模式
8+
* @param endstring 结束字符串,用于检查输出是否包含特定字符串
9+
* @param abortSignal 用于中断请求的信号
10+
* @returns API 返回的完整内容
11+
*/
12+
async function callDeepSeekApi(
13+
userContent: string,
14+
systemContent: string = 'You are a helpful assistant.',
15+
outputChannel?: vscode.OutputChannel,
16+
streamMode: boolean = true,
17+
endstring?: string,
18+
abortSignal?: AbortSignal
19+
): Promise<string | null> {
20+
const { modelName, apiBaseURL, apiKey } = getDeepSeekModelConfig();
21+
const userStopException = 'operation stop by user';
22+
23+
if (!apiKey) {
24+
vscode.window.showErrorMessage('DeepSeek API Key is not configured. Please set it in the settings.');
25+
return null;
26+
}
27+
28+
if (!modelName || !apiBaseURL) {
29+
vscode.window.showErrorMessage('DeepSeek Model Name or API Base URL is not configured.');
30+
return null;
31+
}
32+
33+
try {
34+
const openai = new OpenAI({
35+
apiKey: apiKey,
36+
baseURL: apiBaseURL,
37+
});
38+
39+
if (outputChannel) {
40+
outputChannel.clear();
41+
outputChannel.show();
42+
}
43+
44+
const messages_body: OpenAI.ChatCompletionMessageParam[] = [
45+
{ role: 'system', content: systemContent },
46+
{ role: 'user', content: userContent },
47+
];
48+
let fullResponse = '';
49+
let maxAttempts = 5;
50+
let attempts = 0;
51+
52+
vscode.window.showInformationMessage('开始上传DeepSeek API');
53+
54+
while (attempts < maxAttempts) {
55+
attempts++;
56+
const response = await openai.chat.completions.create({
57+
model: modelName,
58+
messages: messages_body,
59+
stream: streamMode,
60+
max_tokens: 8192,
61+
temperature: 0
62+
});
63+
64+
vscode.window.showInformationMessage('DeepSeek API 正在处理...');
65+
66+
let chunkResponse = '';
67+
let finishReason: string | null = null;
68+
69+
if (streamMode) {
70+
for await (const chunk of response as AsyncIterable<OpenAI.Chat.Completions.ChatCompletionChunk>) {
71+
if (abortSignal?.aborted) {
72+
throw new Error(userStopException);
73+
}
74+
const content = chunk.choices[0]?.delta?.content || '';
75+
chunkResponse += content;
76+
if (outputChannel) {
77+
outputChannel.append(content);
78+
}
79+
finishReason = chunk.choices[0]?.finish_reason || null;
80+
}
81+
} else {
82+
const completion = response as OpenAI.Chat.Completions.ChatCompletion;
83+
chunkResponse = completion.choices[0].message.content || "";
84+
finishReason = completion.choices[0].finish_reason || null;
85+
if (outputChannel) {
86+
outputChannel.append(chunkResponse);
87+
}
88+
}
89+
90+
// 累积完整响应
91+
fullResponse += chunkResponse;
92+
93+
// 检查终止条件
94+
const shouldContinue =
95+
finishReason === 'length' ||
96+
(endstring && !fullResponse.includes(endstring));
97+
98+
if (!shouldContinue) {break;};
99+
100+
if (abortSignal?.aborted) {
101+
throw new Error(userStopException);
102+
}
103+
104+
vscode.window.showWarningMessage('超过最大Token数,正在重试...');
105+
106+
// 准备下一次请求
107+
messages_body.push(
108+
{ role: 'assistant', content: fullResponse },
109+
{ role: 'user', content: '你的输出被截断了,请继续输出剩余部分, 不需要```做起始,直接继续输出纯内容:' }
110+
);
111+
}
112+
113+
// 最终检查
114+
if (endstring && !fullResponse.includes(endstring)) {
115+
vscode.window.showWarningMessage('响应未包含结束标记');
116+
}
117+
118+
messages_body.push({ role: 'assistant', content: fullResponse });
119+
lastMessageBody = messages_body;
120+
return fullResponse;
121+
122+
} catch (error) {
123+
if (error instanceof Error && error.message === userStopException) {
124+
vscode.window.showInformationMessage('operation stop by user');
125+
return null;
126+
}
127+
vscode.window.showErrorMessage('API调用失败: ' + (error as Error).message);
128+
return null;
129+
}
130+
}
131+
132+
export async function callDeepSeekFixApi(
133+
errorInfo: string,
134+
outputChannel?: vscode.OutputChannel,
135+
streamMode: boolean = true,
136+
abortSignal?: AbortSignal
137+
): Promise<string | null> {
138+
const { modelName, apiBaseURL, apiKey } = getDeepSeekModelConfig();
139+
const userStopException = 'operation stop by user';
140+
141+
if (!apiKey) {
142+
vscode.window.showErrorMessage('DeepSeek API Key is not configured. Please set it in the settings.');
143+
return null;
144+
}
145+
146+
if (!modelName || !apiBaseURL) {
147+
vscode.window.showErrorMessage('DeepSeek Model Name or API Base URL is not configured.');
148+
return null;
149+
}
150+
151+
const openai = new OpenAI({
152+
apiKey: apiKey,
153+
baseURL: apiBaseURL,
154+
});
155+
156+
if (outputChannel) {
157+
outputChannel.clear();
158+
outputChannel.show();
159+
}
160+
161+
let messages_body = lastMessageBody;
162+
163+
messages_body.push(
164+
{ role: 'user', content:`你以上提供的数据格式存在错误: ${errorInfo}。
165+
请你仔细检查数据,分析并找出所有错误原因,并核实错误类型。请按照下面的格式输出,要求如下:
166+
167+
【第一步:错误原因分析】
168+
请逐项列出所有错误原因,每项必须包括:
169+
1. 错误类型及原因描述(详细说明为何出错)
170+
2. 对应的文件路径(精确到文件)
171+
3. 错误的写法(直接引用错误代码,指明具体位置)
172+
4. 正确的写法(建议的修正代码,必须准确对应错误部分)
173+
174+
【第二步:最小改动修正】
175+
在保证原有正确部分完整保留的前提下,仅对错误部分做最小改动。要求:
176+
- 详细说明每处改动的理由
177+
- 列出每个文件修改的具体位置和修改内容,确保不遗漏任何正确部分
178+
179+
【第三步:完整输出】
180+
请输出最终修正后的完整数据,按照上一次要求的格式,严格输出。并注意:
181+
- 包含修正后的代码
182+
- 不要遗漏原有正确部分(完整输出,绝对不省略任何内容)
183+
184+
【第四步:总结说明】
185+
在输出完完整数据后,请总结以上步骤,归纳错误原因和修改方案,并确认所有文件路径及代码位置均正确无误。
186+
187+
请严格按照以上步骤输出,确保先详细列出错误原因,再输出完整修正后的数据,不要只输出错误部分。`}
188+
);
189+
190+
let fullResponse = '';
191+
let chunkResponse = '';
192+
let finishReason: string | null = null;
193+
194+
vscode.window.showInformationMessage('开始上传DeepSeek API, 进行修复');
195+
196+
const response = await openai.chat.completions.create({
197+
model: modelName,
198+
messages: messages_body,
199+
stream: streamMode,
200+
max_tokens: 8192,
201+
temperature: 0
202+
});
203+
204+
if (streamMode) {
205+
for await (const chunk of response as AsyncIterable<OpenAI.Chat.Completions.ChatCompletionChunk>) {
206+
if (abortSignal?.aborted) {
207+
throw new Error(userStopException);
208+
}
209+
const content = chunk.choices[0]?.delta?.content || '';
210+
chunkResponse += content;
211+
if (outputChannel) {
212+
outputChannel.append(content);
213+
}
214+
finishReason = chunk.choices[0]?.finish_reason || null;
215+
}
216+
} else {
217+
const completion = response as OpenAI.Chat.Completions.ChatCompletion;
218+
chunkResponse = completion.choices[0].message.content || "";
219+
finishReason = completion.choices[0].finish_reason || null;
220+
if (outputChannel) {
221+
outputChannel.append(chunkResponse);
222+
}
223+
}
224+
225+
fullResponse = chunkResponse;
226+
227+
messages_body.push({ role: 'assistant', content: fullResponse });
228+
lastMessageBody = messages_body;
229+
230+
return fullResponse;
231+
}
232+
233+
/**
234+
* 应用代码重构功能
235+
* @param cvbContent CVB 文件内容
236+
* @param userRequest 用户输入的重构需求
237+
* @param outputChannel 输出通道,用于实时显示流式内容
238+
* @param abortSignal 用于中断请求的信号
239+
* @returns API 返回的完整 CVB 内容
240+
*/
241+
export async function queryCodeReDesign(
242+
cvbContent: string,
243+
userRequest: string,
244+
outputChannel: vscode.OutputChannel,
245+
abortSignal?: AbortSignal
246+
): Promise<string | null> {
247+
const requestContent = `
248+
【格式说明】
249+
- CVB 格式说明:${Cvb.getFormatDescription()}
250+
- TCVB 格式说明:${TCVB.getFormatDescription()}
251+
252+
【任务说明】
253+
请读取以下 CVB 格式代码,并根据需求修改代码。注意:
254+
1. 如果需求涉及“移动代码”,请务必修改原始代码,将代码重新封装到新位置,而非简单复制;
255+
2. 修改后的代码必须完整、可执行,不能有任何省略;
256+
3. 输出内容必须严格遵守 TCVB 格式(仅正文部分含 TCVB 标记,其他地方如有 TCVB 开始或结束符需转义),以确保后续合并正确;
257+
4. 注意不要将某文件的修改内容误认为是其他文件,请一条一条列出具体修改项及对应文件路径。
258+
259+
【输出要求】
260+
1. 先输出你对需求及相关代码的理解,请按层级缩进列出笔记,便于整理思路;
261+
2. 再输出详细的方案大纲,格式如下:
262+
需求理解:
263+
264+
查询资料:
265+
列出每个关键修改点所在的文件路径
266+
修改方案:
267+
文件路径1:
268+
描述修改点,避免用大块代码,注意只输出关键修改,不要太长, 不要加载无用的上下文。不要输出没有改动部分的代码
269+
文件路径2:
270+
描述修改点,同上
271+
272+
最后检查:
273+
对以上输出的方案大纲进行反思,重新阅读输入代码,结合以上方案大纲,逐条检查有没有和原文对不上的地方。检查方案是否完备、文件路径是否正确,设计思路是否无误,如有问题请提出修正意见
274+
3. 请确保输出中既包含错误部分的修正说明,又完整保留原有正确部分,不得遗漏任何内容;
275+
4. 用最小改动实现需求目的。
276+
277+
【输入部分】
278+
- 输入代码:${cvbContent}
279+
- 需求描述:${userRequest}
280+
281+
【最终输出】
282+
请先输出思路与方案大纲,最后汇总输出符合 TCVB 格式的精确代码。
283+
`;
284+
285+
return callDeepSeekApi(requestContent, undefined, outputChannel, true, '## END_TCVB', abortSignal); // 添加结束字符串
286+
}
287+
288+
289+
class Cvb{
290+
public static getFormatDescription() : string
291+
{
292+
return `
293+
CVB 格式介绍:
294+
- 文件以 "## BEGIN_CVB" 开头,以 "## END_CVB" 结尾。
295+
- 元数据部分以 "## META" 开头,以 "## END_META" 结尾,包含用户需求和时间戳。
296+
- 每个文件以 "## FILE:文件路径" 开头,紧接着是 Markdown 格式的代码块,包含文件内容。
297+
- 多个文件按顺序拼接在一起。
298+
`;
299+
}
300+
}
301+
302+
class TCVB{
303+
304+
public static getFormatDescription() : string
305+
{
306+
return `
307+
TCVB 格式规范:
308+
309+
## BEGIN_TCVB
310+
[文件块1]
311+
[文件块2]
312+
...
313+
## END_TCVB
314+
315+
文件块格式:
316+
## FILE:<文件绝对路径>
317+
[操作1]
318+
[操作2]
319+
...
320+
321+
操作类型:
322+
323+
1. 全局替换操作(GLOBAL-REPLACE):
324+
## OPERATION:GLOBAL-REPLACE
325+
## OLD_CONTENT
326+
[markdown代码块:被全局替换的内容, 可以在需要被替换的文本前后包含一些上下文帮助精确替换,一般是上下各3行。不要太长,不要带太多不必要的上下文,因为输出越长就越可能出错导致匹配不上。总长度不要超过10行,尽量不要大块的替换代码,而是切成很多小块替换。]
327+
## NEW_CONTENT
328+
[markdown代码块:新内容]
329+
330+
2. 创建操作(CREATE):
331+
## OPERATION:CREATE
332+
[markdown代码块:直接跟正文内容,表示新文件的全部内容]
333+
334+
注意:
335+
1. 所有OPERATION操作以行为单位
336+
2. 一个'## FILE'下可以有多个'## OPERATION'
337+
3. 锚点为连续的多行内容:使用至少3行唯一文本作为锚点,用来标定范围,防止混淆(如果需要可以超过3行)
338+
4. [markdown代码块], 一定要用\`\`\` ... \`\`\` 包裹,仔细检查不要漏掉。
339+
5. 注意TCVB和CVB的区别。CVB是完整的内容,而TCVB是用来生成差量同步的,通过多个OPERATION去操作已有CVB合成新CVB
340+
6. 插入和删除操作都可以转化为替换操作
341+
7. 用来匹配的锚点必须和原文的格式完全一致,不能有缺失,不能丢弃注释。
342+
8. 注意不要丢失OPERATION而直接输出代码块
343+
9. 不要私自加入不必要的空行
344+
10.如果是在一个已有文件里插入大块代码,不应该用CREATE,而是用替换的方式插入
345+
`;
346+
}
347+
}
348+
}
349+
350+
读懂以上代码,帮我优化提示词
351+
需要让模型更准确的跟随
352+
实际使用queryCodeReDesign时发现,模型生成的代码会有以下几个问题
353+
1.搞错了函数所在的文件
354+
2.被替换的代码太长,其实只需要替换其中一小段,结果模型忘乎所以的几乎把一大半代码都输出当做替换串了
355+
3.输出的被替换串不准确,比如有些可有可无的;结尾,和原文不一致导致匹配失败
356+
4.一些原文里的缩进空格等会错误,导致匹配不准确
357+
5.有时候提前输出的方案里包含了部分代码,正式输出的时候会错觉的把这些代码当成原文的被替换串
358+
359+
360+
callDeepSeekFixApi 有以下问题:
361+
我提供给他一些错误描述,让他反思,结果他只是很敷衍的重复一些废话,比如:就是输入串不匹配。根本不去反思哪里不匹配,为什么会不匹配
362+
然后重新输出的字符串还是错的

0 commit comments

Comments
 (0)