☰
InternLM 对话格式(Chat Format)完全指南:面向工具调用与代码解释器的流式智能体协议
2026/10/6 12:09:08 网站建设 项目流程
  • 大模型
  • 人工智能
  • 基础模型
  • AI Agent

【免费下载链接】InternLM

Official release of InternLM series (InternLM, InternLM2, InternLM2.5, InternLM3).

项目地址:https://gitcode.com/gh_mirrors/in/InternLM
点击查看免费下载

InternLM2-Chat 引入了一套全新的对话格式,在 ChatML 三角色结构之上新增environment角色,以流式方式统一承载通用对话、工具调用(function call)与代码解释器(code interpreter)等智能体应用场景。本文以 chat/chat_format_zh-CN.md 为核心,完整剖析该格式的基本结构、词表 token 映射、工具调用与代码解释器的完整消息流,并结合本仓库中的 web_demo.py、streaming_inference.py 等源码与评测脚本,验证这套格式在真实推理链路中的落地方式。读完本文,你将能够手工拼接符合规范的 InternLM 多轮对话与工具调用历史,理解各特殊 token 的语义与 ID,并能在 Transformers、LMDeploy、Lagent 等框架中正确使用这套格式构建智能体应用。

一、为什么需要一套新的对话格式

InternLM2-Chat 采用全新对话格式,其核心目标有两个:

  1. 灵活支持更广泛的应用:包括工具调用(function call)、代码解释器、多插件协同等通用智能体(agent)场景;
  2. 避免用户输入攻击:通过严格的特殊 token 界定,防止用户输入内容被模型误解为指令或系统提示。

新格式与 ChatML 格式类似,但在system、user、assistant的基础上,新增了environment角色,用于承载来自运行环境(工具执行结果、代码执行输出)的反馈消息,从而支持通用的智能体应用。其中system、user、assistant三个角色与通用对话完全兼容,保证了同一套格式既能驱动复杂智能体,也能退化用于普通多轮对话。

二、基本结构:system / user / assistant 三角色

常规的对话结构包含system、user、assistant三个角色,多轮对话按如下格式拼接:

<|im_start|>system 你是书生浦语2,一个无害的人工智能助手<|im_end|> <|im_start|>user 你好呀<|im_end|> <|im_start|>assistant 你好,我是书生浦语,请问有什么可以帮助你的吗<|im_end|>

其中:

  • <|im_start|>充当每轮对话的开始符;
  • <|im_end|>充当当前轮对话的结束符;
  • 每轮对话一般以<|im_start|>role开头,以模型输出的<|im_end|>结尾;
  • role代表system、user、assistant和environment四种角色。

注:模型侧对对话历史的拼接逻辑可参考 InternLM2.5-Chat 在 Hugging Face 仓库中的modeling_internlm2.py实现(位于build_chat_input附近),其对历史消息按相同规则拼接并生成输入 token。

词表中的特殊 token 映射

目前 InternLM2-Chat 模型词表维护了如下映射关系,支撑完整功能:

特殊 token含义token ID
<|im_start|>每个角色对话的开始符92543
<|im_end|>每个角色对话的结束符92542
<|action_start|>模型调用外部工具(代码解释器或外部插件)的开始符92541
<|action_end|>模型调用外部插件的结束符92540
<|interpreter|>代码解释器92539
<|plugin|>外部插件(常规 tools)92538

这些 token ID 在实际推理代码中会被直接引用。例如 chat/web_demo.py 在调用generate_interactive时显式传入additional_eos_token_id=92542,即把<|im_end|>作为额外的停止符参与生成控制;agent/streaming_inference.py 则将<|action_end|>与<|im_end|>一并作为stop_words,确保模型在输出工具调用结束符后及时终止生成。由此可见,这些 ID 是推理链路中可编程依赖的稳定接口。

三、完整结构:面向通用智能体的流式格式

InternLM2-Chat 的完整对话格式在基本结构之上,还包含针对通用智能体的设计。其核心目的是采用流式格式,使得同一套格式在支持各种类插件拓展和智能体环境的同时,能够和通用对话兼容。

流式格式的含义是:模型并不是一次性输出「思考文字 + 工具调用 + 最终回答」,而是在生成过程中自然输出思考/回应文字,再以<|action_start|>触发工具调用,等待环境返回结果(以environment角色回填),随后继续生成下一段内容。整个对话历史呈现为「assistant 输出 → environment 反馈 → assistant 输出」的交替流,每一段都以<|im_end|>收尾。

