Python——Jinja2模板引擎


整体说明

  • Jinja2 是一个功能强大的 Python 模板引擎,广泛广泛用于 Web 开发(如 Flask、Django 可集成)和文档生成等场景
  • 注:Jinja 和 Jinja2 实际上是同一个模板引擎的不同版本,Jinja2 是 Jinja 的升级版本,它们在模板语法格式上大部分是兼容的,但也存在一些差异和改进
  • 本文主要以 Jinja2 为主介绍简单的使用方法
  • Jinja2 是 Python 的库,安装 Jinja2 库使用 pip 即可:
    1
    pip install jinja2

Jinja2 基本概念介绍

  • 模板(Template) :包含固定内容和动态变量/逻辑的 Text 文件(如 HTML、TXT 等)
  • 变量(Variables) :模板中需要动态替换的值,用 {{ 变量名 }} 表示
  • 控制结构 :用于实现条件判断、循环等逻辑,用 {% 代码 %} 表示
  • 过滤器(Filters) :对变量进行处理(如格式化、转换),用 {{ 变量|过滤器 }} 表示
  • 模板继承 :通过 extendsblock 实现模板复用
  • 语句分隔符 :用来包裹“控制语句”的那对标记符号,告诉模板引擎“这里不是普通文本,而是一条要执行的指令”;Jinja2 默认的语句分隔符是:
    • 语句块(for / if / set / macro …):开始 {%` 结束 `%}
    • 变量输出(把值打印到页面):开始 {{ 变量 }}
    • 注释 :开始 ``

Jinja2 基础语法介绍

变量定义及相关操作

  • 在 Jinja2 中,定义变量可以使用 {% set %} 标签,基本语法和用法总结:
    • 基础变量用 {% set 变量名 = 值 %} 定义
    • 需在循环中修改的变量,用 namespace 命名空间
    • 变量通过 {{ 变量名 }} 输出,支持列表、字典等复杂类型
    • 实际开发中,变量更多从外部(如 Python 代码)传递到模板
