发帖
 找回密码
 立即注册
搜索
0 0 0
技术交流 318 0 3 小时前

很多人尝试codex模型的第一反应该都是,这家伙怎么那么喜欢写脚本改代码啊???

我第一次用的时候也很迷惑,因为按道理来说openai不至于在gpt5的基础上训练出一个更弱智的模型,并且还放出来,并且还作为codex cli 0.40.0版本的默认模型。

所以我又去掏codex的源码了

也就是说codex模型和gpt5模型用的是不一样的system prompt

/// The `instructions` field in the payload sent to a model should always start
/// with this content.
const BASE_INSTRUCTIONS: &str = include_str!("../prompt.md");
const GPT_5_CODEX_INSTRUCTIONS: &str = include_str!("../gpt_5_codex_prompt.md");

并且由于codex模型没有设置 needs_special_apply_patch_instructions: true 所以也不会添加apply_patch的相关提示词

/// Returns a `ModelFamily` for the given model slug, or `None` if the slug
/// does not match any known model family.
pub fn find_family_for_model(slug: &str) -> Option<ModelFamily> {
    if slug.starts_with("codex-") || slug.starts_with("gpt-5-codex") {
        model_family!(
            slug, slug,
            supports_reasoning_summaries: true,
            reasoning_summary_format: ReasoningSummaryFormat::Experimental,
            base_instructions: GPT_5_CODEX_INSTRUCTIONS.to_string(),
        )
    } else if slug.starts_with("gpt-5") {
        model_family!(
            slug, "gpt-5",
            supports_reasoning_summaries: true,
            needs_special_apply_patch_instructions: true,
        )
    } else {
        None
    }
}

/// Detailed instructions for gpt-4.1 on how to use the `apply_patch` tool.
pub const APPLY_PATCH_TOOL_INSTRUCTIONS: &str = include_str!("../apply_patch_tool_instructions.md");

impl Prompt {
    pub(crate) fn get_full_instructions<'a>(&'a self, model: &'a ModelFamily) -> Cow<'a, str> {
        let base = self
            .base_instructions_override
            .as_deref()
            .unwrap_or(model.base_instructions.deref());
        // When there are no custom instructions, add apply_patch_tool_instructions if:
        // - the model needs special instructions (4.1)
        // AND
        // - there is no apply_patch tool present
        let is_apply_patch_tool_present = self.tools.iter().any(|tool| match tool {
            OpenAiTool::Function(f) => f.name == "apply_patch",
            OpenAiTool::Freeform(f) => f.name == "apply_patch",
            _ => false,
        });
        if self.base_instructions_override.is_none()
            && model.needs_special_apply_patch_instructions
            && !is_apply_patch_tool_present
        {
            Cow::Owned(format!("{base}\n{APPLY_PATCH_TOOL_INSTRUCTIONS}"))
        } else {
            Cow::Borrowed(base)
        }
    }

    pub(crate) fn get_formatted_input(&self) -> Vec<ResponseItem> {
        self.input.clone()
    }
}

而在这一篇中,我们提到过apply_patch就是codex用于修改文件的tool。

于是非常聪明的codex模型在发现没有可以用于修改文件的工具后,就开始了使用各种脚本进行修改文件的尝试,这就是开局提到的现象。

那么应该怎么解决呢,也很简单,我们把缺失的apply_patch提示词补上就可以了。

但问题是,openai官方为什么故意不添加apply_patch的提示词呢?

我的猜测是codex模型就是基于gpt5模型的coding数据sft出来的模型,所以openai很自信的认为已经不需要提示它使用apply_patch了,但结果很明显,codex模型根本不知道还有一个apply_patch工具被hook在了shell工具之中,导致tool定义里没有apply_patch的时候,是完全不知道可以使用apply_patch的。

更可能的原因是codex模型的测试集就没有在win上跑过,但是codex识别到环境是win,会倾向于使用pwsh命令,(比如就算我说明我安装了find sed等工具,新模型偶尔还是倾向于使用Get-Content命令,并且对于pwsh的反引号转义一窍不通),于是出错概率很大。

但我不想换linux,也不想跑wsl。 ::melting_face::
所以我下一篇可能会写怎么在git bash上跑

基于以上猜测,我们就可以不完全补上apply_patch的提示词了

# Text Editing Tools

When performing text editing, must use the `apply_patch` tool instead of running temporary scripts with Python commands to edit files (e.g `{"command":["apply_patch","*** Begin Patch\n*** Add File: test.txt\n+test\n*** End Patch\n"],"workdir":"<workdir>","justification":"Create file test.txt"}`)

只需要添加上apply_patch的调用例子,并且强调应该使用apply_patch进行文件修改,应该就和gpt5模型行为对齐了。

──── 0人觉得很赞 ────

使用道具 举报

刚出GPT5Codex的时候我就留意到了,没想到背后是这个原因呢。  
太强了,大佬!
待会儿上班的时候试试。请问大佬,这个跟默认的Python改文件相比,有什么优势呢?
您需要登录后才可以回帖 立即登录
高级模式