四、工具调用(Function Call)

InternLM2-Chat 的通用工具调用支持多种格式(例如 ReAct),其中尤其推荐json 格式,以方便下游应用解析。一次完整的工具调用流程如下所示:

<|im_start|>system 你是书生浦语2,一个无害的人工智能助手<|im_end|> <|im_start|>system name=<|plugin|> [ { "name": "get_current_weather", "description": "Get the current weather in a given location", "parameters": { "type": "object", "properties": { "location": { "type": "string", "description": "The city and state, e.g. San Francisco, CA", }, "unit": {"type": "string"}, }, "required": ["location"], }, } ] <|im_end|> <|im_start|>user 我想了解今天上海的天气<|im_end|> <|im_start|>assistant 好的,我将为你查询上海的天气。<|action_start|><|plugin|> {"name": "get_current_weather", "parameters": {"location": "Shanghai"}}<|action_end|><|im_end|> <|im_start|>environment name=<|plugin|> {"temperature": 22}<|im_end|> <|im_start|>assistant 上海的天气是 22 摄氏度<|im_end|>

整个流程分为三步:

  1. 工具声明(system 角色):首先在系统提示中以 json 格式提供工具调用的格式和字段描述。内容以<|im_start|>system name=<|plugin|>\n开头、<|im_end|>结尾,name=<|plugin|>体现了这是来自工具的指令。InternLM2-Chat支持 system 角色对模型的提示和约束多次出现,所以示例中既能看到关于「无害助手」的对话要求,也能看到工具协议描述,二者共存于对话历史中。

  2. 模型流式调用工具(assistant 角色):模型接到用户指令后,会以流式的形式调用工具——先自然生成文字进行思考/回应用户,然后输出<|action_start|><|plugin|>。其中<|action_start|>表示要调用外部插件,<|plugin|>表示调用的是常规工具。随后模型输出 json 格式的工具调用内容({"name": "get_current_weather", "parameters": {"location": "Shanghai"}}),最后以<|action_end|>表示工具调用结束,并以<|im_end|>收尾本轮。

  3. 环境返回结果(environment 角色):系统执行工具后返回调用结果,消息以<|im_start|>environment name=<|plugin|>开头,表示这是来自环境关于工具调用的反馈,内容同样是 json 格式(如{"temperature": 22}),以<|im_end|>结尾。

工具执行完毕后,模型继续以 assistant 角色生成面向用户的最终回答(如「上海的天气是 22 摄氏度」),从而完成一个完整的功能闭环。

五、代码解释器(Code Interpreter)

InternLM2-Chat 支持使用代码解释器解决复杂数学问题和进行数据分析。整个调用流程与通用工具调用类似,区别在于工具标识与内容格式:

<|im_start|>system 你是书生浦语2,一个无害的人工智能助手<|im_end|> <|im_start|>system name=<|interpreter|> 你现在可以使用一个支持 Python 代码执行的 Jupyter 笔记本环境。只需向 python 发送代码,即可在这个有状态环境中进行运行。这个功能适用于: - 数据分析或处理(如数据操作和图形制作) - 复杂计算(如数学和物理问题) - 编程示例(用于理解编程概念或语言特性) - 文本处理和分析(包括文本分析和自然语言处理) - 机器学习和数据科学(模型训练和数据可视化展示) - 文件操作和数据导入(处理CSV、JSON等格式文件)<|im_end|> <|im_start|>user 请帮我对该数据集进行数据处理并可视化。 <|im_end|> <|im_start|>user name=file [{"path": "data.csv", size='10K'}]<|im_end|> <|im_start|>assistant 我已经帮您处理了数据并进行了可视化。 <|action_start|><|interpreter|> ```python import plotly.express as px import pandas as pd # Load the data into a pandas dataframe df = pd.read_csv('data.csv') # Create a scatter plot of rainfall vs wind direction fig = px.scatter(df, x='WindDir9am', y='Rainfall', color='WindDir3pm', labels={'WindDir9am': 'Wind Direction 9am', 'Rainfall': 'Rainfall', 'WindDir3pm': 'Wind Direction 3pm'}, title='Rainfall vs Wind Direction', template='plotly_dark', width=600, height=500) # Add a hover effect to show the date fig.update_traces(hovertemplate='<b>Date: %{text}</b><br>Wind Direction 9am: %{x}<br>Rainfall: %{y}<br>Wind Direction 3pm: %{marker.color}') # Show the plot fig.show() ```<|action_end|> <|im_end|> <|im_start|>environment name=<|interpreter|> image <|im_end|> <|im_start|>assistant 由于代码输出没有包含在这里,我无法提供具体的图表内容。但是,如果代码执行无误,它会显示一个极坐标图,其中包含两个填充区域,一个代表上午9点的风向与降雨量的关系,另一个代表下午3点的风向与降雨量的关系。每个方向上的值是根据提供的数据集计算得到的平均降雨量。图表应该有一个清晰的标题、图例,并且能够直观地比较不同风向下的降雨量。由于使用了暗色主题,图表的整体外观应该是深色背景上的亮色线条和填充区域。<|im_end|> <|im_start|>user 你能解释一下代码吗<|im_end|> <|im_start|>assistant 我使用的是Python的Plotly库来创建一个极坐标图,以展示风向与降雨量之间的关系。代码中首先创建了一个Plotly的Figure对象。接着,我添加了两个`Scatterpolar`追踪。第一个追踪展示的是上午9点的风向与降雨量的平均值的关系,第二个追踪展示的是下午3点的风向与降雨量的平均值的关系。在这两个追踪中,`r`参数代表降雨量的平均值,`theta`参数代表风向。`fill='toself'`表示图形以自身为边界进行填充。然后我更新了图表的布局,隐藏了径向轴,添加了图例,设置了标题和标题字体,选择了暗色主题,并设定了图表的背景色、宽度和高度。最后,使用`fig.show()`展示了图表。 <|im_end|>

