Purpose
Invoke the Tencent Cloud OCR Exam Grading Agent API, an exam grading product for K12 education scenarios, supporting end-to-end processing of whole papers/single questions (exam paper question segmentation + question grading + handwritten coordinate display), focusing on exam question grading (including handwritten answers) and exam question analysis (excluding handwritten answers). Accurately outputs structured evaluation results such as questions, correctness judgment, answer comparison, error analysis, and knowledge points. The grading effect for lower-grade arithmetic is better than online math homework grading.
Core capabilities:
- Asynchronous dual-interface mode: Submit submits a task to obtain a JobId → Describe polls for the result (completed when DONE/FAIL)
- Whole-paper grading: Automatically segments questions and then grades each question one by one, returning the grading information for each question
- Single-question grading: Skips the question segmentation step and directly grades a single question, supporting the input of reference answers
- Deep thinking: Optionally enable deep thinking mode for deeper reasoning analysis (slower)
- Knowledge point output: Can be configured to output knowledge point information associated with the question
- Correct answer output: Can be configured to output the correct answer to the question
- Handwritten answer coordinates: Can be configured to output the coordinate position of the handwritten answer in the original image
- Multi-format input: Supports PNG, JPG, JPEG, BMP, GIF, WEBP, HEIC, TIFF, HEIF, and PDF formats
Official documentation:
- Submit task:https://cloud.tencent.com/document/api/866/128273
- Query task:https://cloud.tencent.com/document/api/866/128274
When to use
Trigger this skill when the user raises the following needs:
- Need to automatically grade exam paper images/PDFs
- Need to recognize handwritten answers and judge correctness
- Need to perform grading analysis on K12 test questions
- Need to obtain knowledge point information for test questions
- Need to obtain the correct answers to test questions
- Need to grade a single question (including reference answers)
- Any scenario involving exam paper question segmentation or test question analysis
Environment requirements
- Python 3.6+
- Dependencies:
tencentcloud-sdk-python(viapip install tencentcloud-sdk-pythoninstallation) - Environment variables:
TENCENTCLOUD_SECRET_ID: Tencent Cloud API Secret IDTENCENTCLOUD_SECRET_KEY: Tencent Cloud API Secret Key
Usage
Run the scripts/main.py script to complete exam grading. This interface is anasynchronous interface, and the script will automatically submit the task and poll for the result.
Request parameters
Submit task (SubmitQuestionMarkAgentJob) parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| ImageBase64 | str | No (choose one of two) | Base64 value of the image/PDF; after encoding, it must not exceed 10M; resolution is recommended to be above 600*800; supports PNG/JPG/JPEG/BMP/PDF formats |
| ImageUrl | str | No (choose one of two) | URL address of the image/PDF; download time must not exceed 3 seconds. When both are provided, only ImageUrl is used. Recommended to store in Tencent Cloud |
| PdfPageNumber | int | No | PDF page number; only single-page recognition is supported; default is 1 |
| BoolSingleQuestion | bool | No | Whether to grade a single question (skip question splitting); default is false |
| EnableDeepThink | bool | No | Whether to enable deep thinking (deeper reasoning, slower speed); default is false |
| QuestionConfigMap | str | No | Question information output configuration (JSON string); optional keys: KnowledgePoints (output knowledge points)/TrueAnswer (output correct answer)/ReturnAnswerPosition (output handwritten answer coordinates) |
| ReferenceAnswer | str | No | Reference answer for single-question grading; valid only for a single question, and does not take effect for multiple questions |
DescribeQuestionMarkAgentJob parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| JobId | str | Yes | Unique task ID, returned by the Submit API, with a length not exceeding 32 characters |
| UserAgent | str | No | Request source identifier (optional), used to track the call source, uniformly fixed asSkills |
Output format
After successful recognition, the result is returned in JSON format:
Formatted output mode (default):
{
"任务ID": "1410885500986064896",
"任务状态": "DONE",
"切题数量": "2",
"旋转角度": 0.0,
"批改结果": [
{
"题号": 1,
"题干": "1. 小琪在做作业时发现有一道题的一部分被墨水遮住了...",
"子题": [
{
"题号": "1-1",
"题干": "(1)小琪猜测,墨水遮住的内容是"2a",请你根据小琪的猜测完成计算;",
"答案列表": [
{
"手写答案": "\\frac{2}{a-1}...",
"是否正确": false,
"答案分析": "首先将除法转化为乘法,对分子分母因式分解后约分...",
"正确答案": "...",
"知识点": ["分式运算", "因式分解"],
"答案坐标": [113, 648, 558, 648, 558, 698, 113, 698]
}
]
}
]
}
],
"RequestId": "xxx"
}
Raw output mode (--raw):
{
"JobId": "1410885500986064896",
"JobStatus": "DONE",
"ErrorCode": "",
"ErrorMessage": "",
"Angle": 0.0,
"MarkInfos": [
{
"MarkItemTitle": "1. 小琪在做作业时...",
"AnswerInfos": [],
"MarkInfos": [
{
"MarkItemTitle": "(1)小琪猜测...",
"AnswerInfos": [
{
"HandwriteInfo": "\\frac{2}{a-1}...",
"IsCorrect": false,
"AnswerAnalysis": "首先将除法转化为乘法...",
"RightAnswer": "",
"KnowledgePoints": [],
"HandwriteInfoPositions": [113, 648, 558, 648, 558, 698, 113, 698]
}
],
"MarkInfos": []
}
]
}
],
"RequestId": "xxx"
}
Response data structure description
SubmitQuestionMarkAgentJob response
| Parameter | Type | Description |
|---|---|---|
| JobId | str | Unique task ID, used to query the result |
| QuestionInfo | list of QuestionInfo | List of question-splitting question border coordinates (empty when BoolSingleQuestion=true) |
| QuestionCount | str | Number of split questions, used as the total number of billed questions |
| RequestId | str | Unique request ID |
DescribeQuestionMarkAgentJob response
| Parameter | Type | Description |
|---|---|---|
| JobStatus | str | Task status: WAIT (waiting)/RUN (running)/FAIL (failed)/DONE (success) |
| ErrorCode | str | Task execution error code (empty when not FAIL) |
| ErrorMessage | str | Task execution error message (empty when not FAIL) |
| Angle | float | Image rotation angle (in degrees); horizontal direction is 0, clockwise is positive |
| MarkInfos | list of MarkInfo | Question grading information |
| RequestId | str | Unique request ID |
MarkInfo structure (nested recursive):
| Field | Type | Description |
|---|---|---|
| MarkItemTitle | str | Question stem information |
| AnswerInfos | list of AnswerInfo | List of graded answers (arranged from left to right, top to bottom) |
| MarkInfos | list of MarkInfo | Nested sub-question information (empty if there are no sub-questions) |
AnswerInfo structure:
| Field | Type | Description |
|---|---|---|
| HandwriteInfo | str | Handwritten answer content (such as handwritten options for multiple-choice questions and handwritten content for fill-in-the-blank questions) |
| IsCorrect | bool | Whether the answer is correct |
| AnswerAnalysis | str | Answer analysis result |
| HandwriteInfoPositions | list of int | Coordinates of the 4 corner points of the answer area (array of length 8: top-left/top-right/bottom-right/bottom-left); ReturnAnswerPosition must be configured. May return null |
| RightAnswer | str | Correct answer content; requires configuring TrueAnswer in QuestionConfigMap to true |
| KnowledgePoints | list of str | Knowledge point content; requires configuring KnowledgePoints in QuestionConfigMap to true. May return null |
QuestionInfo structure:
| Field | Type | Description |
|---|---|---|
| Angle | float | Rotation angle |
| Height | int | Preprocessed image height |
| Width | int | Preprocessed image width |
| ResultList | list of ResultList | Document element (may return null) |
| OrgHeight | int | Input image height |
| OrgWidth | int | Input image width |
| ImageBase64 | str | Base64-encoded preprocessed image |
Error code description
| Error code | Meaning |
|---|---|
| FailedOperation.DownLoadError | File download failed |
| FailedOperation.ImageDecodeFailed | Image decoding failed |
| FailedOperation.ImageSizeTooLarge | Image size is too large; please ensure it does not exceed 10 MB after encoding |
| FailedOperation.OcrFailed | OCR recognition failed |
| FailedOperation.PDFParseFailed | PDF parsing failed |
| FailedOperation.UnKnowError | Unknown error |
| FailedOperation.UnKnowFileTypeError | Unknown file type |
| FailedOperation.UnOpenError | Service not activated; please activate the Test Paper Grading Agent service in the Tencent Cloud console first |
| InvalidParameterValue.InvalidParameterValueLimit | Invalid parameter value |
| LimitExceeded.TooLargeFileError | File content is too large |
| ResourceUnavailable.InArrears | Account is in arrears |
| ResourceUnavailable.ResourcePackageRunOut | Account resource package exhausted |
| ResourcesSoldOut.ChargeStatusException | Abnormal billing status |
Important business logic
- Asynchronous dual-interface mode: Submit submits the task → Describe polls; completes when JobStatus is DONE/FAIL
- Submit is billed, Describe is not billed
- Either ImageBase64 or ImageUrl must be provided, if both are provided only ImageUrl is used
- Supported formats: PNG/JPG/JPEG/BMP/GIF/WEBP/HEIC/TIFF/HEIF and PDF
- PdfPageNumber must be a positive integer; only single-page recognition is supported
- When BoolSingleQuestion=true, question segmentation is skipped and single-question grading is performed directly
- QuestionConfigMap example:
{"KnowledgePoints":true,"TrueAnswer":true,"ReturnAnswerPosition":false} - ReferenceAnswer is valid only for a single question and does not take effect for multiple questions
- JobId length must not exceed 32 characters
- Default API request concurrency limit: 10 questions/minute
- It is recommended to store images in Tencent Cloud COS for higher download speed and stability
- MarkInfo is a recursively nested structure and may contain multiple levels of sub-questions
Call example
# 通过URL进行整卷批改(输出知识点和正确答案)
python scripts/main.py --image-url "https://example.com/exam_paper.jpg" \
--question-config '{"KnowledgePoints":true,"TrueAnswer":true}'
# 通过URL进行单题批改(带参考答案)
python scripts/main.py --image-url "https://example.com/single_question.jpg" \
--single-question --reference-answer "x=2"
# 开启深度思考模式
python scripts/main.py --image-url "https://example.com/exam.jpg" --enable-deep-think
# 通过文件路径进行批改(自动Base64编码)
python scripts/main.py --image-base64 ./exam_paper.png
# 批改PDF试卷(指定页码)
python scripts/main.py --image-base64 ./exam.pdf --pdf-page-number 2
# 输出原始JSON响应
python scripts/main.py --image-url "https://example.com/exam.jpg" --raw
# 指定地域和自定义轮询参数
python scripts/main.py --image-url "https://example.com/exam.jpg" \
--region ap-beijing --poll-interval 3 --poll-timeout 300```