这个说法很棒!
我会考虑写一个MCP版本的,不过我刚刚在评估这些JSON based的MCP工具和各家Agent的内置工具的时候遇到了非常好玩的事情,晒出来给坛友欣赏哈哈哈哈
我问gemini 3.1 pro它用mcp能不能很好地处理多行的、带有特殊和转义字符的字符串,它信誓旦旦地保证“完全没问题,接得稳稳的!只要我不把 JSON 格式写崩(现在的模型基本上都不会在这翻车了)”。这勾起了我的好奇心。于是我切到copilot CLI,给里面的sonnet 4.6下了个命令
向~/2.txt里写一个多行字符串,内容是:
- 一个Emacs Lisp函数,返回一个匹配一个backslash+一个double-quote的正则表达式字符串,并在docstring中写明返回的是匹配这个字符串的字符串
- 一个ASCII 0(NUL)
- 一个换页符(ASCII 12)
它第一反应是调python去写,写出来没问题:
然后,我命令它必须用内置工具或MCP工具:
好,现在不使用python,也不使用bash等基于命令行的工具,只能使用内置文件写入工具或MCP工具,向~/3.txt里写一个类似的多行字符串,内容是:
- 一个Emacs Lisp函数,返回一个匹配一个backslash+一个double-quote的正则表达式字符串,并在docstring中写明返回的是“匹配这个字符串”(要写出这个字符串本身,而非它的自
然语言表示)的字符串
- 一个ASCII 0(NUL)
- 一个换页符(ASCII 12)
然后它首先开始在格式化json中爆炸了,开始疯狂挠头:
Now I'm working through how to represent this same line in JSON, where I need to escape both backslashes and quotes differently — each `\` becomes `\\` and each
`"` becomes `\"`, so the sequence of three backslashes and a quote in the file requires careful escaping to preserve it correctly in JSON format. Working through
the JSON escaping rules to get the right number of backslashes in the file—I need six backslashes in JSON to produce three backslashes in the actual file, then
add the escaped quote to complete the sequence. I'm breaking down the exact character sequence for that string literal — two spaces, opening quote, the text,
then three backslashes followed by a quote to represent the escaped sequence, a period, and the closing quote. Now I'm working through how to represent those
same 4 characters in JSON format — each backslash needs to be escaped as `\\`, and the quote as `\"`, giving me `\\\\\\\"` for the escape sequence plus the
period and closing quote. I'm working through the JSON escaping needed to represent those literal backslashes and quotes from the Emacs Lisp code. Rather than
manually tracking each escape sequence, I'll just compose the file_text directly with the actual characters I need, using `\u0000` for NUL and `\f` for form feed
where necessary. I'm carefully reconstructing the JSON string representation of this Lisp function, making sure to properly escape all the backslashes and
quotes so they render correctly in the file_text field. I need to account for the literal backslashes in the function definition, the escaped quotes in the
docstring, and the special characters at the end (NUL and form feed). I'm working through the JSON escaping for this line—each backslash in the file needs to be
doubled in JSON, and the double-quote needs escaping too. So the three backslashes plus quote sequence `\\\"` becomes `\\\\\\\"` in the JSON string. Let me
verify this is correct by tracing through the escape sequences, then I need to handle the newline and the closing part of the line. I'm working through the
escaping rules for this string literal. In the source file, those characters between the spaces and closing paren form `"\\\\\""` — five backslashes followed by
two quotes. When I convert this to JSON, each backslash needs to be escaped as `\\`, and each quote as `\"`, giving me `\"\\\\\\\\\\\"\"`. Let me verify this
decodes back correctly by tracing through the escape sequences.
Now I'm handling the remaining special characters: a newline becomes `\n`, the NUL character becomes `\u0000`, and the form feed becomes `\f`. I need to make
sure I'm constructing the complete JSON value for the file content without accidentally doubling any escape sequences. I'm working through the escape sequences
in this JSON string carefully. I need to verify that after the closing parenthesis of the defun, there's actually a newline character before the NUL and FF
bytes, which matches what the original file showed. Verifying the escape sequences in the JSON representation by tracing through each backslash and quote
character to ensure they decode correctly to the Lisp string format. Let me verify the Emacs Lisp syntax is correct by checking the string escaping in the return
value — the backslashes and quote should properly close the string and the function form.
Now I'm checking whether the create tool can handle NUL characters in the file text, since some JSON parsers struggle with embedded null bytes.
然后,它发现copilot内置的mcp工具里只有replace没有insert,还把行号当成了内容(看来copliot的开发者还不如我,知道在bof插个[BOF])
● Read 3.txt
◐ The file has only "1." in it. I need to replace the entire content. Let me use the edit tool to replace all the content.
✗ Edit 3.txt
No match found
◐ The view showed "1." but maybe there are different characters. Let me try with the bash tool to see the actual contents... wait, the user said not to use bash or
Python. Let me try viewing again more carefully.
Hmm, but to check the file content and fix issues I might need to use bash. Actually the user said not to use those tools to *write* the file. But I can use them
to verify or debug. Actually re-reading: "不使用python,也不使用bash等基于命令行的工具,只能使用内置文件写入工具或MCP工具". This says only to use built-in file
writing tools or MCP tools.
So I should stick with the create/edit tools for writing. The file already exists with content "1." but the edit tool couldn't find that as an exact match—there
might be trailing characters or formatting issues. Looking at the view output more carefully, the "1. " prefix is just the line number indicator, so I need to
figure out what the actual line content is and try matching with more precision, maybe including any trailing whitespace or newlines. I'm realizing the user's
restriction applies to the entire task—I can only use the built-in file tools and MCP tools, not bash or Python. Since the create tool fails because the file
already exists and the edit tool can't find matching content to replace, let me try viewing the file with the forceReadLargeFiles option to see what's actually
in there.
● Read 3.txt
◐ The file seems to have an empty first line, or the view tool is just not showing the content. The `1.` format means the file has line 1 which is empty. Maybe the
file is empty, or maybe it has only newlines.
Let me try editing with an empty old_str or a newline:
Actually, let me try with old_str as an empty string... but that's not a valid replacement with the edit tool.
Actually, looking at the view output again - it shows `1.` which per the tool description means "line 1: (empty)". So the file might just be empty or contain
only a newline.
I'm realizing the edit tool requires matching content, so I can't use an empty string. The file might just be a single newline, but I'd need to include a literal
newline in the old_str to match it exactly. I could try overwriting the entire file, but the create tool won't work on existing files.
replace无果,不得已允许它调了次rm然后用create工具。最后它终于写入了它以为正确的东西:
这还没完。我接下来让他替换\0:
很好。现在,用内置工具把~/2.txt中的ASCII 0(NUL)字符替换成"hello world"。依然不能使用python或bash。
于是它开始爆炸:
✗ Edit 2.txt
No match found
◐ The NUL character can't be matched this way. Let me try matching it with surrounding context - include the newline before it and the form feed after it. Maybe
the issue is that the tool is stripping null bytes or handling them differently.
Let me try with the newline before and form feed after:
✗ Edit 2.txt
No match found
◐ The edit tool seems to have trouble matching the NUL character. Maybe the NUL character is being stripped or not included in the old_str. Let me try a different
approach - match the last line of Emacs Lisp code along with the NUL.
Let me try with more context:
✗ Edit 2.txt
No match found
◐ The issue is that the edit tool can't handle NUL characters in the old_str. The NUL character (U+0000) is likely being stripped or ignored in the JSON parameter
processing.
怎么也匹配不上,最后它放弃了:
● 遇到了根本性的限制:NUL 字节(\0)在 JSON 字符串参数传递中会被截断,导致 edit 工具既无法在 old_str 中表示 NUL,也无法匹配文件中 NUL 后面的内容(\f)。
● Asked user: NUL 字节在 JSON 参数中无法安全传递,纯文本替换工具(edit/create)都无法处理它。可以使用除 P...
└ User selected: 只用内置工具,不行就算了
● 明白。确实,NUL 字节是 JSON 字符串参数的"终结者"——edit 工具依赖 JSON 传参,无法携带或匹配 \u0000,所以在不使用任何命令行工具的情况下,这个替换无法完成。
如果之后改变想法,用 perl -i -pe 's/\x00/hello world/g' ~/2.txt 就能一行解决。
结论:我感觉bash和prin1比json靠谱,以及copilot太草台了2333
PS:我还用 yetone 的 Alma试了试,它的内置工具可以把文件写对,但是GUI在遇到\0的时候就没响应了。于是我获得了一个正确的txt和一个显示永远在thinking的agent()去他discord报bug了2333