该流程包含四个关键步骤:

  1. 能力声明(system 角色):在系统提示中提供代码解释器的格式和字段描述。内容以<|im_start|>system name=<|interpreter|>\n开头、<|im_end|>结尾,name=<|interpreter|>表明这是来自代码解释器的指令。与工具调用一样,该声明可与基础 system 提示并存。

  2. 文件上传(user 角色):用户可上传文件并对模型提出要求。文件上传以单独的消息形式发送给模型:以<|im_start|>user name=file开头,以 json 形式给出路径和文件大小(如[{"path": "data.csv", size='10K'}]),以<|im_end|>结尾。

  3. 模型生成代码(assistant 角色):模型接到用户指令后流式调用代码解释器,先自然生成文字,然后输出<|action_start|><|interpreter|>(<|action_start|>表示调用外部工具,<|interpreter|>表示选择代码解释器),随后输出markdown 风格的 python 代码块,最后以<|action_end|>表示代码块结束,并以<|im_end|>收尾。

  4. 环境执行并反馈(environment 角色):系统执行代码块中的代码,然后返回调用结果,以<|im_start|>environment name=<|interpreter|>开头,表示是来自环境关于代码解释器执行的输出,以<|im_end|>结尾。

值得注意的是,示例后续还展示了「用户追问代码含义 → 模型解释代码」的普通多轮对话,说明代码解释器调用结束之后,对话历史可以无缝回归普通对话格式。

六、同时使用工具和代码解释器

InternLM2-Chat 能够在一个对话过程中自主选择调用工具或代码解释器。在工具和代码解释器同时开启的情况下,只需将各自的系统提示合并在一起给模型即可,无需引入任何新的语法结构。合并后的 system 提示中既包含代码解释器的能力声明,也包含工具协议的 json 描述。一个同时调用工具和代码解释器的完整对话历史样例如下:

<|im_start|>system 你是书生浦语2,一个无害的人工智能助手<|im_end|> <|im_start|>system name=<|interpreter|> 你现在可以使用一个支持 Python 代码执行的 Jupyter 笔记本环境。只需向 python 发送代码,即可在这个有状态环境中进行运行。这个功能适用于: - 数据分析或处理(如数据操作和图形制作) - 复杂计算(如数学和物理问题) - 编程示例(用于理解编程概念或语言特性) - 文本处理和分析(包括文本分析和自然语言处理) - 机器学习和数据科学(模型训练和数据可视化展示) - 文件操作和数据导入(处理CSV、JSON等格式文件)<|im_end|> <|im_start|>system name=<|plugin|> [ { "name": "get_current_weather", "description": "Get the current weather in a given location", "parameters": { "type": "object", "properties": { "location": { "type": "string", "description": "The city and state, e.g. San Francisco, CA", }, "unit": {"type": "string"}, }, "required": ["location"], }, } ] <|im_end|> <|im_start|>user 请帮我对该数据集进行数据处理并可视化。 <|im_end|> <|im_start|>user name=file [{"path": "data.csv", size='10K'}]<|im_end|> <|im_start|>assistant 我已经帮您处理了数据并进行了可视化。 <|action_start|><|interpreter|> ```python import plotly.express as px import pandas as pd # Load the data into a pandas dataframe df = pd.read_csv('data.csv') # Create a scatter plot of rainfall vs wind direction fig = px.scatter(df, x='WindDir9am', y='Rainfall', color='WindDir3pm', labels={'WindDir9am': 'Wind Direction 9am', 'Rainfall': 'Rainfall', 'WindDir3pm': 'Wind Direction 3pm'}, title='Rainfall vs Wind Direction', template='plotly_dark', width=600, height=500) # Add a hover effect to show the date fig.update_traces(hovertemplate='<b>Date: %{text}</b><br>Wind Direction 9am: %{x}<br>Rainfall: %{y}<br>Wind Direction 3pm: %{marker.color}') # Show the plot fig.show() ```<|action_end|> <|im_end|> <|im_start|>environment name=<|interpreter|> image <|im_end|> <|im_start|>assistant 由于代码输出没有包含在这里,我无法提供具体的图表内容。但是,如果代码执行无误,它会显示一个极坐标图,其中包含两个填充区域,一个代表上午9点的风向与降雨量的关系,另一个代表下午3点的风向与降雨量的关系。每个方向上的值是根据提供的数据集计算得到的平均降雨量。图表应该有一个清晰的标题、图例,并且能够直观地比较不同风向下的降雨量。由于使用了暗色主题,图表的整体外观应该是深色背景上的亮色线条和填充区域。<|im_end|> <|im_start|>user 你能解释一下代码吗<|im_end|> <|im_start|>assistant 我使用的是Python的Plotly库来创建一个极坐标图,以展示风向与降雨量之间的关系。代码中首先创建了一个Plotly的Figure对象。接着,我添加了两个`Scatterpolar`追踪。第一个追踪展示的是上午9点的风向与降雨量的平均值的关系,第二个追踪展示的是下午3点的风向与降雨量的平均值的关系。在这两个追踪中,`r`参数代表降雨量的平均值,`theta`参数代表风向。`fill='toself'`表示图形以自身为边界进行填充。然后我更新了图表的布局,隐藏了径向轴,添加了图例,设置了标题和标题字体,选择了暗色主题,并设定了图表的背景色、宽度和高度。最后,使用`fig.show()`展示了图表。 <|im_end|> <|im_start|>user 我想了解今天上海的天气<|im_end|> <|im_start|>assistant 好的,我将为你查询上海的天气。<|action_start|><|plugin|> {"name": "get_current_weather", "parameters": {"location": "Shanghai"}}<|action_end|><|im_end|> <|im_start|>environment name=<|plugin|> {"temperature": 22}<|im_end|> <|im_start|>assistant 上海的天气是 22 摄氏度<|im_end|>

从中可以看出三个设计要点:

  • 多段 system 提示共存:基础身份提示、代码解释器声明、工具协议描述以多个<|im_start|>system ... <|im_end|>段依次排列,模型会对所有 system 提示一并遵循;
  • 自主决策工具类型:面对「数据处理与可视化」任务时模型选择了<|interpreter|>,面对「查询天气」任务时选择了<|plugin|>,说明模型能够根据任务类型在两种工具间自主切换;
  • 多轮工具调用不冲突:同一对话历史中先后完成代码解释器调用与插件调用,各自以独立的action_start/action_end与environment消息闭环,互不干扰,且穿插其中的普通问答(如「你能解释一下代码吗」)也完全符合格式规范。

七、源码印证:这套格式如何被真实使用

1. web_demo.py:手工拼接对话历史

chat/web_demo.py 是一个基于 Streamlit 的交互式对话示例(运行方式见 chat/README_zh-CN.md 的「通过前端网页对话」一节:pip install streamlit后执行streamlit run ./web_demo.py)。其中combine_history函数展示了与本文一致的拼接逻辑:

  • 定义了user_prompt = '<|im_start|>user\n{user}<|im_end|>\n'与robot_prompt = '<|im_start|>assistant\n{robot}<|im_end|>\n'模板(见 web_demo.py),每个角色消息严格以<|im_start|>开始、以<|im_end|>结束;
  • 最终 prompt 以<s><|im_start|>system\n{meta_instruction}<|im_end|>\n开头(见 web_demo.py),其中<s>为 BOS 标记,随后逐条拼接历史消息,最后附上当前用户查询与<|im_start|>assistant\n生成前缀;
  • 在生成阶段显式传入additional_eos_token_id=92542(即<|im_end|>的 token ID,见 web_demo.py),确保模型输出到<|im_end|>即停止本轮生成。

