MCPcopy Create free account
hub / github.com/Rfym21/Qwen2API / buildToolSystemPrompt

Function buildToolSystemPrompt

src/utils/tool-prompt.js:81–131  ·  view source on GitHub ↗
(tools, options = {})

Source from the content-addressed store, hash-verified

79// 两个头都认:方括号是规范形式,尖括号是模型 RL 惯性下仍可能吐出的旧原生形式。
80// 旧形式被平台拦截时我们本来就收不到;漏网的那些照旧回收。
81//
82// 这里**不**用否定环视去甩掉 `[tool calls](url)` 这类 Markdown 链接:环视要往后看几十个字符,
83// 而流式解析器在 chunk 边界上看到的是半截 `[tool calls]`('(' 还没到),环视据此提前放行,
84// 于是整段和流式两条路径对同一输入给出不同结果 —— 分歧比误报本身更糟。改为在**定界点**判断
85// (isMarkdownLinkTail),那时两条路径都已经拿到了触发器到负载之间的完整 tail。
86const TOOL_CALL_TRIGGER_RE = /<[ \t]{0,4}tool_calls?|\[[ \t]{0,4}tool[ \t_-]{1,2}calls?/i;
87
88// 触发器到负载之间允许的最大间隔。中位数 3、最大 49、128 上界 —— 这些数字全部量自
89// **尖括号**语料(149 段抓包),方括号形式还没有对应的语料。沿用是合理默认:方括号是
90// 我们自己教给模型、要求写干净的形式,装饰理应更少而不是更多。真要偏离,得先抓一批
91// [TOOL CALL] 的真实输出再调,别凭感觉动这个 128。
92const TOOL_CALL_PAYLOAD_WINDOW = 128;
93
94/** 触发器能匹配到的最长文本,用作 chunk 边界暂存区的上界。取两种形式里更长的那个。 */
95const TOOL_CALL_TRIGGER_MAX = Math.max(
96 '< tool_calls'.length,
97 '[ tool calls'.length
98);
99
100/**
101 * 闭标签同样会被写坏(`</tool_call">`、`</tool_call result>`),而且常和开标签不对称。
102 * 它不携带任何信息,唯一的用处是别把它当正文吐出去,所以只用来**吞掉**,并且有上界。
103 */
104// 闭标签也会被写坏:`</tool_call">`、`</tool_call\n>`、`</tool_call result>`、
105// `</tool_call_id_1>`、`</tool_call>`(中文输入法的全角尖括号)。
106//
107// 尾巴必须收得很紧。之前用 `[^<>>]{0,64}` 太松:`</tool_call and then 5 > 3` 里那个 '>'
108// 让它一口吞掉 24 个字符的**真实回答**。现在只允许「一段不含空白的碎片 + 至多一个单词」,
109// 多词散文因此匹配不上,宁可让闭标签泄漏,也绝不吃掉模型的回答。
110const TOOL_CALL_CLOSE_RE =
111 /^<[ \t]{0,4}\/[ \t]{0,4}tool_calls?[^\s<>>]{0,16}[ \t\r\n]{0,4}(?:[A-Za-z_][\w-]{0,15})?[ \t\r\n]{0,4}[>>]/i;
112const TOOL_CALL_CLOSE_BARE_RE = /^<[ \t]{0,4}\/[ \t]{0,4}tool_calls?/i;
113// 方括号闭标记:`[END TOOL CALL]` 是规范形式,`[/TOOL CALL]` 是可预期的变体。
114// 与尖括号闭标签同一条纪律:只用来吞掉、有上界、多词散文匹配不上。
115// `[TOOL RESULT: …]` 既没有 END 也没有 '/',按构造匹配不上 —— 模型伪造的结果块
116// 不会被当成闭标记吃掉。
117// 装饰段同时排除 '[' 和 ']':consumeTrailingCloser 的 grow 判据把内部的 '['
118// 当成"这段永远成不了闭标记"的证据(`!slice.includes('[', 1)`),正则这一半也必须认同,
119// 否则 `[END TOOL CALL[[[]` 在正则里算闭标记、在 grow 判据里不算,两半自相矛盾。
120//
121// **序号臂**(`#3`)。foldToolMessages 把历史里的调用块写成 `[TOOL CALL #n]`,模型每一轮
122// 都读得到它,而这个文件的开头就写着"模型几乎每次都把标签写坏"、以及当年它正是从读到的
123// 形状里学会了 `<tool_call_id_1>` 那一族。镜像回一个 `[END TOOL CALL #3]` 是最自然的模仿,
124// 而装饰段 `[^\s[\]]{0,16}` **排除空白**,跨不过 '#' 前面那个空格:实测 `[END TOOL CALL#7]`
125// 认得出来,`[END TOOL CALL #7]`(正是我们教出去的那个空格)认不出来 —— 闭标记原样交付给
126// 客户端,stripToolCallResidue 没有 span 可删(交付层绝无第二套扫描),
127// containsOrphanProtocolResidue 也返回 false,连 malformed_protocol 重试都不会触发。
128// 所以这里只放宽到**一段数字**:空白 + '#' + 一串数字,绝不认单词。放数字进来不会咬到
129// 回答(散文里不会出现 `[END TOOL CALL #12]`;`[END TOOL CALL #3 我的回答]` 里序号之后
130// 不是 ']',整条仍然匹配不上,回答完好),放单词进来会(见 :103-105 的纪律:宁可漏出
131// 闭标记,也绝不吃掉模型的回答)。位数取 6 而不是 4:这个上界唯一的失效方式是
132// foldToolMessages 的序号涨过它 —— 那正是本次修的这个静默泄漏,宁可给足余量;而多几位
133// 数字对"吃掉回答"的风险恰好是零。序号里既没有 '[' 也没有 ']',与上面 grow 判据的那条
134// 约定仍然一致。裸臂必须**同步**放宽:流尾停在 `[END TOOL CALL #3`(少一个 ']')时,

Callers 2

buildInternalRequestFunction · 0.85
processRequestBodyFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected