Convert RAG retrieval results or document content in the WeKnora knowledge base into OpenMAIC interactive courses.
Core Capabilities
- RAG → Course: Distill knowledge retrieval results into a teaching requirement, and generate an interactive course through the OpenMAIC API
- PDF → Course: Parse the PDF uploaded by the user, and generate a course based on its content
- Document Chunks → Course Set: Organize multiple document chunks/knowledge fragments into a multi-stage course set
- Concept Graph Traversal → Batch Micro-Classrooms: Traverse all concept pages in the knowledge graph, and generate one micro-classroom for each concept
Capability Boundaries
Through the mcp_api_requester MCP tool registered in WeKnora, you can directly call the OpenMAIC API(HTTP POST/GET requests). This tool is registered in the WeKnora agent as
mcp_{service_name}_{tool_name}format (e.g.,mcp_mcp_api_requester_make_request)。 Mustuse this MCP tool to call the API. If the MCP tool is not configured or unavailable, guide the user to deploy mcp-api-requester first, and do not provide curl commands.
⚠️ MCP Availability Check (must be performed after reading this file each time): Before starting work, check whether the list of available MCP tools contains a tool whose name includes
mcp_api_requester.
- If not found: You must remind the user: "No
mcp_api_requesterMCP service detected. Please first download the code from https://github.com/yryuu/mcp-api-requester and deploy it, then register this MCP service in WeKnora."- If found: Continue with the subsequent process, and use this MCP tool to call the API.
Mode Selection
OpenMAIC has two usage modes;choose according to the user's scenario:
| Mode | Base URL | Authentication Method | Applicable Scenario |
|---|---|---|---|
| Hosted Mode (recommended for quick use) | https://open.maic.chat |
Authorization: Bearer <access-code> |
The user has an open.maic.chat access code, and no local deployment is required |
| Local Mode | Provided by the user (see Local Mode Base URL Handling) | No authentication (local self-deployment) | The user has deployed an OpenMAIC instance themselves |
Decision Rules:
- The user mentions "online service", "open.maic.chat", or "access code" → use Hosted Mode
- The user mentions "local deployment" or "self-hosted" → use Local Mode
- When the user does not specify clearly, ask the user first which mode to use
Local Mode Base URL Handling:
- After the user selects Local Mode, you must ask the user: "Please enter your OpenMAIC local deployment address (e.g.,
http://localhost:3000orhttp://192.168.1.100:3000)" - After receiving the address provided by the user, process it as follows:
- Replace
127.0.0.1in the address withhost.docker.internal - Replace
localhostin the address withhost.docker.internal - Keep other addresses unchanged
- Replace
⚠️ WeKnora runs inside a Docker container,
localhostand127.0.0.1point to the container itself and cannot access host services. You must usehost.docker.internalas the bridge address for the container to access the host.
Prerequisites
| Configuration Item | Description |
|---|---|
| Mode | Hosted mode or Local mode (see the judgment rules above) |
accessCode |
Required for hosted mode — access code (starting with sk- ), obtained by the user at open.maic.chat |
| Health Check | Verify service availability before calling:GET <BASE_URL>/api/health |
Use Cases
Use this skill when the user's request involves the following:
- "Turn this document into courseware"
- "Generate a course based on the retrieval results"
- "Create an interactive classroom for this knowledge point"
- "Convert knowledge base content into teaching materials"
- "Generate courses in bulk" / "Turn all the concepts in the knowledge graph into classrooms" / "Generate micro-classrooms based on the concept map"
Workflow
Phase 1: Confirm the Input Source
Confirm the input source for course generation (choose one of four):
- Pure Requirement Generation: The user directly describes the teaching topic, no additional document needed
→ Directly use the user's description as the
requirement,No script call needed - RAG Retrieval Results: First retrieve relevant knowledge via
knowledge_search, then organize the results into a requirement → Use thescripts/rag-to-requirement.pyscript to convert the retrieval results into a structured requirement (see Phase 1.1) - PDF File: The user provides a PDF file path; parse it first, then call the generation API → After extracting the PDF text, build the requirement,No script call needed
- Concept Graph Traversal for Bulk Generation: Traverse all concept pages in the knowledge graph, generating one micro-classroom per concept
→ Use the
scripts/concept-to-requirement.pyscript to convert the concept + associated entities into a structured requirement (see Phase 1.2)
Phase 1.1: RAG Results → Requirement Conversion (only applies to scenario 2)
When scenario 2 has RAG retrieval results, call scripts/rag-to-requirement.py to convert chunks into a requirement:
execute_skill_script(
skill_name: "openmaic-classroom",
script_path: "scripts/rag-to-requirement.py",
input: '{"chunks": [...检索结果...], "query": "用户查询", "audience": "目标受众"}'
)
input parameter format (JSON string, must be passed via the input parameter, cannot use --file):
chunks(required): RAG retrieval results array, each item containsdocument_name、content、metadataquery(optional): The user's original queryaudience(optional): Target audience description, defaults to "learners in the relevant field"depth(optional): Teaching depthbeginner|intermediate|advanced, defaults tointermediatelanguage(optional):zh-CN|en-US, defaults tozh-CNfocus_areas(optional): Array of focus areas
Note:
- The chunks data must be passed as the
inputparameter (equivalent toecho '{"chunks":...}' | python script.py) - Do notcall this script without any parameters, otherwise it will error out and exit
- If the script fails to execute, you can directly build the requirement manually based on the retrieval results
Phase 1.2: Concept Graph → Requirement Conversion (only applies to scenario 4)
When scenario 4 requires bulk generation of classrooms based on knowledge graph concepts, perform the following steps:
Step 1: List all concept pages
Use wiki_search Tool searches all pages of concept type:
wiki_search("^concept/", limit=50)
If the number of concepts exceeds 50, call pagination multiple times until all are retrieved.
Step 2: For each concept, retrieve details and associated entities
For each concept page:
- Call
wiki_read_page([concept_slug])to retrieve page details (including OutLinks and InLinks) - Filter out slugs starting with
entity/*from OutLinks and InLinks - Determine the link_type of each entity:
- Appears in both OutLinks and InLinks →
bidirectional - Appears only in OutLinks →
outlink - Appears only in InLinks →
inlink
- Appears in both OutLinks and InLinks →
- Call
wiki_read_page([entity_slugs])to batch-read associated entities (retrieve only title + summary, not full content)
Step 3: Convert to requirement
For each concept, call scripts/concept-to-requirement.py to convert the concept + associated entities into a requirement:
execute_skill_script(
skill_name: "openmaic-classroom",
script_path: "scripts/concept-to-requirement.py",
input: '{"concept": {"slug": "...", "title": "...", "summary": "...", "content": "..."}, "entities": [{"slug": "...", "title": "...", "summary": "...", "link_type": "..."}], "language": "zh-CN", "depth": "intermediate"}'
)
input parameter format (JSON string, must be passed via the input parameter):
concept(required): concept page object, containingslug、title、summary、contententities(optional): array of associated entities, each containingslug、title、summary、link_typelanguage(optional):zh-CN|en-US, defaultzh-CNdepth(optional):beginner|intermediate|advanced, defaultintermediateaudience(optional): target audience description, default "learners in related fields"
Step 4: Call the OpenMAIC API sequentially
For each concept's requirement,sequentiallycall the OpenMAIC generation API (concurrency=1):
- each concept → one micro-classroom
- marked in the requirement
micro-classroom - cannot be parallelized, to avoid quota conflicts
Step 5: Generate manifest (recoverability)
Generate a manifest JSON recording the generation status of each concept:
{
"kb_id": "...",
"total_concepts": 10,
"generated": ["concept/rag", "concept/llm"],
"failed": [{"slug": "concept/embedding", "error": "..."}],
"pending": ["concept/vector-db"]
}
On failure, resume from the breakpoint: skip the concepts in generated , and start from the first one in pending .
Key constraints:
- wiki reading and script conversion allow batching
- OpenMAIC API generation concurrency=1
- concept.Summary serves as the core anchor for the requirement
- entities retrieve only title + summary, not full content
- concepts without associated entities can still generate a classroom (lacking a practice segment)
Phase 2: Build Generation Request
Build the request body based on the input source,Field description:
| Field | Type | Required | Description |
|---|---|---|---|
requirement |
string | Yes | Teaching topic description, 1-2 sentences |
pdfContent |
object | No | Text and images after PDF parsing |
language |
string | No | "zh-CN" or "en-US", default "zh-CN" |
enableWebSearch |
bool | No | Whether to enable web search, default false |
enableImageGeneration |
bool | No | Whether to generate illustrations, default false |
enableVideoGeneration |
bool | No | Whether to generate video, default false |
enableTTS |
bool | No | Whether to generate voice narration, default false |
agentMode |
string | No | "default" or "generate", default "default" |
Scenario adaptation:
- Scenario 1 (pure requirements):
requirementDirectly use the user description - Scenario 2 (RAG results):
requirementUse therequirementfield in the Phase 1.1 script output - Scenario 3 (PDF):
requirementBuild from the text extracted from the PDF,pdfContentfill in the parsing result - Scenario 4 (concept graph traversal):
requirementUse therequirementfield in the Phase 1.2 script output, calling the API separately for each concept
Phase 3: Call the OpenMAIC API
Preferred method: Call the API directly through the MCP tool registered with WeKnora.
Step 1: Identify the HTTP request tool
- Among the MCP tools available to you, find the tool used for HTTP requests
- The tool name format is
mcp_{service_name}_{tool_name}(e.g.,mcp_mcp_api_requester_make_request) - Identify by tool description: look for tools containing keywords such as "HTTP request", "API", "GET/POST"
- If no HTTP request MCP tool can be found, guide the user to deploy mcp_api_requester (see MCP availability check)
Step 2: Determine the Base URL and authentication header
| Mode | Base URL | Authentication Header |
|---|---|---|
| Hosted mode | https://open.maic.chat |
Authorization: Bearer <access-code> |
| Local mode | The address provided by the user (having replaced localhost/127.0.0.1 with host.docker.internal) |
None |
Step 3: Feature Detection (before sending optional features)
Before sending the generation request, first query GET <BASE_URL>/api/health(hosted mode requires an auth header), and check the returned capabilities object:
{
"status": "ok",
"version": "...",
"capabilities": {
"webSearch": true,
"imageGeneration": false,
"videoGeneration": false,
"tts": true
}
}
- Only when
capabilitiesan item istruecan the corresponding feature flag be set totrue - If the server does not return
capabilities(older version), do not send any optional feature flags
Step 4: Send the POST request
Use the identified HTTP request tool to send the request. Construct the request according to the mode and URL determined above:
Hosted mode:
{
"url": "https://open.maic.chat/api/generate-classroom",
"method": "POST",
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer <access-code>"
},
"body": {
"requirement": "..."
}
}
Local mode:
{
"url": "<BASE_URL>/api/generate-classroom",
"method": "POST",
"headers": {
"Content-Type": "application/json"
},
"body": {
"requirement": "..."
}
}
Handling when the MCP tool is unavailable:
Inform the user:
Not detected
mcp_api_requesterMCP service. Please first download the code from https://github.com/yryuu/mcp-api-requester and deploy it, then register the MCP service in WeKnora.
Phase 4: Query task progress
The API returns jobId and pollUrl afterward, execute the following process:
1st query (executed immediately after submission):
- Call the HTTP request tool
GET {pollUrl}to get the current status - Check
status:-
If
succeeded→ proceed to Phase 5 -
If
failed→ report the error and stop -
If
queuedorrunning→ Stop querying and inform the user:The course is being generated and is expected to take 2-10 minutes. Please ask me later to check progress. Job ID: {jobId}
-
When the user asks about progress (2nd query):
- Call again
GET {pollUrl} - Check
status:-
If
succeeded→ proceed to Phase 5 -
If
failed→ Report error and stop -
If still in
queuedorrunning→ stop querying and tell the user to keep waiting:The course is still being generated, please try again later. Job ID: {jobId}
-
Important Rules:
- After submission, query only 1 time, do not poll continuously
- When the user asks about progress, query only 1 time, do not poll continuously
- Only when
statusissucceededorfailedshould you proceed to the next step—otherwise you must stop and tell the user to wait - Do not attempt to resubmit the job—keep querying the same
pollUrl
Phase 5: Return results
After successful generation, return:
Classroom ID: <classroomId>
Classroom URL:
<BASE_URL>/classroom/<classroomId>
URL format for hosted mode:https://open.maic.chat/classroom/<classroomId>
The URL must be output as plain text on its own line, without bold, code formatting, or Markdown links.
Error Handling
| Error | Meaning | Handling |
|---|---|---|
| Connection failed | Network unreachable or service not started | Check whether the Base URL is correct and whether the service is started |
| 401 | Invalid access code (hosted mode) | Tell the user to check or regenerate the access code at open.maic.chat |
| 403 | Daily quota exhausted (hosted mode) | Inform them of the daily limit of 10 times, reset at midnight the next day |
| 500 | Server error | Suggest retrying later or switching to local mode |
| Provider configuration error | Model/Provider/authentication issue | Guide the user to check the configuration or contact the administrator |
Multiple documents → course set
When the user needs to generate a course set from multiple documents/knowledge fragments:
- Collect all document contents
- Generate a requirement for each document/topic separately
- Call the generation API sequentially through the MCP tool (no parallel calls, to avoid quota conflicts)
- If the MCP tool is unavailable, tell the user to deploy mcp_api_requester first (see MCP availability check)
- Aggregate and return all Classroom URLs
Concept graph traversal → batch micro-classrooms
When the user needs to batch-generate classrooms based on knowledge graph concepts (scenario 4), follow the complete process in Phase 1.2.
MVP Course Orchestration Strategy:one concept → one micro-classroom
Course type annotation: annotate in the requirement micro-classroom
Batch processing recoverability: generate a manifest JSON recording the generation status of each concept, so that it can resume from the breakpoint on failure.
Key Constraints:
- wiki reading and script conversion allow batching
- OpenMAIC API generation concurrency=1
- concept.Summary serves as the core anchor for the requirement
- entity takes only title + summary, not the full content
- Concepts without associated entities can still generate classrooms (lacking practical segments)
Notes
- Scripts are executed in a Docker sandbox,the sandbox disables network access by default
- The OpenMAIC API must be called through the WeKnora MCP tool—do not provide curl commands as a fallback solution
- The MCP tool name format is
mcp_{service_name}_{tool_name}, identify the HTTP request tool based on the description - If the MCP tool is not enabled or unavailable, tell the user to first download the code from https://github.com/yryuu/mcp-api-requester and deploy it, then register the MCP service in WeKnora
- A single generation task is expected to take 2-10 minutes, depending on content complexity and optional features
- Hosted mode (open.maic.chat) has a maximum of 10 generation quotas per day, independent of the Web UI quota
- If the user requests to generate a new course while the same job is still running, do not resubmit—first check the existing job status