这与本文第三节描述的基本结构完全对应,是格式定义在真实推理代码中的直接落地。

2. streaming_inference.py:基于 Lagent 的代码解释器智能体评测

agent/streaming_inference.py 是仓库提供的 MATH 数学代码解释器评测脚本(详见 agent/README_zh-CN.md),它基于 Lagent 的Internlm2Agent、Internlm2Protocol构建智能体:

  • 在 init_agent 中,通过Internlm2Protocol(meta_prompt=None, interpreter_prompt=DEFAULT_PROMPT)注入代码解释器的 system 提示,并以IPythonInteractiveManager作为解释器执行器;
  • 其--stop_words参数默认值为['<|action_end|>', '<|im_end|>'](见 streaming_inference.py),与本文第五节的格式定义一致——<|action_end|>用于截断代码块,<|im_end|>用于截断整个消息轮次;
  • 评测输出的steps字段清晰体现了「language → tool → environment → language」的交替结构(见 agent/README_zh-CN.md 中的 jsonl 样例),其中tool消息承载AsyncIPythonInteractiveManager的command参数,environment消息则回填代码执行结果(如{x: -16, y: -4}),与本文的assistant → environment流式协议一一对应。

如需用 Lagent 手工搭建 ReAct 智能体,可参考 agent/lagent_zh-CN.md 中的示例:以HFTransformer('internlm/internlm2_5-7b-chat')初始化模型,再通过ActionExecutor(actions=[search_tool, python_interpreter])组合搜索与代码解释器工具,交给ReAct智能体驱动。

3. 推理与部署框架中的格式支持

  • Transformers / ModelScope:通过tokenizer.apply_chat_template(messages, tokenize=True, add_generation_prompt=True, return_tensors="pt")即可自动完成上述对话格式的拼接与 token 化,add_generation_prompt=True会在末尾自动追加<|im_start|>assistant\n生成前缀(示例见 chat/README_zh-CN.md);
  • LMDeploy:作为量化、推理与服务一体的部署工具,其pipeline("internlm/internlm2_5-7b-chat")可直接支持带工具调用的对话,也可通过lmdeploy serve api_server提供兼容 OpenAI 的 RESTful 接口(详见 chat/lmdeploy_zh_cn.md)。在 streaming_inference.py 中,LMDeploy 后端即通过INTERNLM2_META(Lagent 内置的 InternLM 消息模板)与TurbomindEngineConfig完成格式适配。

八、实践要点小结

  1. 起始符与结束符成对出现:每个角色消息都以<|im_start|>role开头、以<|im_end|>结尾;拼接对话历史时切勿遗漏结束符,否则模型可能无法正确解析角色边界;
  2. system提示可多段共存:基础身份提示、工具协议、代码解释器声明可以按任意顺序以多个 system 段给出,模型均会遵循;
  3. 工具调用协议固定:assistant 输出工具调用时必须以<|action_start|><|plugin|>或<|action_start|><|interpreter|>开头,以<|action_end|>结尾;工具/解释器结果必须以<|im_start|>environment name=<|plugin|>或<|im_start|>environment name=<|interpreter|>开头回填;
  4. 文件上传走user name=file消息:以 json 数组形式给出path与size字段,是独立的 user 消息;
  5. 停止符与 token ID 可编程使用:<|im_end|>(92542)与<|action_end|>(92540)可作为生成阶段的额外 EOS 或 stop words,确保流式生成及时终止,参考 web_demo.py 与 streaming_inference.py。

通过以上内容,你既可以手工编写 InternLM 的任意对话历史(普通对话、工具调用、代码解释器或混合场景),也能在 Transformers、LMDeploy、Lagent 等生态中准确理解与复现这套格式,为搭建可靠的智能体应用打下基础。

  • 大模型
  • 人工智能
  • 基础模型
  • AI Agent

【免费下载链接】InternLM

Official release of InternLM series (InternLM, InternLM2, InternLM2.5, InternLM3).

项目地址:https://gitcode.com/gh_mirrors/in/InternLM
点击查看免费下载
上一篇:QtNodes 数据流框架测试体系实战指南:基于 Catch2 的单元测试、信号验证与 UI 交互测试
下一篇:华硕ROG笔记本色彩发白修复教程:使用G-Helper恢复GameVisual配置文件

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询