基本变量定义
  • 使用 {% set 变量名 = 值 %} 格式定义变量:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {# 定义字符串变量 #}
    {% set name = "Jinja2" %}

    {# 定义数字变量 #}
    {% set version = 2 %}

    {# 定义布尔值变量 #}
    {% set is_active = true %}

    {# 定义列表变量 #}
    {% set fruits = ["apple", "banana", "cherry"] %}

    {# 定义字典变量 #}
    {% set user = {"name": "Alice", "age": 30} %}
使用变量
  • 定义后可以用 {{ 变量名 }} 输出变量值,或在控制结构中使用:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <p>名称:{{ name }}</p>
    <p>版本:{{ version }}</p>

    {# 列表遍历 #}
    <ul>
    {% for fruit in fruits %}
    <li>{{ fruit }}</li>
    {% endfor %}
    </ul>

    {# 字典取值 #}
    <p>用户名:{{ user.name }}</p> {# 或 user["name"] #}
命名空间(namespace)变量
  • 如果需要在循环或嵌套结构中修改变量值 ,普通变量无法直接生效,需使用 namespace 命名空间:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    {# 定义命名空间变量 #}
    {% set ns = namespace(total=0) %}

    {# 在循环中修改命名空间变量 #}
    {% for num in [1, 2, 3, 4] %}
    {% set ns.total = ns.total + num %}
    {% endfor %}

    <p>总和:{{ ns.total }}</p> {# 输出:总和:10 #}
  • 普通变量在循环中修改会被重置(作用域限制),而命名空间变量可以跨循环保持状态

变量作用域说明
  • 变量默认在定义它的模板块(block)或宏(macro) 内有效
  • 全局变量可在父模板定义,子模板通过 {{ 变量名 }} 直接使用(需确保变量已传递到子模板)
从外部传递变量
  • 实际开发中,变量通常从 Python 代码中传递到模板,而非在模板内定义:
    1
    2
    3
    4
    5
    6
    # Python 代码
    from jinja2 import Template

    template = Template("Hello, {{ name }}!")
    result = template.render(name="World") # 传递变量 name
    print(result) # 输出:Hello, World!

注释

  • 用 `` 表示,渲染时会被忽略:
    1
    2
    {# 这是一段注释,不会被渲染 #}
    <p>{{ content }}</p>

变量输出

  • {{ 变量名 }} 输出变量,支持嵌套结构(如字典、对象属性):

    1
    2
    3
    4
    <!-- 模板示例 -->
    <h1>{{ title }}</h1>
    <p>作者:{{ author.name }}</p>
    <p>年龄:{{ author.age }}</p>
  • 在 Python 中渲染:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    from jinja2 import Template

    # 定义模板内容
    template_str = """
    <h1>{{ title }}</h1>
    <p>作者:{{ author.name }}</p>
    <p>年龄:{{ author.age }}</p>
    """

    # 定义变量
    data = {
    "title": "Jinja2 教程",
    "author": {"name": "张三", "age": 30}
    }

    # 渲染模板
    template = Template(template_str)
    result = template.render(**data)
    print(result)

    # <h1>Jinja2 教程</h1>
    # <p>作者:张三</p>
    # <p>年龄:30</p>

控制结构

条件判断(if-elif-else
  • 用于实现条件判断,仅执行符合条件的分支
    1
    2
    3
    4
    5
    6
    7
    {% if score >= 90 %}
    <p>优秀</p>
    {% elif score >= 60 %}
    <p>及格</p>
    {% else %}
    <p>不及格</p>
    {% endif %}
循环(for
  • 用于遍历列表、字典等可迭代对象,支持 loop 辅助变量(如索引、是否为第一个元素):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <ul>
    {% for item in items %}
    <li>
    {{ loop.index }}. {{ item.name }} - {{ item.price }}元
    {% if loop.first %}(第一个){% endif %}
    {% if loop.last %}(最后一个){% endif %}
    </li>
    {% else %}
    <li>暂无数据</li> <!-- 当列表为空时执行 -->
    {% endfor %}
    </ul>
  • loop 不需要定义即可使用,是 jinja2 新给的 feature

  • loop 常用属性:

    • loop.index:当前迭代序号(从 1 开始)
    • loop.index0:当前迭代序号(从 0 开始)
    • loop.first:是否为第一个元素(布尔值)
    • loop.last:是否为最后一个元素(布尔值)

过滤器(Filters)

  • 对变量进行处理,格式为 {{ 变量|过滤器(参数) }} 。常用过滤器:
    过滤器 作用 示例
    upper 转为大写 {{ name|upper }}
    lower 转为小写 {{ name|lower }}
    capitalize 首字母大写 {{ name|capitalize }}
    length 获取长度 {{ list|length }}
    join 列表拼接为字符串 {{ list|join(', ') }}
    default 变量不存在时使用默认值 {{ value|default('暂无') }}
    date 日期格式化(需传入 datetime) {{ now|date('%Y-%m-%d') }}
  • 示例:
    1
    2
    3
    <p>姓名(大写):{{ name|upper }}</p>
    <p>列表长度:{{ items|length }}</p>
    <p>列表拼接:{{ items|join('、') }}</p>

模板继承(重要功能)

  • 通过继承可以复用模板中的公共部分(如页面头部、底部),核心是 extendsblock

  • 父模板(base.html) :定义公共结构和可替换的块(block

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>{% block title %}默认标题{% endblock %}</title>
    </head>
    <body>
    <header>公共头部</header>

    <main>
    {% block content %}{% endblock %} <!-- 子模板替换这里 -->
    </main>

    <footer>公共底部</footer>
    </body>
    </html>
  • 子模板(page.html) :继承父模板并替换块

    1
    2
    3
    4
    5
    6
    7
    8
    {% extends "base.html" %}  <!-- 继承父模板 -->

    {% block title %}首页{% endblock %} <!-- 替换标题块 -->

    {% block content %} <!-- 替换内容块 -->
    <h1>这是首页内容</h1>
    <p>欢迎访问</p>
    {% endblock %}

加载外部模板文件

  • 实际开发中,模板通常存放在文件中(而非字符串),可通过 FileSystemLoader 加载:

  • 目录结构:

    1
    2
    3
    4
    5
    project/
    ├── templates/
    │ ├── base.html # 父模板
    │ └── page.html # 子模板
    └── app.py # 主程序
  • Python 代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    from jinja2 import Environment, FileSystemLoader

    # 配置模板目录
    env = Environment(loader=FileSystemLoader('templates'))

    # 加载并渲染子模板
    template = env.get_template('page.html')
    result = template.render() # 可传入变量,如 render(title="首页")
    print(result)

常用高级功能

  • 宏(Macro) :类似函数,用于复用代码片段:

    1
    2
    3
    4
    5
    6
    7
    {% macro input(name, value='', type='text') %}
    <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
    {% endmacro %}

    <!-- 使用宏 -->
    {{ input('username') }}
    {{ input('password', type='password') }}
  • 包含(Include) :引入其他模板片段:

    1
    2
    <!-- 引入导航栏模板 -->
    {% include "navbar.html" %}
  • 自动转义 :默认开启(防止 XSS 攻击),可通过 autoescape 控制:

    1
    2
    3
    {% autoescape off %}
    {{ html_content }} <!-- 不转义,直接渲染HTML -->
    {% endautoescape %}

空白控制符

  • 在原有标签格式上加入 - 可以控制空白控制符
  • 当需要精确控制输出格式(如避免多余空行、压缩 HTML)时,使用带减号的形式
  • 对格式要求不严格时,使用默认形式更简洁
  • 减号仅影响空白字符,不改变标签的逻辑功能(如循环、条件判断等)
  • 最佳实践:一般建议都加上 {%- %} 来使用,格式更美观

控制结构中的空白控制符

  • {% %} (默认形式) :标签不会影响其前后的空白字符(空格、换行、制表符等)。例如:

    1
    2
    3
    4
    5
    <ul>
    {% for item in [0,1] %}
    <li>{{ item }}</li>
    {% endfor %}
    </ul>
    • 渲染后会保留循环标签前后的换行和缩进,可能产生多余空白:
      1
      2
      3
      4
      5
      6
      7
      <ul>

      <li>0</li>

      <li>1</li>

      </ul>
  • {%- %} (带减号的形式) :减号会移除标签一侧的空白字符(具体取决于减号的位置):

    • {%- ... %} :移除标签左侧(前面)的空白

    • {% ... -%} :移除标签右侧(后面)的空白

    • {%- ... -%} :同时移除标签两侧的空白

    • 例如,优化上面的循环:

      1
      2
      3
      4
      5
      <ul>
      {%- for item in items %}
      <li>{{ item }}</li>
      {%- endfor %}
      </ul>
      • 渲染后空白更紧凑:
        1
        2
        3
        4
        <ul>
        <li>0</li>
        <li>1</li>
        </ul>

变量输出中的空白控制符

  • {{ var }} 正常输出,不做额外处理

  • {{- var }} {{ var -}} {{- var -}} 同样可以用连字符 -把变量前面或后面的空白吃掉

  • 举例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    from jinja2 import Template

    template_str = """
    {% set name = 'wo' %}
    <p> {{- name -}} </p>
    <p> {{ name }} </p>
    """

    template = Template(template_str)
    result = template.render()
    print(result)

    # <p>wo</p>
    # <p> wo </p>
  • 一句话:

    • - 就是“吃掉这条标签前/后的空白”,写在左边 ( {%- / {{-) 吃前面,写在右边 (-%} / -}} ) 吃后面

字符串连接符

  • ~字符串连接运算符 ,用于将左右两边的元素拼接成一个字符串

  • ~ 作用类似于 Python 中的 + 运算符,但更灵活:

    • 会自动将非字符串类型(如变量、数字等)转换为字符串后再拼接
    • 不会像 + 那样在两边添加额外空格
    • 如果使用 + 运算符,需要确保两边都是字符串类型,而 ~ 则会自动处理类型转换,在模板中更常用
  • 以常见代码为例:

    1
    {{- "\nthinking_budget: < " ~ thinking_budget ~ "."}}
  • 这里的两个 ~ 会将三个部分拼接成一个完整字符串:

    • 1)"\nthinking_budget: < "(字符串字面量)
    • 2)thinking_budget(变量,会被转换为字符串)
    • 3)"."(字符串字面量)
  • 假设 thinking_budget 的值是 100,最终结果会是:

    1
    thinking_budget: < 100.

附录:补充示例(LongCat-Flash-Chat更详细一些)

  • 以美团开源的 LongCat-Flash-Chat/blob/main/tokenizer_config.json 为例,以下是格式化后的 chat_template Jinja2 代码及其逐行解释:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    {# 设置工具选择变量,默认值为'auto' #}
    {%- set tool_choice = tool_choice | default('auto') %}

    {# 创建命名空间变量,用于存储循环计数、工具类型和最后查询索引 #}
    {%- set ns = namespace(rounds = 0, tool_types = [], last_query_index = -1) %}


    {# 如果存在工具且工具选择不是'none',则输出工具相关信息 #}
    {%- if tools and tool_choice != 'none' %}
    {{- "# Tools\n" }}
    {{- "You have access to the following tools: \n\n" }}

    {# 遍历所有工具 #}
    {%- for tool in tools %}
    {# 只处理代码解释器和函数类型的工具 #}
    {%- if tool.type in ['code_interpreter', 'function'] %}
    {# 如果是新类型的工具,输出工具命名空间 #}
    {%- if tool.type not in ns.tool_types %}
    {%- set ns.tool_types = ns.tool_types + [tool.type] %}
    {{- "## Tool namespace: " ~ tool.type ~ "\n\n" }}
    {%- endif %}

    {# 如果是代码解释器工具,重新定义其配置 #}
    {%- if tool.type == 'code_interpreter' %}
    {%- set tool = {
    "type": "code_interpreter",
    "function": {
    "name": "code_interpreter_preview",
    "description": "The code will be executed in a stateful Jupyter notebook sandbox environment, only supports local computation, data processing, and file operations. \nCode sandbox environment (network isolated) Any external network requests or online API calls are prohibited. \nIf online functionality is needed, please use other permitted tools. \nCode will respond with the output of the execution or time out after 60.0 seconds. ",
    "parameters": {
    "type": "object",
    "properties": {
    "language": {
    "type": "string",
    "description": "The programming language of the code to be executed. Available values: python (Default), java, go, js, ts, c, c++."
    },
    "code": {
    "type": "string",
    "description": "Python code to be executed must not include the following:\n- Importing network libraries such as requests, httplib, etc.\n- Any form of HTTP requests.\n- External API calls.\n- Network port operations. Example: ```python\nimport pandas as pd\npd.DataFrame({'A':[1,2]})\n```"
    },
    "timeout": {
    "type": "number",
    "description": "The maximum execution time of the code, in seconds. Default is 60.0."
    }
    }
    },
    "required": ["code"]
    }
    } %}
    {%- endif %}

    {# 输出工具名称、描述和输入 schema #}
    {{- "### Tool name: " + tool.function.name + "\n\n" }}
    {{- "Description: " + tool.function.description + "\n\n" }}
    {{- "InputSchema: \n" + tool.function.parameters | tojson(indent=2) + "\n\n" }}
    {%- endif %}
    {%- endfor %}

    {# 输出工具调用格式说明 #}
    {{- '**Note** :For each function call, return a json object with function name and arguments within <longcat_tool_call></longcat_tool_call> XML tags as follows:
    <longcat_tool_call>
    {"name": <function-name>, "arguments": <args-dict>}
    </longcat_tool_call>
    ' }}
    {{- 'When multiple functions need to be called simultaneously, each function call should be wrapped in its own <longcat_tool_call> tag and placed consecutively. For example:
    <longcat_tool_call>
    {"name": <function-name>, "arguments": <args-dict>}
    </longcat_tool_call><longcat_tool_call>
    {"name": <function-name>, "arguments": <args-dict>}
    </longcat_tool_call>

    ' }}
    {{- "# Messages\n" }}

    {# 遍历消息,找到最后一个助手的非工具调用消息索引 #}
    {%- for idx in range(messages|length - 1) %}
    {%- set msg = messages[idx] %}
    {%- if msg.role == 'assistant' and not msg.tool_calls %}
    {%- set ns.last_query_index = idx %}
    {%- endif %}
    {%- endfor%}
    {%- endif %}


    {# 遍历所有消息并格式化输出 #}
    {%- for msg in messages %}
    {# 系统消息处理 #}
    {%- if msg.role == "system" %}
    {{- "SYSTEM:" + msg.content }}

    {# 用户消息处理 #}
    {%- elif msg.role == "user" %}
    {%- if loop.first %}
    {{- "[Round " ~ (ns.rounds) ~ "] USER:" }}
    {%- else %}
    {{- " [Round " ~ (ns.rounds) ~ "] USER:"}}
    {%- endif %}
    {%- set ns.rounds = ns.rounds + 1 %}

    {# 如果有文件,输出文件信息 #}
    {%- if msg["files"] %}
    {{- '<longcat_files>\n' ~ msg.files | tojson(indent=2) ~ '\n</longcat_files>' }}
    {%- endif %}
    {{- msg.content }}

    {# 助手消息处理 #}
    {%- elif msg.role == "assistant" %}
    {{- " ASSISTANT:" }}

    {# 如果启用思考模式且有思考内容,输出思考过程 #}
    {%- if enable_thinking == true and msg.reasoning_content and ns.tool_types != [] and loop.index0 > ns.last_query_index %}
    {{- "\n<longcat_think>\n" ~ msg.reasoning_content ~ "\n</longcat_think>\n" }}
    {%- endif %}

    {# 输出助手内容 #}
    {%- if msg.content%}
    {{- msg.content }}
    {%- endif %}

    {# 输出工具调用信息 #}
    {%- if msg.tool_calls %}
    {%- for tool_call in msg.tool_calls -%}
    {{- "<longcat_tool_call>\n" -}}
    {%- if tool_call.function.arguments is string -%}
    {"name": "{{ tool_call.function.name}}", "arguments": {{tool_call.function.arguments}}}
    {%- else -%}
    {"name": "{{ tool_call.function.name}}", "arguments": {{tool_call.function.arguments | tojson}}}
    {%- endif -%}
    {{- "\n</longcat_tool_call>" }}
    {%- endfor %}
    {%- endif %}
    {{- "</longcat_s>" -}}

    {# 工具返回结果处理 #}
    {%- elif msg.role == "tool" %}
    {{- " TOOL:" -}}
    {%- if msg.name -%}
    {"name": {{msg.name | tojson}}, "content": {{msg.content | tojson}}}
    {%- else -%}
    {"content": {{msg.content | tojson}}}
    {%- endif -%}
    {%- endif %}
    {%- endfor %}


    {# 如果需要生成提示,输出相应的提示信息 #}
    {%- if add_generation_prompt %}
    {%- if enable_thinking == true %}
    {{- " /think_on" }}
    {%- if thinking_budget %}
    {%- if thinking_budget < 1024 %}
    {%- set thinking_budget = 1024 %}
    {%- endif%}
    {{- "\nthinking_budget: < " ~ thinking_budget ~ "."}}
    {%- endif %}
    {{- " ASSISTANT:<longcat_think>\n"}}
    {%- elif enable_thinking == false %}
    {{- " /think_off ASSISTANT:<longcat_think>\n\n</longcat_think>\n" }}
    {%- else %}
    {{- " ASSISTANT:" }}
    {%- endif %}
    {%- endif %}
  • 关于示例的一些补充说明:

    • </longcat_s> 是结束符,不是开始符号,记忆:从 </s> 变形而来
    • add_generation_prompt 用于判断是否需要增加生成信息,一般来说是 serving 需要,trainging 不需要
    • thinking_budget 可以不加,默认没有预算约束
    • 上述示例还缺少的模版 features 为 RAG documents 参数的使用,详情可参考 huggingface.co/CohereLabs/c4ai-command-r-v01/blob/main/tokenizer_config.json

code_interpreter 的使用

  • 特别说明:使用 code_interpreter 时,只需要在 tools 里面加一项 { "type": "code_interpreter" },,这样 chat_template 会自动识别到该字段并输出一些使用信息,告诉模型如何给出代码,并告知模型这个代码可以被执行

  • 本文示例中 chat_template 的具体做法是先将 code_interpreter 包装成一个类似 function 的格式,再统一输出,最终效果就是让模型知道可以调用 code_interpreter 执行代码("code" 参数内容就是代码)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    {# 如果是代码解释器工具,重新定义其配置 #}
    {%- if tool.type == 'code_interpreter' %}
    {%- set tool = {
    "type": "code_interpreter",
    "function": {
    "name": "code_interpreter_preview",
    "description": "The code will be executed in a stateful Jupyter notebook sandbox environment, only supports local computation, data processing, and file operations. \nCode sandbox environment (network isolated) Any external network requests or online API calls are prohibited. \nIf online functionality is needed, please use other permitted tools. \nCode will respond with the output of the execution or time out after 60.0 seconds. ",
    "parameters": {
    "type": "object",
    "properties": {
    "language": {
    "type": "string",
    "description": "The programming language of the code to be executed. Available values: python (Default), java, go, js, ts, c, c++."
    },
    "code": {
    "type": "string",
    "description": "Python code to be executed must not include the following:\n- Importing network libraries such as requests, httplib, etc.\n- Any form of HTTP requests.\n- External API calls.\n- Network port operations. Example: ```python\nimport pandas as pd\npd.DataFrame({'A':[1,2]})\n```"
    },
    "timeout": {
    "type": "number",
    "description": "The maximum execution time of the code, in seconds. Default is 60.0."
    }
    }
    },
    "required": ["code"]
    }
    } %}
    {%- endif %}
  • tools 的第一条信息是 { "type": "code_interpreter" } 时,chat_tempalte 格式化的结果为:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    # Tools
    You have access to the following tools:

    ## Tool namespace: code_interpreter

    ### Tool name: code_interpreter_preview

    Description: The code will be executed in a stateful Jupyter notebook sandbox environment, only supports local computation, data processing, and file operations.
    Code sandbox environment (network isolated) Any external network requests or online API calls are prohibited.
    If online functionality is needed, please use other permitted tools.
    Code will respond with the output of the execution or time out after 60.0 seconds.

    InputSchema:
    {
    "type": "object",
    "properties": {
    "language": {
    "type": "string",
    "description": "The programming language of the code to be executed. Available values: python (Default), java, go, js, ts, c, c++."
    },
    "code": {
    "type": "string",
    "description": "Python code to be executed must not include the following:\n- Importing network libraries such as requests, httplib, etc.\n- Any form of HTTP requests.\n- External API calls.\n- Network port operations. Example: ```python\nimport pandas as pd\npd.DataFrame({'A':[1,2]})\n```"
    },
    "timeout": {
    "type": "number",
    "description": "The maximum execution time of the code, in seconds. Default is 60.0."
    }
    }
    }

    ## Tool namespace: function

    ### Tool name: search

    Description: 网页搜索,使用传统搜索引擎,复杂问题需要拆分为简单query

    InputSchema:
    {
    "type": "object",
    "required": [
    "query"
    ],
    "properties": {
    "query": {
    "type": "string",
    "description": "适合传统搜索引擎的简单query"
    }
    }
    }
    ... 更多